From b6f2cc59f7e0d3484dad8ed5c3428366ff50ea87 Mon Sep 17 00:00:00 2001 From: Shekar Siri Date: Fri, 10 Feb 2023 11:41:58 +0100 Subject: [PATCH] change(ui) - fix date range in url, other misc changes --- frontend/app/components/Login/Login.js | 6 +- frontend/app/components/Signup/Signup.js | 57 +++++---- .../SessionSearchQueryParamHandler.tsx | 94 ++------------ frontend/app/duck/search.js | 1 + frontend/app/svg/register.svg | 57 +++++++++ frontend/app/utils/search.ts | 117 ++++++++++++++++++ 6 files changed, 217 insertions(+), 115 deletions(-) create mode 100644 frontend/app/svg/register.svg create mode 100644 frontend/app/utils/search.ts diff --git a/frontend/app/components/Login/Login.js b/frontend/app/components/Login/Login.js index 7270944d1..34ca11de5 100644 --- a/frontend/app/components/Login/Login.js +++ b/frontend/app/components/Login/Login.js @@ -68,13 +68,11 @@ class Login extends React.Component { return (
-
+
-
- -
+
diff --git a/frontend/app/components/Signup/Signup.js b/frontend/app/components/Signup/Signup.js index 516d993c2..83a658ec1 100644 --- a/frontend/app/components/Signup/Signup.js +++ b/frontend/app/components/Signup/Signup.js @@ -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 }) => (
- +
{text}
-) +); @withPageTitle('Signup - OpenReplay') export default class Signup extends React.Component { render() { return ( -
-
+
+
- +
-
-
-
- OpenReplay Cloud
-
-
OpenReplay Cloud is the hosted version of our open-source project.
-
We’ll manage hosting, scaling and upgrades.
- -
- - - + +
+
+
+ OpenReplay Cloud{' '} +
+ +
+
+
OpenReplay Cloud is the hosted version of our open-source project.
+
We’ll manage hosting, scaling and upgrades.
+ +
+ + + +
-
-
-
-
-
-
-
+
+
+ +
+
+
); } } diff --git a/frontend/app/components/shared/SessionSearchQueryParamHandler/SessionSearchQueryParamHandler.tsx b/frontend/app/components/shared/SessionSearchQueryParamHandler/SessionSearchQueryParamHandler.tsx index 1951b00a4..820ed4aa0 100644 --- a/frontend/app/components/shared/SessionSearchQueryParamHandler/SessionSearchQueryParamHandler.tsx +++ b/frontend/app/components/shared/SessionSearchQueryParamHandler/SessionSearchQueryParamHandler.tsx @@ -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; -} diff --git a/frontend/app/duck/search.js b/frontend/app/duck/search.js index ce4306cbb..f4d84ffce 100644 --- a/frontend/app/duck/search.js +++ b/frontend/app/duck/search.js @@ -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); diff --git a/frontend/app/svg/register.svg b/frontend/app/svg/register.svg new file mode 100644 index 000000000..e0de5d4c7 --- /dev/null +++ b/frontend/app/svg/register.svg @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/frontend/app/utils/search.ts b/frontend/app/utils/search.ts new file mode 100644 index 000000000..82b3daee1 --- /dev/null +++ b/frontend/app/utils/search.ts @@ -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; +}