From 659adbb4862f25961336ed25b92c6f43fabe3c4e Mon Sep 17 00:00:00 2001 From: Shekar Siri Date: Tue, 23 Aug 2022 14:22:54 +0200 Subject: [PATCH] fix(ui) - metadata options on project switch --- frontend/app/Router.js | 6 +- frontend/app/components/Header/Header.js | 4 +- .../app/components/Header/SiteDropdown.js | 2 +- .../Filters/FilterModal/FilterModal.tsx | 4 +- .../shared/SessionSearch/SessionSearch.tsx | 7 +- frontend/app/duck/customField.js | 86 +++++++++++-------- frontend/app/types/filter/newFilter.js | 49 +++++++---- 7 files changed, 93 insertions(+), 65 deletions(-) diff --git a/frontend/app/Router.js b/frontend/app/Router.js index c0538d21d..04929d3bd 100644 --- a/frontend/app/Router.js +++ b/frontend/app/Router.js @@ -8,7 +8,6 @@ import { fetchUserInfo } from 'Duck/user'; import withSiteIdUpdater from 'HOCs/withSiteIdUpdater'; import WidgetViewPure from 'Components/Dashboard/components/WidgetView'; import Header from 'Components/Header/Header'; -import { fetchList as fetchMetadata } from 'Duck/customField'; import { fetchList as fetchSiteList } from 'Duck/site'; import { fetchList as fetchAnnouncements } from 'Duck/announcements'; import { fetchList as fetchAlerts } from 'Duck/alerts'; @@ -90,14 +89,13 @@ const ONBOARDING_REDIRECT_PATH = routes.onboarding(OB_DEFAULT_TAB); const jwt = state.get('jwt'); const changePassword = state.getIn(['user', 'account', 'changePassword']); const userInfoLoading = state.getIn(['user', 'fetchUserInfoRequest', 'loading']); - const metaLoading = state.getIn(['customFields', 'fetchRequest', 'loading']); return { jwt, siteId, changePassword, sites: state.getIn(['site', 'list']), isLoggedIn: jwt !== null && !changePassword, - loading: siteId === null || userInfoLoading || metaLoading, + loading: siteId === null || userInfoLoading, email: state.getIn(['user', 'account', 'email']), account: state.getIn(['user', 'account']), organisation: state.getIn(['user', 'account', 'name']), @@ -112,7 +110,6 @@ const ONBOARDING_REDIRECT_PATH = routes.onboarding(OB_DEFAULT_TAB); fetchUserInfo, fetchTenants, setSessionPath, - fetchMetadata, fetchSiteList, fetchAnnouncements, fetchAlerts, @@ -133,7 +130,6 @@ class Router extends React.Component { await this.props.fetchSiteList() const { mstore } = this.props; mstore.initClient(); - await this.props.fetchMetadata(); }; componentDidMount() { diff --git a/frontend/app/components/Header/Header.js b/frontend/app/components/Header/Header.js index 8b08d48f5..60536ba24 100644 --- a/frontend/app/components/Header/Header.js +++ b/frontend/app/components/Header/Header.js @@ -23,7 +23,7 @@ import { init as initSite } from 'Duck/site'; import ErrorGenPanel from 'App/dev/components'; import Alerts from '../Alerts/Alerts'; import AnimatedSVG, { ICONS } from '../shared/AnimatedSVG/AnimatedSVG'; -import { fetchList as fetchMetadata } from 'Duck/customField'; +import { fetchListActive as fetchMetadata } from 'Duck/customField'; import { useStore } from 'App/mstore'; import { useObserver } from 'mobx-react-lite'; @@ -57,7 +57,7 @@ const Header = (props) => { Promise.all([ userStore.fetchLimits(), notificationStore.fetchNotificationsCount(), - // props.fetchMetadata(), + props.fetchMetadata(), ]).then(() => { userStore.updateKey('initialDataFetched', true); }); diff --git a/frontend/app/components/Header/SiteDropdown.js b/frontend/app/components/Header/SiteDropdown.js index 7f89eee82..08c4c8d59 100644 --- a/frontend/app/components/Header/SiteDropdown.js +++ b/frontend/app/components/Header/SiteDropdown.js @@ -11,7 +11,7 @@ import styles from './siteDropdown.module.css'; import cn from 'classnames'; import { clearSearch } from 'Duck/search'; import { clearSearch as clearSearchLive } from 'Duck/liveSearch'; -import { fetchList as fetchIntegrationVariables } from 'Duck/customField'; +import { fetchListActive as fetchIntegrationVariables } from 'Duck/customField'; import { withStore } from 'App/mstore'; import AnimatedSVG, { ICONS } from '../shared/AnimatedSVG/AnimatedSVG'; import NewProjectButton from './NewProjectButton'; diff --git a/frontend/app/components/shared/Filters/FilterModal/FilterModal.tsx b/frontend/app/components/shared/Filters/FilterModal/FilterModal.tsx index 770b66adc..c833583f7 100644 --- a/frontend/app/components/shared/Filters/FilterModal/FilterModal.tsx +++ b/frontend/app/components/shared/Filters/FilterModal/FilterModal.tsx @@ -34,7 +34,7 @@ interface Props { filters: any, onFilterClick?: (filter) => void, filterSearchList: any, - metaOptions: any, + // metaOptions: any, isMainSearch?: boolean, fetchingFilterSearchList: boolean, searchQuery?: string, @@ -127,7 +127,7 @@ export default connect((state: any, props: any) => { filterSearchList: props.isLive ? state.getIn([ 'liveSearch', 'filterSearchList' ]) : state.getIn([ 'search', 'filterSearchList' ]), // filterSearchList: state.getIn([ 'search', 'filterSearchList' ]), // liveFilterSearchList: state.getIn([ 'liveSearch', 'filterSearchList' ]), - metaOptions: state.getIn([ 'customFields', 'list' ]), + // metaOptions: state.getIn([ 'customFields', 'list' ]), fetchingFilterSearchList: props.isLive ? state.getIn(['liveSearch', 'fetchFilterSearch', 'loading']) : state.getIn(['search', 'fetchFilterSearch', 'loading']), diff --git a/frontend/app/components/shared/SessionSearch/SessionSearch.tsx b/frontend/app/components/shared/SessionSearch/SessionSearch.tsx index 7f8eb6262..48856d929 100644 --- a/frontend/app/components/shared/SessionSearch/SessionSearch.tsx +++ b/frontend/app/components/shared/SessionSearch/SessionSearch.tsx @@ -12,12 +12,14 @@ interface Props { edit: typeof edit; addFilter: typeof addFilter; saveRequestPayloads: boolean; + metaLoading?: boolean } function SessionSearch(props: Props) { - const { appliedFilter, saveRequestPayloads = false } = props; + const { appliedFilter, saveRequestPayloads = false, metaLoading } = props; const hasEvents = appliedFilter.filters.filter((i: any) => i.isEvent).size > 0; const hasFilters = appliedFilter.filters.filter((i: any) => !i.isEvent).size > 0; + const onAddFilter = (filter: any) => { props.addFilter(filter); }; @@ -53,7 +55,7 @@ function SessionSearch(props: Props) { }); }; - return ( + return !metaLoading && ( <> {hasEvents || hasFilters ? ( @@ -98,6 +100,7 @@ export default connect( (state: any) => ({ saveRequestPayloads: state.getIn(['site', 'instance', 'saveRequestPayloads']), appliedFilter: state.getIn(['search', 'instance']), + metaLoading: state.getIn(['customFields', 'fetchRequestActive', 'loading']) }), { edit, addFilter } )(SessionSearch); diff --git a/frontend/app/duck/customField.js b/frontend/app/duck/customField.js index 76378a2b3..d77987d05 100644 --- a/frontend/app/duck/customField.js +++ b/frontend/app/duck/customField.js @@ -4,15 +4,16 @@ import { fetchListType, saveType, editType, initType, removeType } from './funcT import { createItemInListUpdater, mergeReducers, success, array } from './funcTools/tools'; import { createEdit, createInit } from './funcTools/crud'; import { createRequestReducer } from './funcTools/request'; -import { addElementToFiltersMap, addElementToLiveFiltersMap } from 'Types/filter/newFilter'; +import { addElementToFiltersMap, addElementToLiveFiltersMap, clearMetaFilters } from 'Types/filter/newFilter'; import { FilterCategory } from '../types/filter/filterType'; -import { refreshFilterOptions } from './search' +import { refreshFilterOptions } from './search'; -const name = "integration/variable"; +const name = 'integration/variable'; const idKey = 'index'; const itemInListUpdater = createItemInListUpdater(idKey); const FETCH_LIST = fetchListType(name); +const FETCH_LIST_ACTIVE = fetchListType(name + '_ACTIVE'); const SAVE = saveType(name); const UPDATE = saveType(name); const EDIT = editType(name); @@ -21,6 +22,7 @@ const INIT = initType(name); const FETCH_SOURCES = fetchListType('integration/sources'); const FETCH_SUCCESS = success(FETCH_LIST); +const FETCH_LIST_ACTIVE_SUCCESS = success(FETCH_LIST_ACTIVE); const SAVE_SUCCESS = success(SAVE); const UPDATE_SUCCESS = success(UPDATE); const REMOVE_SUCCESS = success(REMOVE); @@ -31,33 +33,41 @@ const initialState = Map({ list: List(), instance: CustomField(), sources: List(), - optionsReady: false + optionsReady: false, }); const reducer = (state = initialState, action = {}) => { - switch(action.type) { - case FETCH_SUCCESS: - action.data.forEach(item => { + switch (action.type) { + case FETCH_SUCCESS: + return state.set('list', List(action.data).map(CustomField)) + case FETCH_LIST_ACTIVE_SUCCESS: + clearMetaFilters(); + action.data.forEach((item) => { addElementToFiltersMap(FilterCategory.METADATA, item.key); addElementToLiveFiltersMap(FilterCategory.METADATA, item.key); }); - return state.set('list', List(action.data).map(CustomField)) - .set('optionsReady', true) //.concat(defaultMeta)) + return state; + case FETCH_SOURCES_SUCCESS: - return state.set('sources', List(action.data.map(({ value, ...item}) => ({label: value, key: value, ...item}))).map(CustomField)) + return state.set( + 'sources', + List(action.data.map(({ value, ...item }) => ({ label: value, key: value, ...item }))).map( + CustomField + ) + ); case SAVE_SUCCESS: case UPDATE_SUCCESS: - return state.update('list', itemInListUpdater(CustomField(action.data))) + return state.update('list', itemInListUpdater(CustomField(action.data))); case REMOVE_SUCCESS: - return state.update('list', list => list.filter(item => item.index !== action.index)); + return state.update('list', (list) => list.filter((item) => item.index !== action.index)); case INIT: return state.set('instance', CustomField(action.instance)); case EDIT: - return state.mergeIn([ 'instance' ], action.instance); - default: - return state; - } -} + return state.mergeIn(['instance'], action.instance); + default: + return state; + } +}; export const edit = createEdit(name); export const init = createInit(name); @@ -65,41 +75,47 @@ export const init = createInit(name); export const fetchList = (siteId) => (dispatch, getState) => { return dispatch({ types: array(FETCH_LIST), - call: client => client.get(siteId ? `/${siteId}/metadata` : '/metadata'), + call: (client) => client.get(siteId ? `/${siteId}/metadata` : '/metadata'), + }) +}; + +export const fetchListActive = (siteId) => (dispatch, getState) => { + return dispatch({ + types: array(FETCH_LIST_ACTIVE), + call: (client) => client.get(siteId ? `/${siteId}/metadata` : '/metadata'), }).then(() => { dispatch(refreshFilterOptions()); }); -} +}; export const fetchSources = () => { return { types: array(FETCH_SOURCES), - call: client => client.get('/integration/sources'), - } -} + call: (client) => client.get('/integration/sources'), + }; +}; export const save = (siteId, instance) => { - const url = instance.exists() - ? `/${siteId}/metadata/${instance.index}` - : `/${siteId}/metadata`; + const url = instance.exists() ? `/${siteId}/metadata/${instance.index}` : `/${siteId}/metadata`; return { types: array(instance.exists() ? SAVE : UPDATE), - call: client => client.post(url, instance.toData()), - } -} + call: (client) => client.post(url, instance.toData()), + }; +}; export const remove = (siteId, index) => { return { types: array(REMOVE), - call: client => client.delete(`/${siteId}/metadata/${index}`), + call: (client) => client.delete(`/${siteId}/metadata/${index}`), index, - } -} + }; +}; export default mergeReducers( - reducer, - createRequestReducer({ + reducer, + createRequestReducer({ fetchRequest: FETCH_LIST, + fetchRequestActive: FETCH_LIST_ACTIVE, saveRequest: SAVE, - }), -) \ No newline at end of file + }) +); diff --git a/frontend/app/types/filter/newFilter.js b/frontend/app/types/filter/newFilter.js index 452c4f1c9..31ad4125f 100644 --- a/frontend/app/types/filter/newFilter.js +++ b/frontend/app/types/filter/newFilter.js @@ -53,35 +53,48 @@ export const filters = [ { key: FilterKey.ISSUE, type: FilterType.ISSUE, category: FilterCategory.JAVASCRIPT, label: 'Issue', operator: 'is', operatorOptions: filterOptions.getOperatorsByKeys(['is', 'isAny', 'isNot']), icon: 'filters/click', options: filterOptions.issueOptions }, ]; -export const filtersMap = filters.reduce((acc, filter) => { +const mapFilters = (list) => { + return list.reduce((acc, filter) => { acc[filter.key] = filter; return acc; -}, {}); + }, {}); +} -export const liveFiltersMap = {} -filters.forEach(filter => { - if ( - filter.category !== FilterCategory.INTERACTIONS && - filter.category !== FilterCategory.JAVASCRIPT && - filter.category !== FilterCategory.PERFORMANCE && - filter.key !== FilterKey.DURATION && - filter.key !== FilterKey.REFERRER - ) { - liveFiltersMap[filter.key] = {...filter}; - liveFiltersMap[filter.key].operator = 'contains'; - liveFiltersMap[filter.key].operatorDisabled = true; - if (filter.key === FilterKey.PLATFORM) { - liveFiltersMap[filter.key].operator = 'is'; +const mapLiveFilters = (list) => { + const obj = {}; + list.forEach(filter => { + if ( + filter.category !== FilterCategory.INTERACTIONS && + filter.category !== FilterCategory.JAVASCRIPT && + filter.category !== FilterCategory.PERFORMANCE && + filter.key !== FilterKey.DURATION && + filter.key !== FilterKey.REFERRER + ) { + obj[filter.key] = {...filter}; + obj[filter.key].operator = 'contains'; + obj[filter.key].operatorDisabled = true; + if (filter.key === FilterKey.PLATFORM) { + obj[filter.key].operator = 'is'; + } } - } -}) + }) + return obj; +} export const filterLabelMap = filters.reduce((acc, filter) => { acc[filter.key] = filter.label return acc }, {}) +export let filtersMap = mapFilters(filters) +export let liveFiltersMap = mapLiveFilters(filters) + +export const clearMetaFilters = () => { + filtersMap = mapFilters(filters); + liveFiltersMap = mapLiveFilters(filters); +}; + /** * Add a new filter to the filter list * @param {*} category