change(ui) - fix date range in url, other misc changes

This commit is contained in:
Shekar Siri 2023-02-10 11:41:58 +01:00
parent 227bcda4e5
commit b6f2cc59f7
6 changed files with 217 additions and 115 deletions

View file

@ -68,13 +68,11 @@ class Login extends React.Component {
return (
<div className="flex flex-col md:flex-row" style={{ height: '100vh' }}>
<div className={cn('md:w-6/12 relative', stl.left)}>
<div className={cn('md:w-6/12 relative overflow-hidden', stl.left)}>
<div className="px-6 pt-10">
<img src="/assets/logo-white.svg" />
</div>
<div className="color-white text-lg flex items-center">
<img style={{ width: '800px', position: 'absolute', bottom: 0, left: 0 }} src={LoginBg} />
</div>
<img style={{ width: '800px', position: 'absolute', bottom: -100, left: 0 }} src={LoginBg} />
</div>
<div className="md:w-6/12 flex items-center justify-center py-10">
<div className="">

View file

@ -5,47 +5,54 @@ import { Icon } from 'UI';
import stl from './signup.module.css';
import cn from 'classnames';
import SignupForm from './SignupForm';
import RegisterBg from '../../svg/register.svg';
const BulletItem = ({ text }) => (
<div className="flex items-center mb-4">
<div className="mr-3 h-8 w-8 rounded-full bg-white shadow flex items-center justify-center">
<Icon name="check" size="26"/>
<Icon name="check" size="26" />
</div>
<div>{text}</div>
</div>
)
);
@withPageTitle('Signup - OpenReplay')
export default class Signup extends React.Component {
render() {
return (
<div className="flex" style={{ height: '100vh'}}>
<div className={cn("w-6/12", stl.left)}>
<div className="flex" style={{ height: '100vh' }}>
<div className={cn('w-6/12 relative overflow-hidden', stl.left)}>
<div className="px-6 pt-10">
<img src="/assets/logo-white.svg" />
<img src="/assets/logo-white.svg" />
</div>
<div className="color-white text-lg flex items-center px-20 pt-32">
<div>
<div className="flex items-center text-3xl font-bold mb-6">
OpenReplay Cloud <div className="ml-2"><Icon name="signup" size="28" color="white" /></div>
</div>
<div>OpenReplay Cloud is the hosted version of our open-source project.</div>
<div>Well manage hosting, scaling and upgrades.</div>
<div className="mt-8">
<BulletItem text="First 1K sessions free every month." />
<BulletItem text="Pay per use, cancel anytime" />
<BulletItem text="Community, Slack & email support" />
<img
style={{ width: '800px', position: 'absolute', bottom: -100, left: 0 }}
src={RegisterBg}
/>
<div className="color-white text-lg flex items-center px-20 pt-32">
<div>
<div className="flex items-center text-3xl font-bold mb-6">
OpenReplay Cloud{' '}
<div className="ml-2">
<Icon name="signup" size="28" color="white" />
</div>
</div>
<div>OpenReplay Cloud is the hosted version of our open-source project.</div>
<div>Well manage hosting, scaling and upgrades.</div>
<div className="mt-8">
<BulletItem text="First 1K sessions free every month." />
<BulletItem text="Pay per use, cancel anytime" />
<BulletItem text="Community, Slack & email support" />
</div>
</div>
</div>
</div>
</div>
<div className="w-6/12 flex items-center justify-center">
<div className="">
<SignupForm />
</div>
</div>
</div>
<div className="w-6/12 flex items-center justify-center">
<div className="">
<SignupForm />
</div>
</div>
</div>
);
}
}

View file

@ -2,10 +2,8 @@ import React, { useEffect } from 'react';
import { useHistory } from 'react-router';
import { connect } from 'react-redux';
import { addFilterByKeyAndValue, addFilter } from 'Duck/search';
import { getFilterKeyTypeByKey, setQueryParamKeyFromFilterkey } from 'Types/filter/filterType';
import { filtersMap } from 'App/types/filter/newFilter';
import Filter from 'Types/filter/filter';
import { applyFilter } from 'Duck/search';
import { createUrlQuery, getFiltersFromQuery } from 'App/utils/search';
interface Props {
appliedFilter: any;
@ -13,93 +11,25 @@ interface Props {
addFilterByKeyAndValue: typeof addFilterByKeyAndValue;
addFilter: typeof addFilter;
}
const SessionSearchQueryParamHandler = React.memo((props: Props) => {
const SessionSearchQueryParamHandler = (props: Props) => {
const { appliedFilter } = props;
const history = useHistory();
const createUrlQuery = (filters: any) => {
const query: any = [];
filters.forEach((filter: any) => {
const item: any = {};
if (filter.value.length > 0) {
const _key = setQueryParamKeyFromFilterkey(filter.key);
if (_key) {
let str = `${filter.operator}|${filter.value.join('|')}`;
if (filter.hasSource) {
str = `${str}^${filter.sourceOperator}|${filter.source.join('|')}`;
}
item.key = _key + '[]';
item.value = str;
} else {
let str = `${filter.operator}|${filter.value.join('|')}`;
item.key = [filter.key] + '[]';
item.value = str;
}
query.push(item);
}
});
return query;
};
const applyFilterFromQuery = () => {
if (appliedFilter.filters.size > 0 || history.location.search === "") {
return;
}
const entires = getQueryObject(history.location.search);
const _filters: any = { ...filtersMap };
if (entires.length > 0) {
const filters: any = [];
entires.forEach((item: any) => {
if (!item.key || !item.value) { return }
let filter: any = {}
const filterKey = getFilterKeyTypeByKey(item.key);
const tmp = item.value.split('^');
const valueArr = tmp[0].split('|');
const operator = valueArr.shift();
const sourceArr = tmp[1] ? tmp[1].split('|') : [];
const sourceOperator = sourceArr.shift();
if (filterKey) {
filter.type = filterKey;
filter.key = filterKey;
} else {
filter = _filters[item.key];
if (!!filter) {
filter.type = filter.key;
filter.key = filter.key;
}
}
filter.value = valueArr;
filter.operator = operator;
filter.source = sourceArr;
filter.sourceOperator = !!sourceOperator ? decodeURI(sourceOperator) : null;
filters.push(filter);
});
const f = Filter({ filters })
props.applyFilter(f);
}
const filter = getFiltersFromQuery(history.location.search, appliedFilter);
props.applyFilter(filter, true);
};
const generateUrlQuery = () => {
const query: any = createUrlQuery(appliedFilter.filters);
let queryString = query.reduce((acc: any, curr: any, index: any) => {
acc += `${curr.key}=${curr.value}`;
if (index < query.length - 1) {
acc += '&';
}
return acc;
}, '');
history.replace({ search: queryString });
const search: any = createUrlQuery(appliedFilter);
history.replace({ search });
};
useEffect(applyFilterFromQuery, []);
useEffect(generateUrlQuery, [appliedFilter]);
return <></>;
});
};
export default connect(
(state: any) => ({
@ -107,11 +37,3 @@ export default connect(
}),
{ addFilterByKeyAndValue, addFilter, applyFilter }
)(SessionSearchQueryParamHandler);
function getQueryObject(search: any) {
let jsonArray = search.slice(1).split('&').map((item: any) => {
let [key, value] = item.split('=');
return {key: key.slice(0, -2), value};
});
return jsonArray;
}

View file

@ -71,6 +71,7 @@ function reducer(state = initialState, action = {}) {
case EDIT:
return state.mergeIn(['instance'], action.instance).set('currentPage', 1);
case APPLY:
return action.fromUrl ? state.set('instance', Filter(action.filter)) : state.mergeIn(['instance'], action.filter).set('currentPage', 1);
case success(FETCH):
return state.set('instance', action.data);

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 48 KiB

View file

@ -0,0 +1,117 @@
import { getFilterKeyTypeByKey, setQueryParamKeyFromFilterkey } from 'Types/filter/filterType';
import Period, { LAST_24_HOURS, LAST_7_DAYS, LAST_30_DAYS, CUSTOM_RANGE } from 'Types/app/period';
import Filter from 'Types/filter/filter';
import { filtersMap } from 'App/types/filter/newFilter';
export const createUrlQuery = (filter: any) => {
const query = [];
for (const f of filter.filters) {
if (!f.value.length) {
continue;
}
let str = `${f.operator}|${f.value.join('|')}`;
if (f.hasSource) {
str = `${str}^${f.sourceOperator}|${f.source.join('|')}`;
}
let key: any = setQueryParamKeyFromFilterkey(f.key);
if (!key) {
key = [f.key];
}
query.push({ key: key + '[]', value: str });
}
if (query.length > 0) {
query.push({ key: 'range[]', value: filter.rangeValue });
if (filter.rangeValue === CUSTOM_RANGE) {
query.push({ key: 'rStart[]', value: filter.startDate });
query.push({ key: 'rEnd[]', value: filter.endDate });
}
}
return query.map(({ key, value }) => `${key}=${value}`).join('&');
};
export const getFiltersFromQuery = (search: string, filter: any) => {
if (!search || filter.filters.size > 0) {
return;
}
const entires = getQueryObject(search);
const period: any = getPeriodFromEntries(entires);
const filters = getFiltersFromEntries(entires);
return Filter({ filters, rangeValue: period.rangeName });
};
const getFiltersFromEntries = (entires: any) => {
const _filters: any = { ...filtersMap };
const filters: any = [];
if (entires.length > 0) {
entires.forEach((item: any) => {
if (!item.key || !item.value) {
return;
}
let filter: any = {};
const filterKey = getFilterKeyTypeByKey(item.key);
if (!filterKey) {
return;
}
const tmp = item.value.split('^');
const valueArr = tmp[0].split('|');
const operator = valueArr.shift();
const sourceArr = tmp[1] ? tmp[1].split('|') : [];
const sourceOperator = sourceArr.shift();
if (filterKey) {
filter.type = filterKey;
filter.key = filterKey;
} else {
filter = _filters[item.key];
if (!!filter) {
filter.type = filter.key;
filter.key = filter.key;
}
}
filter.value = valueArr;
filter.operator = operator;
filter.source = sourceArr;
filter.sourceOperator = !!sourceOperator ? decodeURI(sourceOperator) : null;
if (!filter.filters || filter.filters.size === 0) {
filters.push(filter);
}
});
}
return filters;
};
const getPeriodFromEntries = (entires: any) => {
const rangeFilter = entires.find(({ key }: any) => key === 'range');
if (!rangeFilter) {
return Period();
}
if (rangeFilter.value === CUSTOM_RANGE) {
const start = entires.find(({ key }: any) => key === 'rStart').value;
const end = entires.find(({ key }: any) => key === 'rEnd').value;
return Period({ rangeName: rangeFilter.value, start, end });
}
return Period({ rangeName: rangeFilter.value });
};
function getQueryObject(search: any) {
let jsonArray = search
.slice(1)
.split('&')
.map((item: any) => {
let [key, value] = item.split('=');
return { key: key.slice(0, -2), value };
});
return jsonArray;
}