move all critical components, drop site duck
This commit is contained in:
parent
c2bc023c5e
commit
997d69c389
19 changed files with 108 additions and 267 deletions
|
|
@ -14,6 +14,7 @@ import withLocationHandlers from 'HOCs/withLocationHandlers';
|
|||
import APIClient from 'App/api_client';
|
||||
import { useLocation } from 'react-router-dom';
|
||||
import { toast } from 'react-toastify';
|
||||
import { useStore } from 'App/mstore';
|
||||
|
||||
interface Props {
|
||||
session: Session;
|
||||
|
|
@ -26,7 +27,6 @@ interface Props {
|
|||
query?: Record<string, (key: string) => any>;
|
||||
request: () => void;
|
||||
userId: number;
|
||||
siteId: number;
|
||||
}
|
||||
|
||||
let playerInst: ILivePlayerContext['player'] | undefined;
|
||||
|
|
@ -40,7 +40,6 @@ function LivePlayer({
|
|||
query,
|
||||
isEnterprise,
|
||||
userId,
|
||||
siteId,
|
||||
}: Props) {
|
||||
// @ts-ignore
|
||||
const [contextValue, setContextValue] = useState<ILivePlayerContext>(defaultContextValue);
|
||||
|
|
@ -48,8 +47,10 @@ function LivePlayer({
|
|||
const openedFromMultiview = query?.get('multi') === 'true';
|
||||
const usedSession = isMultiview ? customSession! : session;
|
||||
const location = useLocation();
|
||||
const { projectsStore } = useStore();
|
||||
|
||||
useEffect(() => {
|
||||
const projectId = projectsStore.getSiteId();
|
||||
playerInst = undefined;
|
||||
if (!usedSession.sessionId || contextValue.player !== undefined) return;
|
||||
console.debug('creating live player for', usedSession.sessionId);
|
||||
|
|
@ -69,7 +70,7 @@ function LivePlayer({
|
|||
sessionWithAgentData,
|
||||
data,
|
||||
userId,
|
||||
siteId,
|
||||
projectId,
|
||||
(state) => makeAutoObservable(state),
|
||||
toast
|
||||
);
|
||||
|
|
@ -81,7 +82,7 @@ function LivePlayer({
|
|||
sessionWithAgentData,
|
||||
null,
|
||||
userId,
|
||||
siteId,
|
||||
projectId,
|
||||
(state) => makeAutoObservable(state),
|
||||
toast
|
||||
);
|
||||
|
|
@ -140,7 +141,6 @@ function LivePlayer({
|
|||
export default withPermissions(['ASSIST_LIVE', 'SERVICE_ASSIST_LIVE'], '', true, false)(
|
||||
connect((state: any) => {
|
||||
return {
|
||||
siteId: state.getIn([ 'site', 'siteId' ]),
|
||||
session: state.getIn(['sessions', 'current']),
|
||||
showAssist: state.getIn(['sessions', 'showChatWindow']),
|
||||
isEnterprise: state.getIn(['user', 'account', 'edition']) === 'ee',
|
||||
|
|
|
|||
|
|
@ -22,7 +22,8 @@ const ASSIST_ROUTE = assistRoute();
|
|||
function LivePlayerBlockHeader(props: any) {
|
||||
const [hideBack, setHideBack] = React.useState(false);
|
||||
const { store } = React.useContext(PlayerContext);
|
||||
const { assistMultiviewStore } = useStore();
|
||||
const { assistMultiviewStore, projectsStore } = useStore();
|
||||
const siteId = projectsStore.siteId;
|
||||
const history = useHistory();
|
||||
const { width, height } = store.get();
|
||||
|
||||
|
|
@ -30,7 +31,6 @@ function LivePlayerBlockHeader(props: any) {
|
|||
session,
|
||||
metaList,
|
||||
closedLive = false,
|
||||
siteId,
|
||||
isMultiview,
|
||||
} = props;
|
||||
|
||||
|
|
@ -109,7 +109,6 @@ const PlayerHeaderCont = connect(
|
|||
isAssist,
|
||||
session,
|
||||
sessionPath: state.getIn(['sessions', 'sessionPath']),
|
||||
siteId: state.getIn(['site', 'siteId']),
|
||||
metaList: state.getIn(['customFields', 'list']).map((i: any) => i.key),
|
||||
closedLive: !!state.getIn(['sessions', 'errors']) || (isAssist && !session.live),
|
||||
};
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ function Controls(props: any) {
|
|||
const { player, store } = React.useContext(MobilePlayerContext);
|
||||
const history = useHistory();
|
||||
const { playing, completed, skip, speed, messagesLoading } = store.get();
|
||||
const { uiPlayerStore } = useStore();
|
||||
const { uiPlayerStore, projectsStore } = useStore();
|
||||
const fullscreen = uiPlayerStore.fullscreen;
|
||||
const bottomBlock = uiPlayerStore.bottomBlock;
|
||||
const toggleBottomBlock = uiPlayerStore.toggleBottomBlock
|
||||
|
|
@ -54,12 +54,12 @@ function Controls(props: any) {
|
|||
const fullscreenOff = uiPlayerStore.fullscreenOff;
|
||||
const changeSkipInterval = uiPlayerStore.changeSkipInterval;
|
||||
const skipInterval = uiPlayerStore.skipInterval;
|
||||
const siteId = projectsStore.siteId;
|
||||
const {
|
||||
session,
|
||||
setActiveTab,
|
||||
previousSessionId,
|
||||
nextSessionId,
|
||||
siteId,
|
||||
disableDevtools,
|
||||
} = props;
|
||||
|
||||
|
|
@ -289,7 +289,6 @@ export default connect(
|
|||
totalAssistSessions: state.getIn(['liveSearch', 'total']),
|
||||
previousSessionId: state.getIn(['sessions', 'previousId']),
|
||||
nextSessionId: state.getIn(['sessions', 'nextId']),
|
||||
siteId: state.getIn(['site', 'siteId']),
|
||||
};
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -23,13 +23,12 @@ function PlayerBlockHeader(props: any) {
|
|||
|
||||
const playerState = store?.get?.() || { width: 0, height: 0, showEvents: false };
|
||||
const { width = 0, height = 0, showEvents = false } = playerState;
|
||||
const { customFieldStore } = useStore();
|
||||
|
||||
const { customFieldStore, projectsStore } = useStore();
|
||||
const siteId = projectsStore.siteId!;
|
||||
const {
|
||||
session,
|
||||
fullscreen,
|
||||
metaList,
|
||||
siteId,
|
||||
setActiveTab,
|
||||
activeTab,
|
||||
history,
|
||||
|
|
@ -108,7 +107,6 @@ const PlayerHeaderCont = connect(
|
|||
sessionPath: state.getIn(['sessions', 'sessionPath']),
|
||||
local: state.getIn(['sessions', 'timezone']),
|
||||
funnelRef: state.getIn(['funnels', 'navRef']),
|
||||
siteId: state.getIn(['site', 'siteId']),
|
||||
metaList: state.getIn(['customFields', 'list']).map((i: any) => i.key),
|
||||
};
|
||||
},
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import QueueControls from 'Components/Session_/QueueControls';
|
|||
import Bookmark from 'Shared/Bookmark';
|
||||
import Issues from 'Components/Session_/Issues/Issues';
|
||||
import NotePopup from 'Components/Session_/components/NotePopup';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { connect } from 'react-redux';
|
||||
import { Tag } from 'antd'
|
||||
import { ShareAltOutlined } from '@ant-design/icons';
|
||||
|
|
@ -56,8 +55,7 @@ function SubHeader(props: any) {
|
|||
}
|
||||
|
||||
export default connect((state: any) => ({
|
||||
siteId: state.getIn(['site', 'siteId']),
|
||||
modules: state.getIn(['user', 'account', 'modules']) || [],
|
||||
integrations: state.getIn(['issues', 'list']),
|
||||
isIOS: state.getIn(['sessions', 'current']).platform === 'ios',
|
||||
}))(observer(SubHeader));
|
||||
}))(SubHeader);
|
||||
|
|
|
|||
|
|
@ -24,7 +24,8 @@ const SESSIONS_ROUTE = sessionsRoute();
|
|||
function PlayerBlockHeader(props: any) {
|
||||
const [hideBack, setHideBack] = React.useState(false);
|
||||
const { player, store } = React.useContext(PlayerContext);
|
||||
const { uxtestingStore, customFieldStore } = useStore()
|
||||
const { uxtestingStore, customFieldStore, projectsStore } = useStore()
|
||||
const siteId = projectsStore.siteId!;
|
||||
const playerState = store?.get?.() || { width: 0, height: 0, showEvents: false }
|
||||
const { width = 0, height = 0, showEvents = false } = playerState
|
||||
|
||||
|
|
@ -33,7 +34,6 @@ function PlayerBlockHeader(props: any) {
|
|||
fullscreen,
|
||||
metaList,
|
||||
closedLive = false,
|
||||
siteId,
|
||||
setActiveTab,
|
||||
activeTab,
|
||||
history,
|
||||
|
|
@ -137,7 +137,6 @@ const PlayerHeaderCont = connect(
|
|||
sessionPath: state.getIn(['sessions', 'sessionPath']),
|
||||
local: state.getIn(['sessions', 'timezone']),
|
||||
funnelRef: state.getIn(['funnels', 'navRef']),
|
||||
siteId: state.getIn(['site', 'siteId']),
|
||||
metaList: state.getIn(['customFields', 'list']).map((i: any) => i.key),
|
||||
};
|
||||
},
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ import React from 'react';
|
|||
import { Button, Checkbox, Input } from 'antd';
|
||||
import { useHistory } from 'react-router-dom';
|
||||
import { withSiteId, sessions } from 'App/routes';
|
||||
import store from 'App/store';
|
||||
import { useStore } from 'App/mstore';
|
||||
|
||||
interface Props {
|
||||
onSave: (name: string, ignoreClRage: boolean, ignoreDeadCl: boolean) => Promise<any>;
|
||||
|
|
@ -11,6 +11,7 @@ interface Props {
|
|||
|
||||
function SaveModal({ onSave, hideModal }: Props) {
|
||||
const history = useHistory();
|
||||
const { projectsStore } = useStore();
|
||||
const [name, setName] = React.useState('');
|
||||
const [ignoreClRage, setIgnoreClRage] = React.useState(false);
|
||||
const [ignoreDeadCl, setIgnoreDeadCl] = React.useState(false);
|
||||
|
|
@ -22,7 +23,7 @@ function SaveModal({ onSave, hideModal }: Props) {
|
|||
const saveAndOpen = () => {
|
||||
onSave(name, ignoreClRage, ignoreDeadCl).then((tagId) => {
|
||||
hideModal();
|
||||
const siteId = store.getState().getIn(['site', 'siteId']);
|
||||
const siteId = projectsStore.getSiteId() as unknown as string;
|
||||
history.push(withSiteId(sessions({ tnw: `is|${tagId}`, range: 'LAST_24_HOURS' }), siteId));
|
||||
});
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,20 +15,19 @@ import SessionTileFooter from './SessionTileFooter'
|
|||
function Multiview({
|
||||
total,
|
||||
fetchSessions,
|
||||
siteId,
|
||||
assistCredentials,
|
||||
customSetSessions,
|
||||
}: {
|
||||
total: number;
|
||||
customSetSessions: (data: any) => void;
|
||||
fetchSessions: (filter: any) => void;
|
||||
siteId: string;
|
||||
assistCredentials: any;
|
||||
list: Record<string, any>[];
|
||||
}) {
|
||||
const { showModal, hideModal } = useModal();
|
||||
|
||||
const { assistMultiviewStore } = useStore();
|
||||
const { assistMultiviewStore, projectsStore } = useStore();
|
||||
const siteId = projectsStore.siteId!;
|
||||
const history = useHistory();
|
||||
// @ts-ignore
|
||||
const { sessionsquery } = useParams();
|
||||
|
|
@ -128,7 +127,6 @@ function Multiview({
|
|||
export default connect(
|
||||
(state: any) => ({
|
||||
total: state.getIn(['liveSearch', 'total']),
|
||||
siteId: state.getIn(['site', 'siteId']),
|
||||
}),
|
||||
{
|
||||
fetchSessions,
|
||||
|
|
|
|||
|
|
@ -42,9 +42,10 @@ const CurrentTab = React.memo(() => (
|
|||
</Tab>
|
||||
));
|
||||
|
||||
function AssistTabs({ session, siteId }: { session: Record<string, any>; siteId: string }) {
|
||||
function AssistTabs({ session }: { session: Record<string, any> }) {
|
||||
const history = useHistory();
|
||||
const { assistMultiviewStore } = useStore();
|
||||
const { assistMultiviewStore, projectsStore } = useStore();
|
||||
const siteId = projectsStore.siteId!;
|
||||
|
||||
const placeholder = new Array(4 - assistMultiviewStore.sessions.length).fill(0);
|
||||
|
||||
|
|
@ -83,6 +84,4 @@ function AssistTabs({ session, siteId }: { session: Record<string, any>; siteId:
|
|||
);
|
||||
}
|
||||
|
||||
export default connect((state: any) => ({ siteId: state.getIn(['site', 'siteId']) }))(
|
||||
observer(AssistTabs)
|
||||
);
|
||||
export default observer(AssistTabs)
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ function getStorageName(type: any) {
|
|||
|
||||
function Controls(props: any) {
|
||||
const { player, store } = React.useContext(PlayerContext);
|
||||
const { uxtestingStore, uiPlayerStore } = useStore();
|
||||
const { uxtestingStore, uiPlayerStore, projectsStore } = useStore();
|
||||
const fullscreen = uiPlayerStore.fullscreen;
|
||||
const bottomBlock = uiPlayerStore.bottomBlock;
|
||||
const toggleBottomBlock = uiPlayerStore.toggleBottomBlock;
|
||||
|
|
@ -80,6 +80,7 @@ function Controls(props: any) {
|
|||
const skipInterval = uiPlayerStore.skipInterval;
|
||||
const showStorageRedux = !uiPlayerStore.hiddenHints.storage;
|
||||
const history = useHistory();
|
||||
const siteId = projectsStore.siteId;
|
||||
const {
|
||||
playing,
|
||||
completed,
|
||||
|
|
@ -95,7 +96,6 @@ function Controls(props: any) {
|
|||
session,
|
||||
previousSessionId,
|
||||
nextSessionId,
|
||||
siteId,
|
||||
setActiveTab,
|
||||
} = props;
|
||||
|
||||
|
|
@ -440,7 +440,6 @@ export default connect(
|
|||
totalAssistSessions: state.getIn(['liveSearch', 'total']),
|
||||
previousSessionId: state.getIn(['sessions', 'previousId']),
|
||||
nextSessionId: state.getIn(['sessions', 'nextId']),
|
||||
siteId: state.getIn(['site', 'siteId']),
|
||||
};
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,34 +1,40 @@
|
|||
import { ShareAltOutlined } from '@ant-design/icons';
|
||||
import { Button as AntButton, Popover, Switch, Tooltip } from 'antd';
|
||||
import cn from 'classnames';
|
||||
import { Link2 } from 'lucide-react';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import React, { useMemo } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import { PlayerContext } from 'App/components/Session/playerContext';
|
||||
import { IFRAME } from 'App/constants/storageKeys';
|
||||
import { useStore } from 'App/mstore';
|
||||
import { checkParam, truncateStringToFit } from 'App/utils';
|
||||
import SessionTabs from 'Components/Session/Player/SharedComponents/SessionTabs';
|
||||
import KeyboardHelp from 'Components/Session_/Player/Controls/components/KeyboardHelp';
|
||||
import { Icon } from 'UI';
|
||||
import {Link2} from 'lucide-react';
|
||||
import QueueControls from './QueueControls';
|
||||
|
||||
import Bookmark from 'Shared/Bookmark';
|
||||
|
||||
import SharePopup from '../shared/SharePopup/SharePopup';
|
||||
import Issues from './Issues/Issues';
|
||||
import QueueControls from './QueueControls';
|
||||
import NotePopup from './components/NotePopup';
|
||||
import { PlayerContext } from 'App/components/Session/playerContext';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { connect } from 'react-redux';
|
||||
import SessionTabs from 'Components/Session/Player/SharedComponents/SessionTabs';
|
||||
import { IFRAME } from 'App/constants/storageKeys';
|
||||
import cn from 'classnames';
|
||||
import { Switch, Button as AntButton, Popover, Tooltip } from 'antd';
|
||||
import { ShareAltOutlined } from '@ant-design/icons';
|
||||
import { checkParam, truncateStringToFit } from 'App/utils';
|
||||
|
||||
const localhostWarn = (project) => project + '_localhost_warn';
|
||||
const disableDevtools = 'or_devtools_uxt_toggle';
|
||||
|
||||
function SubHeader(props) {
|
||||
const localhostWarnKey = localhostWarn(props.siteId);
|
||||
const defaultLocalhostWarn = localStorage.getItem(localhostWarnKey) !== '1';
|
||||
const { uxtestingStore, projectsStore } = useStore();
|
||||
const defaultLocalhostWarn = React.useMemo(() => {
|
||||
const siteId = projectsStore.siteId;
|
||||
const localhostWarnKey = localhostWarn(siteId);
|
||||
return localStorage.getItem(localhostWarnKey) !== '1';
|
||||
}, [projectsStore.siteId]);
|
||||
const [showWarningModal, setWarning] = React.useState(defaultLocalhostWarn);
|
||||
const { store } = React.useContext(PlayerContext);
|
||||
const { location: currentLocation = 'loading...' } = store.get();
|
||||
const hasIframe = localStorage.getItem(IFRAME) === 'true';
|
||||
const { uxtestingStore } = useStore();
|
||||
const [hideTools, setHideTools] = React.useState(false);
|
||||
React.useEffect(() => {
|
||||
const hideDevtools = checkParam('hideTools');
|
||||
|
|
@ -46,10 +52,15 @@ function SubHeader(props) {
|
|||
return integrations.some((i) => i.token);
|
||||
}, [props.integrations]);
|
||||
|
||||
const locationTruncated = truncateStringToFit(currentLocation, window.innerWidth - 200);
|
||||
const locationTruncated = truncateStringToFit(
|
||||
currentLocation,
|
||||
window.innerWidth - 200
|
||||
);
|
||||
|
||||
const showWarning =
|
||||
currentLocation && /(localhost)|(127.0.0.1)|(0.0.0.0)/.test(currentLocation) && showWarningModal;
|
||||
currentLocation &&
|
||||
/(localhost)|(127.0.0.1)|(0.0.0.0)/.test(currentLocation) &&
|
||||
showWarningModal;
|
||||
const closeWarning = () => {
|
||||
localStorage.setItem(localhostWarnKey, '1');
|
||||
setWarning(false);
|
||||
|
|
@ -65,7 +76,11 @@ function SubHeader(props) {
|
|||
<div
|
||||
className="w-full px-4 flex items-center border-b relative"
|
||||
style={{
|
||||
background: uxtestingStore.isUxt() ? (props.live ? '#F6FFED' : '#EBF4F5') : undefined
|
||||
background: uxtestingStore.isUxt()
|
||||
? props.live
|
||||
? '#F6FFED'
|
||||
: '#EBF4F5'
|
||||
: undefined,
|
||||
}}
|
||||
>
|
||||
{showWarning ? (
|
||||
|
|
@ -77,7 +92,7 @@ function SubHeader(props) {
|
|||
left: '50%',
|
||||
bottom: '-24px',
|
||||
transform: 'translate(-50%, 0)',
|
||||
fontWeight: 500
|
||||
fontWeight: 500,
|
||||
}}
|
||||
>
|
||||
Some assets may load incorrectly on localhost.
|
||||
|
|
@ -114,7 +129,10 @@ function SubHeader(props) {
|
|||
trigger={
|
||||
<div className="relative">
|
||||
<Tooltip title="Share Session" placement="bottom">
|
||||
<AntButton size={'small'} className="flex items-center justify-center">
|
||||
<AntButton
|
||||
size={'small'}
|
||||
className="flex items-center justify-center"
|
||||
>
|
||||
<ShareAltOutlined />
|
||||
</AntButton>
|
||||
</Tooltip>
|
||||
|
|
@ -141,8 +159,8 @@ function SubHeader(props) {
|
|||
{locationTruncated && (
|
||||
<div className={'w-full bg-white border-b border-gray-lighter'}>
|
||||
<div className="flex w-fit items-center cursor-pointer color-gray-medium text-sm p-1">
|
||||
<Link2 className="mx-2" size={16} />
|
||||
<Tooltip title="Open in new tab" delay={0} placement='bottom'>
|
||||
<Link2 className="mx-2" size={16} />
|
||||
<Tooltip title="Open in new tab" delay={0} placement="bottom">
|
||||
<a href={currentLocation} target="_blank" className="truncate">
|
||||
{locationTruncated}
|
||||
</a>
|
||||
|
|
@ -155,7 +173,6 @@ function SubHeader(props) {
|
|||
}
|
||||
|
||||
export default connect((state) => ({
|
||||
siteId: state.getIn(['site', 'siteId']),
|
||||
integrations: state.getIn(['issues', 'list']),
|
||||
modules: state.getIn(['user', 'account', 'modules']) || []
|
||||
modules: state.getIn(['user', 'account', 'modules']) || [],
|
||||
}))(observer(SubHeader));
|
||||
|
|
|
|||
|
|
@ -1,23 +1,19 @@
|
|||
import React from 'react';
|
||||
import { Alert, Space, Button } from 'antd';
|
||||
import { connect } from 'react-redux';
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { useStore } from "App/mstore";
|
||||
import { onboarding as onboardingRoute } from 'App/routes';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
import * as routes from '../../../routes';
|
||||
import { indigo } from 'tailwindcss/colors';
|
||||
import { SquareArrowOutUpRight } from 'lucide-react';
|
||||
import { useHistory } from 'react-router';
|
||||
|
||||
|
||||
const withSiteId = routes.withSiteId;
|
||||
const indigoWithOpacity = `rgba(${parseInt(indigo[500].slice(1, 3), 16)}, ${parseInt(indigo[500].slice(3, 5), 16)}, ${parseInt(indigo[500].slice(5, 7), 16)}, 0.1)`; // 0.5 is the opacity level
|
||||
|
||||
|
||||
const NoSessionsMessage = (props) => {
|
||||
const {
|
||||
sites,
|
||||
siteId
|
||||
} = props;
|
||||
const NoSessionsMessage = () => {
|
||||
const { projectsStore } = useStore();
|
||||
const sites = projectsStore.list;
|
||||
const siteId = projectsStore.siteId;
|
||||
const history = useHistory();
|
||||
const activeSite = sites.find((s) => s.id === siteId);
|
||||
const showNoSessions = !!activeSite && !activeSite.recorded;
|
||||
|
|
@ -60,7 +56,4 @@ const NoSessionsMessage = (props) => {
|
|||
);
|
||||
};
|
||||
|
||||
export default connect((state) => ({
|
||||
site: state.getIn(['site', 'siteId']),
|
||||
sites: state.getIn(['site', 'list'])
|
||||
}))(withRouter(NoSessionsMessage));
|
||||
export default withRouter(observer(NoSessionsMessage));
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { useHistory } from 'react-router';
|
||||
|
||||
import {
|
||||
|
|
@ -8,6 +7,7 @@ import {
|
|||
withSiteId,
|
||||
} from 'App/routes';
|
||||
import { Icon, Link } from 'UI';
|
||||
import { useStore } from 'App/mstore';
|
||||
|
||||
const PLAY_ICON_NAMES = {
|
||||
notPlayed: 'play-fill',
|
||||
|
|
@ -30,6 +30,7 @@ interface Props {
|
|||
siteId?: string;
|
||||
}
|
||||
function PlayLink(props: Props) {
|
||||
const { projectsStore } = useStore();
|
||||
const { isAssist, viewed, sessionId, onClick = null, queryParams } = props;
|
||||
const history = useHistory();
|
||||
const defaultIconName = getDefaultIconName(viewed);
|
||||
|
|
@ -47,9 +48,10 @@ function PlayLink(props: Props) {
|
|||
: sessionRoute(sessionId);
|
||||
|
||||
const handleBeforeOpen = (e: any) => {
|
||||
const projectId = props.siteId ?? projectsStore.getSiteId().siteId!;
|
||||
const replayLink = withSiteId(
|
||||
link + (props.query ? props.query : ''),
|
||||
props.siteId
|
||||
projectId
|
||||
);
|
||||
if (props.beforeOpen) {
|
||||
// check for ctrl or shift
|
||||
|
|
@ -86,6 +88,4 @@ function PlayLink(props: Props) {
|
|||
);
|
||||
}
|
||||
|
||||
export default connect((state: any, props: Props) => ({
|
||||
siteId: props.siteId || state.getIn(['site', 'siteId']),
|
||||
}))(PlayLink);
|
||||
export default PlayLink
|
||||
|
|
|
|||
|
|
@ -28,8 +28,9 @@ interface Props {
|
|||
}
|
||||
|
||||
function SessionSearch(props: Props) {
|
||||
const { tagWatchStore, aiFiltersStore } = useStore();
|
||||
const { appliedFilter, saveRequestPayloads = false, metaLoading = false } = props;
|
||||
const { tagWatchStore, aiFiltersStore, projectsStore } = useStore();
|
||||
const saveRequestPayloads = projectsStore.instance?.saveRequestPayloads ?? false
|
||||
const { appliedFilter, metaLoading = false } = props;
|
||||
const hasEvents = appliedFilter.filters.filter((i: any) => i.isEvent).size > 0;
|
||||
const hasFilters = appliedFilter.filters.filter((i: any) => !i.isEvent).size > 0;
|
||||
|
||||
|
|
@ -154,7 +155,6 @@ function SessionSearch(props: Props) {
|
|||
|
||||
export default connect(
|
||||
(state: any) => ({
|
||||
saveRequestPayloads: state.getIn(['site', 'instance', 'saveRequestPayloads']),
|
||||
appliedFilter: state.getIn(['search', 'instance']),
|
||||
metaLoading: state.getIn(['customFields', 'fetchRequestActive', 'loading']),
|
||||
}),
|
||||
|
|
|
|||
|
|
@ -3,9 +3,12 @@ import ListingVisibility from './components/ListingVisibility';
|
|||
import DefaultPlaying from './components/DefaultPlaying';
|
||||
import DefaultTimezone from './components/DefaultTimezone';
|
||||
import CaptureRate from './components/CaptureRate';
|
||||
import { connect } from 'react-redux';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { useStore } from 'App/mstore';
|
||||
|
||||
function SessionSettings({ projectId }: { projectId: number }) {
|
||||
function SessionSettings() {
|
||||
const { projectsStore } = useStore();
|
||||
const projectId = projectsStore.siteId;
|
||||
return (
|
||||
<div className='bg-white box-shadow h-screen overflow-y-auto'>
|
||||
<div className='px-6 pt-6'>
|
||||
|
|
@ -32,6 +35,4 @@ function SessionSettings({ projectId }: { projectId: number }) {
|
|||
);
|
||||
}
|
||||
|
||||
export default connect((state: any) => ({
|
||||
projectId: state.getIn(['site', 'siteId'])
|
||||
}))(SessionSettings);
|
||||
export default observer(SessionSettings)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import ConditionalRecordingSettings from 'Shared/SessionSettings/components/Cond
|
|||
type Props = {
|
||||
isAdmin: boolean;
|
||||
isEnterprise?: boolean;
|
||||
projectId?: number;
|
||||
projectId?: string;
|
||||
setShowCaptureRate: (show: boolean) => void;
|
||||
open: boolean;
|
||||
showCaptureRate: boolean;
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { useStore } from 'App/mstore'
|
||||
import Select from 'Shared/Select';
|
||||
|
||||
const SiteDropdown = ({ contextName = '', sites, onChange, value }) => {
|
||||
const options = sites.map(site => ({ value: site.id, label: site.host })).toJS();
|
||||
const SiteDropdown = ({ contextName = '', onChange, value }) => {
|
||||
const { projectsStore } = useStore();
|
||||
const sites = projectsStore.list;
|
||||
const options = sites.map(site => ({ value: site.id, label: site.host }));
|
||||
return (
|
||||
<Select
|
||||
name={`${contextName}_site`}
|
||||
|
|
@ -17,6 +20,4 @@ const SiteDropdown = ({ contextName = '', sites, onChange, value }) => {
|
|||
|
||||
SiteDropdown.displayName = 'SiteDropdown';
|
||||
|
||||
export default connect(state => ({
|
||||
sites: state.getIn(['site', 'list'])
|
||||
}))(SiteDropdown);
|
||||
export default observer(SiteDropdown);
|
||||
|
|
@ -1,20 +1,23 @@
|
|||
import React from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { connect } from 'react-redux';
|
||||
import { observer } from 'mobx-react-lite'
|
||||
import { useStore } from "App/mstore";
|
||||
import cn from 'classnames';
|
||||
import { withSiteId } from 'App/routes';
|
||||
import styles from './link.module.css';
|
||||
|
||||
const OpenReplayLink = ({ siteId, to, className="", dispatch, ...other }) => (
|
||||
<Link
|
||||
{ ...other }
|
||||
className={ cn(className, styles.link , 'px-2', 'hover:text-inherit') }
|
||||
to={ withSiteId(to, siteId) }
|
||||
/>
|
||||
);
|
||||
const OpenReplayLink = ({ siteId, to, className="", dispatch, ...other }) => {
|
||||
const { projectsStore } = useStore();
|
||||
const projectId = projectsStore.siteId;
|
||||
return (
|
||||
<Link
|
||||
{ ...other }
|
||||
className={ cn(className, styles.link , 'px-2', 'hover:text-inherit') }
|
||||
to={ withSiteId(to, siteId ?? projectId) }
|
||||
/>
|
||||
)
|
||||
};
|
||||
|
||||
OpenReplayLink.displayName = 'OpenReplayLink';
|
||||
|
||||
export default connect((state, props) => ({
|
||||
siteId: props.siteId || state.getIn([ 'site', 'siteId' ])
|
||||
}))(OpenReplayLink);
|
||||
export default OpenReplayLink;
|
||||
|
|
@ -1,164 +0,0 @@
|
|||
import Site from "Types/site";
|
||||
import GDPR from 'Types/site/gdpr';
|
||||
import {
|
||||
mergeReducers,
|
||||
success,
|
||||
array,
|
||||
createListUpdater
|
||||
} from './funcTools/tools';
|
||||
import {
|
||||
createCRUDReducer,
|
||||
getCRUDRequestTypes,
|
||||
createInit,
|
||||
createEdit,
|
||||
createRemove,
|
||||
createUpdate,
|
||||
saveType
|
||||
} from './funcTools/crud';
|
||||
import { createRequestReducer } from './funcTools/request';
|
||||
import { Map, List, fromJS } from 'immutable';
|
||||
import { GLOBAL_HAS_NO_RECORDINGS, SITE_ID_STORAGE_KEY } from 'App/constants/storageKeys';
|
||||
|
||||
const storedSiteId = localStorage.getItem(SITE_ID_STORAGE_KEY);
|
||||
|
||||
const name = 'project';
|
||||
const idKey = 'id';
|
||||
const updateItemInList = createListUpdater(idKey);
|
||||
|
||||
const EDIT_GDPR = 'sites/EDIT_GDPR';
|
||||
const SAVE_GDPR = 'sites/SAVE_GDPR';
|
||||
const FETCH_GDPR = 'sites/FETCH_GDPR';
|
||||
const FETCH_LIST = 'sites/FETCH_LIST';
|
||||
const SET_SITE_ID = 'sites/SET_SITE_ID';
|
||||
const FETCH_GDPR_SUCCESS = success(FETCH_GDPR);
|
||||
const SAVE_GDPR_SUCCESS = success(SAVE_GDPR);
|
||||
const FETCH_LIST_SUCCESS = success(FETCH_LIST);
|
||||
const SAVE = saveType('sites/SAVE');
|
||||
|
||||
const UPDATE_PROJECT_RECORDING_STATUS = 'sites/UPDATE_PROJECT_RECORDING_STATUS';
|
||||
|
||||
const initialState = Map({
|
||||
list: List(),
|
||||
instance: fromJS(),
|
||||
remainingSites: undefined,
|
||||
siteId: null,
|
||||
active: null
|
||||
});
|
||||
|
||||
const reducer = (state = initialState, action = {}) => {
|
||||
switch (action.type) {
|
||||
case EDIT_GDPR:
|
||||
return state.mergeIn(['instance', 'gdpr'], action.gdpr);
|
||||
case FETCH_GDPR_SUCCESS:
|
||||
return state.mergeIn(['instance', 'gdpr'], action.data);
|
||||
case success(SAVE):
|
||||
const newSite = Site(action.data);
|
||||
return updateItemInList(state, newSite)
|
||||
.set('siteId', newSite.get('id'))
|
||||
.set('active', newSite);
|
||||
case SAVE_GDPR_SUCCESS:
|
||||
const gdpr = GDPR(action.data);
|
||||
return state.setIn(['instance', 'gdpr'], gdpr);
|
||||
case FETCH_LIST_SUCCESS:
|
||||
let siteId = state.get('siteId');
|
||||
const siteIds = action.data.map(s => parseInt(s.projectId));
|
||||
const siteExists = siteIds.includes(siteId);
|
||||
if (action.siteIdFromPath && siteIds.includes(parseInt(action.siteIdFromPath))) {
|
||||
siteId = action.siteIdFromPath;
|
||||
} else if (!siteId || !siteExists) {
|
||||
siteId = siteIds.includes(parseInt(storedSiteId))
|
||||
? storedSiteId
|
||||
: action.data[0].projectId;
|
||||
}
|
||||
const list = List(action.data.map(Site));
|
||||
const hasRecordings = list.some(s => s.recorded);
|
||||
if (!hasRecordings) {
|
||||
localStorage.setItem(GLOBAL_HAS_NO_RECORDINGS, true);
|
||||
} else {
|
||||
localStorage.removeItem(GLOBAL_HAS_NO_RECORDINGS);
|
||||
}
|
||||
|
||||
return state.set('list', list)
|
||||
.set('siteId', siteId)
|
||||
.set('active', list.find(s => parseInt(s.id) === parseInt(siteId)));
|
||||
case SET_SITE_ID:
|
||||
const _siteId = action.siteId ? action.siteId : state.get('list').get(0).id;
|
||||
localStorage.setItem(SITE_ID_STORAGE_KEY, _siteId);
|
||||
const site = state.get('list').find(s => parseInt(s.id) == _siteId);
|
||||
return state.set('siteId', _siteId).set('active', site);
|
||||
case UPDATE_PROJECT_RECORDING_STATUS:
|
||||
const { siteId: _siteIdToUpdate, status } = action;
|
||||
const siteToUpdate = state.get('list').find(s => parseInt(s.id) === parseInt(_siteIdToUpdate));
|
||||
const updatedSite = siteToUpdate.set('recorded', status);
|
||||
return updateItemInList(state, updatedSite);
|
||||
}
|
||||
return state;
|
||||
};
|
||||
|
||||
export function editGDPR(gdpr) {
|
||||
return {
|
||||
type: EDIT_GDPR,
|
||||
gdpr
|
||||
};
|
||||
}
|
||||
|
||||
export function fetchGDPR(siteId) {
|
||||
return {
|
||||
types: array(FETCH_GDPR),
|
||||
call: client => client.get(`/${siteId}/gdpr`)
|
||||
};
|
||||
}
|
||||
|
||||
export const saveGDPR = (siteId, gdpr) => (dispatch, getState) => {
|
||||
const g = getState().getIn(['site', 'instance', 'gdpr']);
|
||||
return dispatch({
|
||||
types: array(SAVE_GDPR),
|
||||
call: client => client.post(`/${siteId}/gdpr`, g.toData())
|
||||
});
|
||||
};
|
||||
|
||||
export function fetchList(siteId) {
|
||||
return {
|
||||
types: array(FETCH_LIST),
|
||||
call: client => client.get('/projects'),
|
||||
siteIdFromPath: siteId
|
||||
};
|
||||
}
|
||||
|
||||
export function save(site) {
|
||||
return {
|
||||
types: array(SAVE),
|
||||
call: client => client.post(`/projects`, site.toData())
|
||||
};
|
||||
}
|
||||
|
||||
// export const fetchList = createFetchList(name);
|
||||
export const init = createInit(name);
|
||||
export const edit = createEdit(name);
|
||||
// export const save = createSave(name);
|
||||
export const update = createUpdate(name);
|
||||
export const remove = createRemove(name);
|
||||
|
||||
export function setSiteId(siteId) {
|
||||
return {
|
||||
type: SET_SITE_ID,
|
||||
siteId
|
||||
};
|
||||
}
|
||||
|
||||
export const updateProjectRecordingStatus = (siteId, status) => {
|
||||
return {
|
||||
type: UPDATE_PROJECT_RECORDING_STATUS,
|
||||
siteId,
|
||||
status
|
||||
};
|
||||
};
|
||||
|
||||
export default mergeReducers(
|
||||
reducer,
|
||||
createCRUDReducer(name, Site, idKey),
|
||||
createRequestReducer({
|
||||
saveGDPR: SAVE_GDPR,
|
||||
...getCRUDRequestTypes(name)
|
||||
})
|
||||
);
|
||||
Loading…
Add table
Reference in a new issue