diff --git a/frontend/app/components/Client/Integrations/AssistDoc/AssistDoc.js b/frontend/app/components/Client/Integrations/AssistDoc/AssistDoc.js index 7e75ed186..1165af6ec 100644 --- a/frontend/app/components/Client/Integrations/AssistDoc/AssistDoc.js +++ b/frontend/app/components/Client/Integrations/AssistDoc/AssistDoc.js @@ -5,7 +5,6 @@ import AssistScript from './AssistScript'; import AssistNpm from './AssistNpm'; import { Tabs, CodeBlock } from 'UI'; import { useState } from 'react'; -import { connect } from 'react-redux'; import { observer } from 'mobx-react-lite' const NPM = 'NPM'; @@ -15,9 +14,9 @@ const TABS = [ { key: NPM, text: NPM }, ]; -const AssistDoc = (props) => { - const { integrationsStore } = useStore(); - const sites = props.sites ? props.sites.toJS() : [] +const AssistDoc = () => { + const { integrationsStore, projectsStore } = useStore(); + const sites = projectsStore.list; const siteId = integrationsStore.integrations.siteId const projectKey = siteId ? sites.find((site) => site.id === siteId)?.projectKey : sites[0]?.projectKey const [activeTab, setActiveTab] = useState(SCRIPT); @@ -58,9 +57,4 @@ const AssistDoc = (props) => { AssistDoc.displayName = 'AssistDoc'; -export default connect((state) => { - const sites = state.getIn(['site', 'list']); - return { - sites, - }; -})(observer(AssistDoc)); +export default observer(AssistDoc); diff --git a/frontend/app/components/Client/Integrations/GraphQLDoc/GraphQLDoc.js b/frontend/app/components/Client/Integrations/GraphQLDoc/GraphQLDoc.js index da06db940..2b7bb916a 100644 --- a/frontend/app/components/Client/Integrations/GraphQLDoc/GraphQLDoc.js +++ b/frontend/app/components/Client/Integrations/GraphQLDoc/GraphQLDoc.js @@ -3,12 +3,11 @@ import React from 'react'; import { CodeBlock } from "UI"; import DocLink from 'Shared/DocLink/DocLink'; import ToggleContent from 'Shared/ToggleContent'; -import { connect } from 'react-redux'; import { observer } from 'mobx-react-lite' -const GraphQLDoc = (props) => { - const { integrationsStore } = useStore(); - const sites = props.sites ? props.sites.toJS() : [] +const GraphQLDoc = () => { + const { integrationsStore, projectsStore } = useStore(); + const sites = projectsStore.list; const siteId = integrationsStore.integrations.siteId const projectKey = siteId ? sites.find((site) => site.id === siteId)?.projectKey : sites[0]?.projectKey const usage = `import OpenReplay from '@openreplay/tracker'; @@ -75,9 +74,4 @@ export const recordGraphQL = tracker.use(trackerGraphQL());` GraphQLDoc.displayName = 'GraphQLDoc'; -export default connect((state) => { - const sites = state.getIn(['site', 'list']); - return { - sites, - }; -})(observer(GraphQLDoc)); +export default observer(GraphQLDoc); diff --git a/frontend/app/components/Client/Integrations/MobxDoc/MobxDoc.js b/frontend/app/components/Client/Integrations/MobxDoc/MobxDoc.js index fb1c1ec3a..9c917f876 100644 --- a/frontend/app/components/Client/Integrations/MobxDoc/MobxDoc.js +++ b/frontend/app/components/Client/Integrations/MobxDoc/MobxDoc.js @@ -1,14 +1,13 @@ import React from 'react'; import ToggleContent from 'Shared/ToggleContent'; import DocLink from 'Shared/DocLink/DocLink'; -import { connect } from 'react-redux'; import { CodeBlock } from "UI"; import { useStore } from 'App/mstore'; import { observer } from 'mobx-react-lite'; -const MobxDoc = (props) => { - const { integrationsStore } = useStore(); - const sites = props.sites ? props.sites.toJS() : [] +const MobxDoc = () => { + const { integrationsStore, projectsStore } = useStore(); + const sites = projectsStore.list; const siteId = integrationsStore.integrations.siteId const projectKey = siteId ? sites.find((site) => site.id === siteId)?.projectKey : sites[0]?.projectKey @@ -72,9 +71,4 @@ function SomeFunctionalComponent() { MobxDoc.displayName = 'MobxDoc'; -export default connect((state) => { - const sites = state.getIn(['site', 'list']); - return { - sites, - }; -})(observer(MobxDoc)) +export default observer(MobxDoc) diff --git a/frontend/app/components/Client/Integrations/NgRxDoc/NgRxDoc.js b/frontend/app/components/Client/Integrations/NgRxDoc/NgRxDoc.js index a06981550..e4d199f5b 100644 --- a/frontend/app/components/Client/Integrations/NgRxDoc/NgRxDoc.js +++ b/frontend/app/components/Client/Integrations/NgRxDoc/NgRxDoc.js @@ -3,12 +3,11 @@ import React from 'react'; import { CodeBlock } from "UI"; import ToggleContent from 'Shared/ToggleContent'; import DocLink from 'Shared/DocLink/DocLink'; -import { connect } from 'react-redux'; import { observer } from 'mobx-react-lite' -const NgRxDoc = (props) => { - const { integrationsStore } = useStore(); - const sites = props.sites ? props.sites.toJS() : [] +const NgRxDoc = () => { + const { integrationsStore, projectsStore } = useStore(); + const sites = projectsStore.list; const siteId = integrationsStore.integrations.siteId const projectKey = siteId ? sites.find((site) => site.id === siteId)?.projectKey : sites[0]?.projectKey const usage = `import { StoreModule } from '@ngrx/store'; @@ -85,9 +84,4 @@ const metaReducers = [tracker.use(trackerNgRx())]; // check list of ava NgRxDoc.displayName = 'NgRxDoc'; -export default connect((state) => { - const sites = state.getIn(['site', 'list']); - return { - sites, - }; -})(observer(NgRxDoc)); +export default observer(NgRxDoc); diff --git a/frontend/app/components/Client/Integrations/ProfilerDoc/ProfilerDoc.js b/frontend/app/components/Client/Integrations/ProfilerDoc/ProfilerDoc.js index 4788768d0..35abc1eb0 100644 --- a/frontend/app/components/Client/Integrations/ProfilerDoc/ProfilerDoc.js +++ b/frontend/app/components/Client/Integrations/ProfilerDoc/ProfilerDoc.js @@ -1,15 +1,14 @@ import { useStore } from "App/mstore"; import React from 'react'; -import { connect } from 'react-redux'; import { observer } from 'mobx-react-lite'; import { CodeBlock } from 'UI'; import DocLink from 'Shared/DocLink/DocLink'; import ToggleContent from 'Shared/ToggleContent'; -const ProfilerDoc = (props) => { - const { integrationsStore } = useStore(); - const sites = props.sites ? props.sites.toJS() : [] +const ProfilerDoc = () => { + const { integrationsStore, projectsStore } = useStore(); + const sites = projectsStore.list; const siteId = integrationsStore.integrations.siteId const projectKey = siteId ? sites.find((site) => site.id === siteId)?.projectKey : sites[0]?.projectKey @@ -91,9 +90,4 @@ const fn = profiler('call_name')(() => { ProfilerDoc.displayName = 'ProfilerDoc'; -export default connect((state) => { - const sites = state.getIn(['site', 'list']); - return { - sites - }; -})(observer(ProfilerDoc)); +export default observer(ProfilerDoc); diff --git a/frontend/app/components/Client/Integrations/ReduxDoc/ReduxDoc.js b/frontend/app/components/Client/Integrations/ReduxDoc/ReduxDoc.js index b6b3a4b98..e782a2298 100644 --- a/frontend/app/components/Client/Integrations/ReduxDoc/ReduxDoc.js +++ b/frontend/app/components/Client/Integrations/ReduxDoc/ReduxDoc.js @@ -3,12 +3,11 @@ import React from 'react'; import { CodeBlock } from 'UI' import ToggleContent from 'Components/shared/ToggleContent'; import DocLink from 'Shared/DocLink/DocLink'; -import { connect } from 'react-redux'; import { observer } from 'mobx-react-lite' -const ReduxDoc = (props) => { - const { integrationsStore } = useStore(); - const sites = props.sites ? props.sites.toJS() : [] +const ReduxDoc = () => { + const { integrationsStore, projectsStore } = useStore(); + const sites = projectsStore.list; const siteId = integrationsStore.integrations.siteId const projectKey = siteId ? sites.find((site) => site.id === siteId)?.projectKey : sites[0]?.projectKey @@ -79,9 +78,4 @@ const store = createStore( ReduxDoc.displayName = 'ReduxDoc'; -export default connect((state) => { - const sites = state.getIn(['site', 'list']); - return { - sites - }; -})(observer(ReduxDoc)); +export default observer(ReduxDoc); diff --git a/frontend/app/components/Client/Integrations/VueDoc/VueDoc.js b/frontend/app/components/Client/Integrations/VueDoc/VueDoc.js index cf058537a..1c2ff19c6 100644 --- a/frontend/app/components/Client/Integrations/VueDoc/VueDoc.js +++ b/frontend/app/components/Client/Integrations/VueDoc/VueDoc.js @@ -3,12 +3,11 @@ import React from 'react'; import { CodeBlock } from "UI"; import ToggleContent from 'Components/shared/ToggleContent'; import DocLink from 'Shared/DocLink/DocLink'; -import { connect } from 'react-redux'; import { observer } from 'mobx-react-lite'; -const VueDoc = (props) => { - const { integrationsStore } = useStore(); - const sites = props.sites ? props.sites.toJS() : [] +const VueDoc = () => { + const { integrationsStore, projectsStore } = useStore(); + const sites = projectsStore.list; const siteId = integrationsStore.integrations.siteId const projectKey = siteId ? sites.find((site) => site.id === siteId)?.projectKey : sites[0]?.projectKey @@ -86,9 +85,4 @@ const store = new Vuex.Store({ VueDoc.displayName = 'VueDoc'; -export default connect((state) => { - const sites = state.getIn(['site', 'list']); - return { - sites, - }; -})(observer(VueDoc)); +export default observer(VueDoc); diff --git a/frontend/app/components/Client/Integrations/ZustandDoc/ZustandDoc.js b/frontend/app/components/Client/Integrations/ZustandDoc/ZustandDoc.js index ae11e06d9..eb7dcd091 100644 --- a/frontend/app/components/Client/Integrations/ZustandDoc/ZustandDoc.js +++ b/frontend/app/components/Client/Integrations/ZustandDoc/ZustandDoc.js @@ -3,12 +3,11 @@ import React from 'react'; import { CodeBlock } from "UI"; import ToggleContent from 'Components//shared/ToggleContent'; import DocLink from 'Shared/DocLink/DocLink'; -import { connect } from 'react-redux'; import { observer } from 'mobx-react-lite' const ZustandDoc = (props) => { - const { integrationsStore } = useStore(); - const sites = props.sites ? props.sites.toJS() : [] + const { integrationsStore, projectsStore } = useStore(); + const sites = projectsStore.list; const siteId = integrationsStore.integrations.siteId const projectKey = siteId ? sites.find((site) => site.id === siteId)?.projectKey : sites[0]?.projectKey @@ -102,9 +101,4 @@ const useBearStore = create( ZustandDoc.displayName = 'ZustandDoc'; -export default connect((state) => { - const sites = state.getIn(['site', 'list']); - return { - sites, - }; -})(observer(ZustandDoc)); +export default observer(ZustandDoc); diff --git a/frontend/app/components/Header/NewProjectButton/NewProjectButton.tsx b/frontend/app/components/Header/NewProjectButton/NewProjectButton.tsx index 2ac9e95ae..241136a63 100644 --- a/frontend/app/components/Header/NewProjectButton/NewProjectButton.tsx +++ b/frontend/app/components/Header/NewProjectButton/NewProjectButton.tsx @@ -1,40 +1,26 @@ +import { observer } from 'mobx-react-lite'; import React from 'react'; -import { Icon } from 'UI'; -import { useStore } from 'App/mstore'; -import { useObserver } from 'mobx-react-lite'; -import { useModal } from 'App/components/Modal'; + import NewSiteForm from 'App/components/Client/Sites/NewSiteForm'; -import { init } from 'Duck/site'; -import { connect } from 'react-redux'; -interface Props { - isAdmin?: boolean; - init?: (data: any) => void; -} -function NewProjectButton(props: Props) { - const { isAdmin = false } = props; - const { userStore } = useStore(); - const limtis = useObserver(() => userStore.limits); - const canAddProject = useObserver(() => isAdmin && (limtis.projects === -1 || limtis.projects > 0)); - const { showModal, hideModal } = useModal(); +import { useModal } from 'App/components/Modal'; +import { useStore } from 'App/mstore'; +import { Icon } from 'UI'; - const onClick = () => { - props.init({}); - showModal(, { right: true }); - }; +function NewProjectButton() { + const { projectsStore } = useStore(); + const { showModal, hideModal } = useModal(); - return ( -
  • - - Add Project -
  • - //
    - // - // Add New Project - //
    - ); + const onClick = () => { + projectsStore.initProject({}); + showModal(, { right: true }); + }; + + return ( +
  • + + Add Project +
  • + ); } -export default connect(null, { init })(NewProjectButton); +export default observer(NewProjectButton); diff --git a/frontend/app/components/Onboarding/components/OnboardingTabs/ProjectCodeSnippet/ProjectCodeSnippet.js b/frontend/app/components/Onboarding/components/OnboardingTabs/ProjectCodeSnippet/ProjectCodeSnippet.js index 831f962b6..e4ee5e2c4 100644 --- a/frontend/app/components/Onboarding/components/OnboardingTabs/ProjectCodeSnippet/ProjectCodeSnippet.js +++ b/frontend/app/components/Onboarding/components/OnboardingTabs/ProjectCodeSnippet/ProjectCodeSnippet.js @@ -1,8 +1,8 @@ import React, { useEffect, useState } from 'react'; -import { connect } from 'react-redux'; -import { editGDPR, saveGDPR, init } from 'Duck/site'; +import { useStore } from 'App/mstore'; +import { observer } from 'mobx-react-lite'; import { Checkbox, Loader, Toggler } from 'UI'; -import GDPR from 'Types/site/gdpr'; +import GDPR from 'App/mstore/types/gdpr'; import cn from 'classnames'; import stl from './projectCodeSnippet.module.css'; import CircleNumber from '../../CircleNumber'; @@ -18,37 +18,39 @@ const inputModeOptions = [ const inputModeOptionsMap = {}; inputModeOptions.forEach((o, i) => (inputModeOptionsMap[o.value] = i)); -const ProjectCodeSnippet = (props) => { - const { site } = props; - const { gdpr } = props.site; +const ProjectCodeSnippet = () => { + const { projectsStore } = useStore(); + const siteId = projectsStore.siteId; + const site = projectsStore.instance; + const gdpr = site.gdpr; + const sites = projectsStore.list; + const editGDPR = projectsStore.editGDPR; + const onSaveGDPR = projectsStore.saveGDPR; + const init = projectsStore.initProject; const [changed, setChanged] = useState(false); const [isAssistEnabled, setAssistEnabled] = useState(false); const [showLoader, setShowLoader] = useState(false); useEffect(() => { - const site = props.sites.find((s) => s.id === props.siteId); + const site = sites.find((s) => s.id === siteId); if (site) { - props.init(site); + init(site); } }, []); - const saveGDPR = (value) => { + const saveGDPR = () => { setChanged(true); - props.saveGDPR(site.id, GDPR({ ...value })); + void onSaveGDPR(site.id); }; const onChangeSelect = ({ name, value }) => { - const _gdpr = { ...gdpr.toData() }; - _gdpr[name] = value; - props.editGDPR({ [name]: value }); - saveGDPR(_gdpr); + editGDPR({ [name]: value }); + saveGDPR(); }; const onChangeOption = ({ target: { name, checked } }) => { - const _gdpr = { ...gdpr.toData() }; - _gdpr[name] = checked; - props.editGDPR({ [name]: checked }); - saveGDPR(_gdpr); + editGDPR({ [name]: checked }); + saveGDPR(); }; useEffect(() => { @@ -159,12 +161,4 @@ const ProjectCodeSnippet = (props) => { ); }; -export default connect( - (state) => ({ - siteId: state.getIn(['site', 'siteId']), - site: state.getIn(['site', 'instance']), - sites: state.getIn(['site', 'list']), - saving: state.getIn(['site', 'saveGDPR', 'loading']), - }), - { editGDPR, saveGDPR, init } -)(ProjectCodeSnippet); +export default observer(ProjectCodeSnippet); diff --git a/frontend/app/components/Onboarding/components/ProjectFormButton/ProjectFormButton.js b/frontend/app/components/Onboarding/components/ProjectFormButton/ProjectFormButton.js index da9f4211b..22405aead 100644 --- a/frontend/app/components/Onboarding/components/ProjectFormButton/ProjectFormButton.js +++ b/frontend/app/components/Onboarding/components/ProjectFormButton/ProjectFormButton.js @@ -1,10 +1,14 @@ import React from 'react'; -import { connect } from 'react-redux'; import NewSiteForm from '../../../Client/Sites/NewSiteForm'; -import { init } from 'Duck/site'; import { useModal } from 'App/components/Modal'; +import { observer } from 'mobx-react-lite' +import { useStore } from 'App/mstore'; -const ProjectFormButton = ({ sites, siteId, init }) => { +const ProjectFormButton = () => { + const { projectsStore } = useStore(); + const sites = projectsStore.list; + const siteId = projectsStore.siteId; + const init = projectsStore.initProject; const site = sites.find(({ id }) => id === siteId); const { showModal, hideModal } = useModal(); const openModal = (e) => { @@ -26,10 +30,4 @@ const ProjectFormButton = ({ sites, siteId, init }) => { ); }; -export default connect( - (state) => ({ - siteId: state.getIn(['site', 'siteId']), - sites: state.getIn(['site', 'list']), - }), - { init } -)(ProjectFormButton); +export default observer(ProjectFormButton); diff --git a/frontend/app/components/Session_/Player/Overlay/AutoplayTimer.tsx b/frontend/app/components/Session_/Player/Overlay/AutoplayTimer.tsx index 144d28208..40cd92231 100644 --- a/frontend/app/components/Session_/Player/Overlay/AutoplayTimer.tsx +++ b/frontend/app/components/Session_/Player/Overlay/AutoplayTimer.tsx @@ -2,21 +2,22 @@ import React, { useEffect, useState } from 'react'; import cn from 'classnames'; import { connect } from 'react-redux'; import { withRouter, RouteComponentProps } from 'react-router-dom'; -import { Button, Link, Icon } from 'UI'; +import { Button, Link } from 'UI'; import { session as sessionRoute, withSiteId } from 'App/routes'; import stl from './AutoplayTimer.module.css'; import clsOv from './overlay.module.css'; import AutoplayToggle from 'Shared/AutoplayToggle'; +import { useStore } from 'App/mstore'; interface IProps extends RouteComponentProps { nextId: number; - siteId: string; } -function AutoplayTimer({ nextId, siteId, history }: IProps) { +function AutoplayTimer({ nextId, history }: IProps) { let timer: NodeJS.Timer; const [cancelled, setCancelled] = useState(false); const [counter, setCounter] = useState(5); + const { projectsStore } = useStore(); useEffect(() => { if (counter > 0) { @@ -26,6 +27,7 @@ function AutoplayTimer({ nextId, siteId, history }: IProps) { } if (counter === 0) { + const siteId = projectsStore.getSiteId().siteId; history.push(withSiteId(sessionRoute(nextId), siteId)); } @@ -70,7 +72,6 @@ function AutoplayTimer({ nextId, siteId, history }: IProps) { export default withRouter( connect((state: any) => ({ - siteId: state.getIn(['site', 'siteId']), nextId: state.getIn(['sessions', 'nextId']), }))(AutoplayTimer) ); diff --git a/frontend/app/components/Session_/QueueControls/QueueControls.tsx b/frontend/app/components/Session_/QueueControls/QueueControls.tsx index a3ebb0557..c60f69607 100644 --- a/frontend/app/components/Session_/QueueControls/QueueControls.tsx +++ b/frontend/app/components/Session_/QueueControls/QueueControls.tsx @@ -8,11 +8,11 @@ import cn from 'classnames'; import { fetchAutoplaySessions } from 'Duck/search'; import { LeftOutlined, RightOutlined } from '@ant-design/icons'; import { Button, Popover } from 'antd' +import { useStore } from "App/mstore"; const PER_PAGE = 10; interface Props extends RouteComponentProps { - siteId: string; previousId: string; nextId: string; defaultList: any; @@ -24,8 +24,8 @@ interface Props extends RouteComponentProps { fetchAutoplaySessions: (page: number) => Promise; } function QueueControls(props: Props) { + const { projectsStore } = useStore(); const { - siteId, previousId, nextId, currentPage, @@ -54,10 +54,12 @@ function QueueControls(props: Props) { }, []); const nextHandler = () => { + const siteId = projectsStore.getSiteId().siteId!; props.history.push(withSiteId(sessionRoute(nextId), siteId)); }; const prevHandler = () => { + const siteId = projectsStore.getSiteId().siteId!; props.history.push(withSiteId(sessionRoute(previousId), siteId)); }; @@ -106,7 +108,6 @@ export default connect( (state: any) => ({ previousId: state.getIn(['sessions', 'previousId']), nextId: state.getIn(['sessions', 'nextId']), - siteId: state.getIn(['site', 'siteId']), currentPage: state.getIn(['search', 'currentPage']) || 1, total: state.getIn(['sessions', 'total']) || 0, sessionIds: state.getIn(['sessions', 'sessionIds']) || [], diff --git a/frontend/app/components/Session_/ScreenRecorder/ScreenRecorder.tsx b/frontend/app/components/Session_/ScreenRecorder/ScreenRecorder.tsx index 10f4595ee..1cecb3ffc 100644 --- a/frontend/app/components/Session_/ScreenRecorder/ScreenRecorder.tsx +++ b/frontend/app/components/Session_/ScreenRecorder/ScreenRecorder.tsx @@ -11,6 +11,7 @@ import { formatTimeOrDate } from 'App/date'; import { PlayerContext, ILivePlayerContext } from 'App/components/Session/playerContext'; import { observer } from 'mobx-react-lite'; import { ENTERPRISE_REQUEIRED } from 'App/constants'; +import { useStore } from 'App/mstore'; /** * "edge" || "edg/" chromium based edge (dev or canary) @@ -32,16 +33,16 @@ const supportedBrowsers = ['Chrome v91+', 'Edge v90+']; const supportedMessage = `Supported Browsers: ${supportedBrowsers.join(', ')}`; function ScreenRecorder({ - siteId, sessionId, agentId, isEnterprise, }: { - siteId: string; sessionId: string; isEnterprise: boolean; agentId: number, }) { + const { projectsStore } = useStore(); + const siteId = projectsStore.siteId; const { player, store } = React.useContext(PlayerContext) as ILivePlayerContext; const recordingState = store.get().recordingState; @@ -144,7 +145,6 @@ function ScreenRecorder({ export default connect((state: any) => ({ isEnterprise: state.getIn(['user', 'account', 'edition']) === 'ee' || state.getIn(['user', 'account', 'edition']) === 'msaas', - siteId: state.getIn(['site', 'siteId']), sessionId: state.getIn(['sessions', 'current']).sessionId, agentId: state.getIn(['user', 'account', 'id']), }))(observer(ScreenRecorder)); diff --git a/frontend/app/components/shared/ErrorsBadge/ErrorsBadge.js b/frontend/app/components/shared/ErrorsBadge/ErrorsBadge.js index d8d4ed323..6706608c5 100644 --- a/frontend/app/components/shared/ErrorsBadge/ErrorsBadge.js +++ b/frontend/app/components/shared/ErrorsBadge/ErrorsBadge.js @@ -1,6 +1,5 @@ import { observer } from 'mobx-react-lite'; import React, { useEffect } from 'react'; -import { connect } from 'react-redux'; import { DATE_RANGE_VALUES, getDateRangeFromValue } from 'App/dateRange'; import { useStore } from 'App/mstore'; @@ -11,8 +10,9 @@ const AUTOREFRESH_INTERVAL = 5 * 60 * 1000; const weekRange = getDateRangeFromValue(DATE_RANGE_VALUES.LAST_7_DAYS); let intervalId = null; -function ErrorsBadge({ projects }) { - const { errorsStore } = useStore(); +function ErrorsBadge() { + const { errorsStore, projectsStore } = useStore(); + const projects = projectsStore.list; const errorsStats = errorsStore.stats; useEffect(() => { if (projects.size === 0 || !!intervalId) return; @@ -21,20 +21,16 @@ function ErrorsBadge({ projects }) { startTimestamp: weekRange.start.ts, endTimestamp: weekRange.end.ts, }; - errorsStore.fetchNewErrorsCount(params); + void errorsStore.fetchNewErrorsCount(params); intervalId = setInterval(() => { - errorsStore.fetchNewErrorsCount(params); + void errorsStore.fetchNewErrorsCount(params); }, AUTOREFRESH_INTERVAL); }, [projects]); return errorsStats.unresolvedAndUnviewed > 0 ? (
    {
    }
    - ) : ( - '' - ); + ) : null; } -export default connect((state) => ({ - projects: state.getIn(['site', 'list']), -}))(observer(ErrorsBadge)); +export default observer(ErrorsBadge); diff --git a/frontend/app/components/shared/GettingStarted/StepList.tsx b/frontend/app/components/shared/GettingStarted/StepList.tsx index 485990434..178cb4aa1 100644 --- a/frontend/app/components/shared/GettingStarted/StepList.tsx +++ b/frontend/app/components/shared/GettingStarted/StepList.tsx @@ -5,7 +5,6 @@ import { Step } from 'App/mstore/types/gettingStarted'; import { useStore } from 'App/mstore'; import { onboarding as onboardingRoute, withSiteId } from 'App/routes'; import { RouteComponentProps, withRouter } from 'react-router'; -import { connect } from 'react-redux'; import { useModal } from 'App/components/Modal'; interface StepListProps extends RouteComponentProps { @@ -13,7 +12,6 @@ interface StepListProps extends RouteComponentProps { steps: Step[]; status: 'pending' | 'completed'; docsLink?: string; - siteId: string; } const StepItem = React.memo( @@ -63,11 +61,12 @@ const StepItem = React.memo( ); const StepList = React.memo((props: StepListProps) => { - const { title, steps, status } = props; + const { title, steps } = props; const { hideModal } = useModal(); const { settingsStore: { gettingStarted }, + projectsStore, } = useStore(); const onIgnore = (e: React.MouseEvent, step: any) => { @@ -80,7 +79,8 @@ const StepList = React.memo((props: StepListProps) => { } const onClick = (step: any) => { - const { siteId, history } = props; + const { history } = props; + const siteId = projectsStore.getSiteId().siteId!; hideModal(); history.push(withSiteId(onboardingRoute(step.url), siteId)); }; @@ -97,6 +97,4 @@ const StepList = React.memo((props: StepListProps) => { ); }); -export default connect((state: any) => ({ - siteId: state.getIn(['site', 'siteId']), -}))(withRouter(StepList)); +export default withRouter(StepList); diff --git a/frontend/app/components/shared/LiveSessionSearch/LiveSessionSearch.tsx b/frontend/app/components/shared/LiveSessionSearch/LiveSessionSearch.tsx index 289a05ac0..58ee93950 100644 --- a/frontend/app/components/shared/LiveSessionSearch/LiveSessionSearch.tsx +++ b/frontend/app/components/shared/LiveSessionSearch/LiveSessionSearch.tsx @@ -4,15 +4,18 @@ import FilterSelection from 'Shared/Filters/FilterSelection'; import { connect } from 'react-redux'; import { Button } from 'UI'; import { edit, addFilter } from 'Duck/liveSearch'; +import { observer } from 'mobx-react-lite'; +import { useStore } from 'App/mstore'; interface Props { appliedFilter: any; edit: typeof edit; addFilter: typeof addFilter; - saveRequestPayloads: boolean; } function LiveSessionSearch(props: Props) { - const { appliedFilter, saveRequestPayloads = false } = props; + const { appliedFilter } = props; + const { projectsStore } = useStore(); + const saveRequestPayloads = projectsStore.active?.saveRequestPayloads const hasEvents = appliedFilter.filters.filter(i => i.isEvent).size > 0; const hasFilters = appliedFilter.filters.filter(i => !i.isEvent).size > 0; @@ -89,6 +92,5 @@ function LiveSessionSearch(props: Props) { } export default connect(state => ({ - saveRequestPayloads: state.getIn(['site', 'active', 'saveRequestPayloads']), appliedFilter: state.getIn([ 'liveSearch', 'instance' ]), -}), { edit, addFilter })(LiveSessionSearch); \ No newline at end of file +}), { edit, addFilter })(observer(LiveSessionSearch)); \ No newline at end of file diff --git a/frontend/app/components/shared/MainSearchBar/MainSearchBar.tsx b/frontend/app/components/shared/MainSearchBar/MainSearchBar.tsx index 821c94959..90a749710 100644 --- a/frontend/app/components/shared/MainSearchBar/MainSearchBar.tsx +++ b/frontend/app/components/shared/MainSearchBar/MainSearchBar.tsx @@ -2,22 +2,24 @@ import React from 'react'; import SessionSearchField from 'Shared/SessionSearchField'; import AiSessionSearchField from 'Shared/SessionSearchField/AiSessionSearchField'; import SavedSearch from 'Shared/SavedSearch'; -// import { Button } from 'UI'; import { Button } from 'antd'; import { connect } from 'react-redux'; import { clearSearch } from 'Duck/search'; import TagList from './components/TagList'; +import { observer } from 'mobx-react-lite'; +import { useStore } from 'App/mstore'; interface Props { clearSearch: () => void; appliedFilter: any; savedSearch: any; - site: any; } const MainSearchBar = (props: Props) => { - const { appliedFilter, site } = props; - const currSite = React.useRef(site) + const { appliedFilter } = props; + const { projectsStore } = useStore(); + const projectId = projectsStore.siteId; + const currSite = React.useRef(projectId) const hasFilters = appliedFilter && appliedFilter.filters && appliedFilter.filters.size > 0; const hasSavedSearch = props.savedSearch && props.savedSearch.exists(); const hasSearch = hasFilters || hasSavedSearch; @@ -27,12 +29,12 @@ const MainSearchBar = (props: Props) => { const isSaas = /app\.openreplay\.com/.test(originStr); React.useEffect(() => { - if (site !== currSite.current && currSite.current !== undefined) { + if (projectId !== currSite.current && currSite.current !== undefined) { console.debug('clearing filters due to project change') props.clearSearch(); - currSite.current = site + currSite.current = projectId } - }, [site]) + }, [projectId]) return (
    @@ -60,9 +62,8 @@ export default connect( (state: any) => ({ appliedFilter: state.getIn(['search', 'instance']), savedSearch: state.getIn(['search', 'savedSearch']), - site: state.getIn(['site', 'siteId']), }), { clearSearch, } -)(MainSearchBar); +)(observer(MainSearchBar)); diff --git a/frontend/app/components/shared/ProjectDropdown/ProjectDropdown.tsx b/frontend/app/components/shared/ProjectDropdown/ProjectDropdown.tsx index f15493212..7b632f3d8 100644 --- a/frontend/app/components/shared/ProjectDropdown/ProjectDropdown.tsx +++ b/frontend/app/components/shared/ProjectDropdown/ProjectDropdown.tsx @@ -15,8 +15,6 @@ import NewSiteForm from 'Components/Client/Sites/NewSiteForm'; import { useModal } from 'Components/Modal'; import { clearSearch as clearSearchLive } from 'Duck/liveSearch'; import { clearSearch } from 'Duck/search'; -import { setSiteId } from 'Duck/site'; -import { init as initProject } from 'Duck/site'; import { Icon } from 'UI'; const { Text } = Typography; diff --git a/frontend/app/components/shared/SessionsTabOverview/components/SessionTags/SessionTags.tsx b/frontend/app/components/shared/SessionsTabOverview/components/SessionTags/SessionTags.tsx index 641f09657..f6dd45d47 100644 --- a/frontend/app/components/shared/SessionsTabOverview/components/SessionTags/SessionTags.tsx +++ b/frontend/app/components/shared/SessionsTabOverview/components/SessionTags/SessionTags.tsx @@ -5,6 +5,8 @@ import { Angry, CircleAlert, Skull, WifiOff } from 'lucide-react'; import React, { memo } from 'react'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; +import { observer } from 'mobx-react-lite'; +import { useStore } from 'App/mstore'; import { setActiveTab } from 'Duck/search'; import { Icon } from 'UI'; @@ -17,7 +19,6 @@ interface Tag { interface StateProps { activeTab: { type: string }; - tags: Tag[]; total: number; } @@ -36,7 +37,16 @@ const tagIcons = { } as Record const SessionTags: React.FC = memo( - ({ activeTab, tags, total, setActiveTab }) => { + ({ activeTab, total, setActiveTab }) => { + const { projectsStore } = useStore(); + const platform = projectsStore.active?.platform || ''; + const tags = issues_types.filter( + (tag) => + tag.type !== 'mouse_thrashing' && + (platform === 'web' + ? tag.type !== types.TAP_RAGE + : tag.type !== types.CLICK_RAGE) + ); const disable = activeTab.type === 'all' && total === 0; const options = tags.map((tag, i) => ({ @@ -114,18 +124,10 @@ export const TagItem: React.FC<{ )); const mapStateToProps = (state: any): StateProps => { - const platform = state.getIn(['site', 'active'])?.platform || ''; const activeTab = state.getIn(['search', 'activeTab']); - const filteredTags = issues_types.filter( - (tag) => - tag.type !== 'mouse_thrashing' && - (platform === 'web' - ? tag.type !== types.TAP_RAGE - : tag.type !== types.CLICK_RAGE) - ); const total = state.getIn(['sessions', 'total']) || 0; - return { activeTab, tags: filteredTags, total }; + return { activeTab, total }; }; const mapDispatchToProps = (dispatch: any): DispatchProps => @@ -136,4 +138,4 @@ const mapDispatchToProps = (dispatch: any): DispatchProps => dispatch ); -export default connect(mapStateToProps, mapDispatchToProps)(SessionTags); +export default connect(mapStateToProps, mapDispatchToProps)(observer(SessionTags)); diff --git a/frontend/app/components/shared/TrackerUpdateMessage/TrackerUpdateMessage.js b/frontend/app/components/shared/TrackerUpdateMessage/TrackerUpdateMessage.js deleted file mode 100644 index b95f4ecda..000000000 --- a/frontend/app/components/shared/TrackerUpdateMessage/TrackerUpdateMessage.js +++ /dev/null @@ -1,49 +0,0 @@ -import React, { useEffect } from 'react' -import { Icon } from 'UI' -import { connect } from 'react-redux' -import { withRouter } from 'react-router-dom'; -import { onboarding as onboardingRoute } from 'App/routes' -import { withSiteId } from 'App/routes'; -import { isGreaterOrEqualVersion } from 'App/utils' - -const TrackerUpdateMessage= (props) => { - const [needUpdate, setNeedUpdate] = React.useState(false) - const { sites, match: { params: { siteId } } } = props; - const activeSite = sites.find(s => s.id == siteId); - - useEffect(() => { - if (!activeSite || !activeSite.trackerVersion) return; - - const isLatest = isGreaterOrEqualVersion(activeSite.trackerVersion, window.env.TRACKER_VERSION); - if (!isLatest && activeSite.recorded) { - setNeedUpdate(true) - } - }, [activeSite]) - - return needUpdate ? ( - <> - {( -
    -
    -
    -
    - -
    -
    - There might be a mismatch between the tracker and the backend versions. Please make sure to props.history.push(withSiteId(onboardingRoute('installing'), siteId))}>update the tracker to latest version ({window.env.TRACKER_VERSION}). -
    -
    -
    -
    - )} - - ) : '' -} - -export default connect(state => ({ - site: state.getIn([ 'site', 'instance' ]), - sites: state.getIn([ 'site', 'list' ]) -}))(withRouter(TrackerUpdateMessage)) \ No newline at end of file diff --git a/frontend/app/components/shared/TrackerUpdateMessage/index.js b/frontend/app/components/shared/TrackerUpdateMessage/index.js deleted file mode 100644 index b9f95895d..000000000 --- a/frontend/app/components/shared/TrackerUpdateMessage/index.js +++ /dev/null @@ -1 +0,0 @@ -export { default } from './TrackerUpdateMessage' \ No newline at end of file diff --git a/frontend/app/components/shared/TrackingCodeModal/ProjectCodeSnippet/ProjectCodeSnippet.js b/frontend/app/components/shared/TrackingCodeModal/ProjectCodeSnippet/ProjectCodeSnippet.js index 4b51fc963..abe89daad 100644 --- a/frontend/app/components/shared/TrackingCodeModal/ProjectCodeSnippet/ProjectCodeSnippet.js +++ b/frontend/app/components/shared/TrackingCodeModal/ProjectCodeSnippet/ProjectCodeSnippet.js @@ -1,6 +1,6 @@ import React, { useState } from 'react' -import { connect } from 'react-redux'; -import { editGDPR, saveGDPR } from 'Duck/site'; +import { observer } from 'mobx-react-lite' +import { useStore } from 'Project/mstore' import { Checkbox } from 'UI'; import cn from 'classnames' import styles from './projectCodeSnippet.module.css' @@ -18,21 +18,25 @@ inputModeOptions.forEach((o, i) => inputModeOptionsMap[o.value] = i) const ProjectCodeSnippet = props => { - const { gdpr, site } = props; + const { projectsStore } = useStore(); + const site = props.site; + const gdpr = projectsStore.instance.gdpr; + const saveGdpr = projectsStore.saveGDPR; + const editGdpr = projectsStore.editGDPR; const [changed, setChanged] = useState(false) const saveGDPR = () => { setChanged(true) - props.saveGDPR(site.id); + saveGdpr(site.id); } const onChangeSelect = ({ name, value }) => { - props.editGDPR({ [ name ]: value }); + editGdpr({ [ name ]: value }); saveGDPR(); }; const onChangeOption = ({ target: { name, checked }}) => { - props.editGDPR({ [ name ]: checked }); + editGdpr({ [ name ]: checked }); saveGDPR() } @@ -94,7 +98,4 @@ const ProjectCodeSnippet = props => { ) } -export default connect(state => ({ - gdpr: state.getIn([ 'site', 'instance', 'gdpr' ]), - saving: state.getIn([ 'site', 'saveGDPR', 'loading' ]) -}), { editGDPR, saveGDPR })(ProjectCodeSnippet) +export default observer(ProjectCodeSnippet)