ui: start moving saas-specific files

This commit is contained in:
nick-delirium 2025-03-28 14:02:53 +01:00
parent 85f6551b32
commit c16bf9644d
No known key found for this signature in database
GPG key ID: 93ABD695DF5FDBA0
12 changed files with 146 additions and 93 deletions

View file

@ -6,8 +6,8 @@ import { MODULES } from 'Components/Client/Modules';
import { useStore } from 'App/mstore';
import { observer } from 'mobx-react-lite';
import AssistStats from '../../AssistStats';
import Recordings from '../RecordingsList/Recordings';
import { useTranslation } from 'react-i18next';
import TrainingVideosBtn from './TrainingVideosBtn';
function AssistSearchActions() {
const { t } = useTranslation();
@ -23,12 +23,6 @@ function AssistSearchActions() {
const showStats = () => {
showModal(<AssistStats />, { right: true, width: 960 });
};
const showRecords = () => {
showModal(<Recordings />, { right: true, width: 960 });
};
const originStr = window.env.ORIGIN || window.location.origin;
const isSaas = /app\.openreplay\.com/.test(originStr);
return (
<div className="flex items-center w-full gap-2">
<h3 className="text-2xl capitalize mr-2">
@ -44,9 +38,7 @@ function AssistSearchActions() {
{t('Clear')}
</Button>
</Tooltip>
{!isSaas && isEnterprise && !modules.includes(MODULES.OFFLINE_RECORDINGS)
? <Button size={'small'} onClick={showRecords}>{t('Training Videos')}</Button> : null
}
<TrainingVideosBtn />
{isEnterprise && userStore.account?.admin && (
<Button size={'small'} onClick={showStats}
disabled={modules.includes(MODULES.ASSIST_STATS) || modules.includes(MODULES.ASSIST)}>

View file

@ -0,0 +1,32 @@
import React from 'react';
import { useModal } from 'App/components/Modal';
import { useStore } from 'App/mstore';
import { observer } from 'mobx-react-lite';
import { useTranslation } from 'react-i18next';
import { Button } from 'antd';
import { MODULES } from 'Components/Client/Modules';
import Recordings from '../RecordingsList/Recordings';
/** SAAS:
function TrainingVideosBtn() {
return null
}
*/
function TrainingVideosBtn() {
const { t } = useTranslation();
const { userStore } = useStore();
const modules = userStore.account.settings?.modules ?? [];
const { isEnterprise } = userStore;
const { showModal } = useModal();
const showRecords = () => {
showModal(<Recordings />, { right: true, width: 960 });
};
return (
isEnterprise && !modules.includes(MODULES.OFFLINE_RECORDINGS)
? <Button size={'small'} onClick={showRecords}>{t('Training Videos')}</Button> : null
)
}
export default observer(TrainingVideosBtn);

View file

@ -11,7 +11,6 @@ import {
AppWindow,
Combine,
Users,
Sparkles,
Globe,
MonitorSmartphone,
} from 'lucide-react';
@ -250,8 +249,6 @@ const AddCardSection = observer(
{ label: t('Web Analytics'), value: 'web_analytics' },
];
const originStr = window.env.ORIGIN || window.location.origin;
const isSaas = /api\.openreplay\.com/.test(originStr);
const onExistingClick = () => {
const dashboardId = dashboardStore.selectedDashboard?.dashboardId;
const siteId = projectsStore.activeSiteId;
@ -273,12 +270,6 @@ const AddCardSection = observer(
<div className="text-xl font-medium mb-1">
{t('What do you want to visualize?')}
</div>
{isSaas ? (
<div className="font-medium flex items-center gap-2 cursor-pointer">
<Sparkles color="#3C00FFD8" size={16} />
<div className="ai-gradient">{t('Ask AI')}</div>
</div>
) : null}
</div>
<div>
{options.length > 1 ? (

View file

@ -1,12 +1,12 @@
import { Card, Col, Modal, Row, Typography } from 'antd';
import { Col, Modal, Row, Typography } from 'antd';
import { GalleryVertical, Plus } from 'lucide-react';
import React from 'react';
import { useStore } from 'App/mstore';
import NewDashboardModal from 'Components/Dashboard/components/DashboardList/NewDashModal';
import AiQuery from './DashboardView/AiQuery';
import { useTranslation } from 'react-i18next';
import AiQuerySection, { panelSize } from './AiQuerySection';
interface Props {
open: boolean;
@ -32,8 +32,6 @@ function AddCardSelectionModal(props: Props) {
setOpen(true);
};
const originStr = window.env.ORIGIN || window.location.origin;
const isSaas = /app\.openreplay\.com/.test(originStr);
return (
<>
<Modal
@ -42,8 +40,9 @@ function AddCardSelectionModal(props: Props) {
footer={null}
onCancel={props.onClose}
className="addCard"
width={isSaas ? 900 : undefined}
width={panelSize}
>
<AiQuerySection />
<Row gutter={16} justify="center" className="py-5">
<Col span={12}>
<div

View file

@ -0,0 +1,30 @@
/** Saas:
import React from 'react'
import { Row } from 'antd'
import AiQuery from './DashboardView/AiQuery'
import { useTranslation } from 'react-i18next'
function AiQuerySection() {
const { t } = useTranslation()
return (
<>
<Row gutter={16} justify="center" className="py-2">
<AiQuery />
</Row>
<div className="flex items-center justify-center w-full text-disabled-text">
{t('or')}
</div>
</>
)
}
export const panelSize = 900
*/
function AiQuerySection() {
return null
}
export const panelSize = undefined
export default AiQuerySection

View file

@ -4,7 +4,7 @@ import { useStore } from 'App/mstore';
import { Loader } from 'UI';
import { withSiteId } from 'App/routes';
import withModal from 'App/components/Modal/withModal';
import { withRouter, RouteComponentProps } from 'react-router-dom';
import { RouteComponentProps } from 'react-router-dom';
import { useModal } from 'App/components/Modal';
import AlertFormModal from 'App/components/Alerts/AlertFormModal';
import withPageTitle from 'HOCs/withPageTitle';
@ -89,9 +89,6 @@ function DashboardView(props: Props) {
}, [dashboard]);
if (!dashboard) return null;
const originStr = window.env.ORIGIN || window.location.origin;
const isSaas = /app\.openreplay\.com/.test(originStr);
return (
<Loader loading={loading}>
<div
@ -104,7 +101,6 @@ function DashboardView(props: Props) {
siteId={siteId}
dashboardId={dashboardId}
/>
{isSaas ? <AiQuery /> : null}
<DashboardWidgetGrid
siteId={siteId}
dashboardId={dashboardId}

View file

@ -27,7 +27,7 @@ import {
} from 'App/mstore/uiPlayerStore';
import { useStore } from 'App/mstore';
import { session as sessionRoute, withSiteId } from 'App/routes';
import { SummaryButton } from 'Components/Session_/Player/Controls/Controls';
import SummaryButton from 'Components/Session_/Player/Controls/SummaryButton';
import useShortcuts from '../ReplayPlayer/useShortcuts';
import { useTranslation } from 'react-i18next';
@ -184,9 +184,6 @@ const DevtoolsButtons = observer(
} = store.get();
const showExceptions = exceptionsList.length > 0;
// @ts-ignore
const originStr = window.env.ORIGIN || window.location.origin;
const isSaas = /app\.openreplay\.com/.test(originStr);
const showSummary = () => {
player.pause();
@ -197,13 +194,11 @@ const DevtoolsButtons = observer(
};
return (
<>
{isSaas ? (
<SummaryButton
onClick={showSummary}
withToggle={bottomBlock === OVERVIEW}
toggleValue={aiSummaryStore.toggleSummary}
/>
) : null}
<SummaryButton
onClick={showSummary}
withToggle={bottomBlock === OVERVIEW}
toggleValue={aiSummaryStore.toggleSummary}
/>
<ControlButton
popover={
<div className="flex items-center gap-2">

View file

@ -10,7 +10,7 @@ import {
} from 'App/components/Session/playerContext';
import { useStore } from 'App/mstore';
import SummaryBlock from 'Components/Session/Player/ReplayPlayer/SummaryBlock';
import { SummaryButton } from 'Components/Session_/Player/Controls/Controls';
import SummaryButton from 'Components/Session_/Player/Controls/SummaryButton';
import TimelineZoomButton from 'Components/Session_/Player/Controls/components/TimelineZoomButton';
import { Icon, NoContent } from 'UI';
import TabSelector from '../../shared/DevTools/TabSelector';
@ -99,8 +99,6 @@ function MobileOverviewPanelCont() {
player.scale();
}, [selectedFeatures]);
const originStr = window.env.ORIGIN || window.location.origin;
const isSaas = /app\.openreplay\.com/.test(originStr);
return (
<PanelComponent
resources={resources}
@ -111,7 +109,7 @@ function MobileOverviewPanelCont() {
isMobile
performanceList={performanceList}
sessionId={sessionId}
showSummary={isSaas}
showSummary
toggleSummary={() =>
aiSummaryStore.setToggleSummary(!aiSummaryStore.toggleSummary)
}
@ -229,8 +227,6 @@ function WebOverviewPanelCont() {
],
);
const originStr = window.env.ORIGIN || window.location.origin;
const isSaas = /app\.openreplay\.com/.test(originStr);
return (
<PanelComponent
resources={resources}
@ -238,7 +234,7 @@ function WebOverviewPanelCont() {
selectedFeatures={selectedFeatures}
fetchPresented={fetchPresented}
setSelectedFeatures={setSelectedFeatures}
showSummary={isSaas}
showSummary
toggleSummary={() =>
aiSummaryStore.setToggleSummary(!aiSummaryStore.toggleSummary)
}

View file

@ -41,6 +41,7 @@ import Timeline from './Timeline';
import PlayerControls from './components/PlayerControls';
import styles from './controls.module.css';
import { useTranslation } from 'react-i18next';
import SummaryButton from './SummaryButton';
export const SKIP_INTERVALS = {
2: 2e3,
@ -231,11 +232,6 @@ const DevtoolsButtons = observer(
const { t } = useTranslation();
const { aiSummaryStore, integrationsStore } = useStore();
const { store, player } = React.useContext(PlayerContext);
// @ts-ignore
const originStr = window.env.ORIGIN || window.location.origin;
const isSaas = /app\.openreplay\.com/.test(originStr);
const { inspectorMode, currentTab, tabStates } = store.get();
const disableButtons = disabled;
@ -304,7 +300,7 @@ const DevtoolsButtons = observer(
const getLabel = (block: string) => labels[block][showIcons ? 'icon' : 'label']
return (
<>
{isSaas ? <SummaryButton onClick={showSummary} /> : null}
<SummaryButton onClick={showSummary} />
<ControlButton
popover={
<div className="flex items-center gap-2">
@ -435,37 +431,6 @@ const DevtoolsButtons = observer(
},
);
export function SummaryButton({
onClick,
withToggle,
onToggle,
toggleValue,
}: {
onClick?: () => void;
withToggle?: boolean;
onToggle?: () => void;
toggleValue?: boolean;
}) {
const { t } = useTranslation();
const [isHovered, setHovered] = React.useState(false);
return (
<div style={gradientButton} onClick={onClick}>
<div
style={isHovered ? onHoverFillStyle : fillStyle}
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
>
{withToggle ? (
<Switch size="small" checked={toggleValue} onChange={onToggle} />
) : null}
<Icon name="sparkles" size={16} />
<div className="font-semibold text-main">{t('Summary AI')}</div>
</div>
</div>
);
}
export const gradientButton = {
border: 'double 1px transparent',
borderRadius: '60px',
@ -479,7 +444,7 @@ export const gradientButton = {
alignItems: 'center',
justifyContent: 'center',
};
const onHoverFillStyle = {
export const onHoverFillStyle = {
width: '100%',
height: '100%',
display: 'flex',
@ -489,7 +454,7 @@ const onHoverFillStyle = {
padding: '1px 8px',
background: 'linear-gradient(156deg, #E3E6FF 0%, #E4F3F4 69.48%)',
};
const fillStyle = {
export const fillStyle = {
width: '100%',
height: '100%',
display: 'flex',

View file

@ -0,0 +1,44 @@
/** Saas
import React from 'react'
import { Switch, } from 'antd'
import { Icon } from 'UI';
import { useTranslation } from 'react-i18next';
import { gradientButton, onHoverFillStyle, fillStyle } from './Controls';
function SummaryButton({
onClick,
withToggle,
onToggle,
toggleValue,
}: {
onClick?: () => void;
withToggle?: boolean;
onToggle?: () => void;
toggleValue?: boolean;
}) {
const { t } = useTranslation();
const [isHovered, setHovered] = React.useState(false);
return (
<div style={gradientButton} onClick={onClick}>
<div
style={isHovered ? onHoverFillStyle : fillStyle}
onMouseEnter={() => setHovered(true)}
onMouseLeave={() => setHovered(false)}
>
{withToggle ? (
<Switch size="small" checked={toggleValue} onChange={onToggle} />
) : null}
<Icon name="sparkles" size={16} />
<div className="font-semibold text-main">{t('Summary AI')}</div>
</div>
</div>
);
}
*/
function SummaryButton(props: any) {
return null;
}
export default SummaryButton;

View file

@ -0,0 +1,14 @@
/** Saas
import React from 'react'
import AiSessionSearchField from 'Shared/SessionFilters/AiSessionSearchField';
function AiSearchSection() {
return <AiSessionSearchField />
}
*/
function AiSearchSection() {
return null
}
export default AiSearchSection

View file

@ -3,7 +3,7 @@ import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG';
import { observer } from 'mobx-react-lite';
import { useStore } from 'App/mstore';
import { Button, Tooltip } from 'antd';
import AiSessionSearchField from 'Shared/SessionFilters/AiSessionSearchField';
import AiSearchSection from './AiSearchSection';
import { useTranslation } from 'react-i18next';
import SavedSearch from '../SavedSearch/SavedSearch';
@ -30,13 +30,11 @@ function SearchActions() {
return t('Sessions');
}, [activeTab?.type, isEnterprise, i18n.language]);
// @ts-ignore
const originStr = window.env.ORIGIN || window.location.origin;
const isSaas = /app\.openreplay\.com/.test(originStr);
const showAiField = isSaas && activeTab?.type === 'sessions';
const showAiField = activeTab?.type === 'sessions';
const showPanel = hasEvents || hasFilters || aiFiltersStore.isLoading;
return !metaLoading ? (
<div className="mb-2">
{/* mobile */}
<div className={'flex flex-col lg:hidden items-start gap-2 w-full'}>
<div className='flex items-center justify-between w-full'>
<h2 className="text-2xl capitalize mr-4 inline">{title}</h2>
@ -54,12 +52,13 @@ function SearchActions() {
</Tooltip>
</div>
</div>
{isSaas ? <AiSessionSearchField/> : null}
<AiSearchSection />
</div>
{/* desktop */}
<div className={'hidden lg:flex items-center gap-2 w-full '}>
<h2 className="text-2xl capitalize mr-4">{title}</h2>
{isSaas && showAiField ? <AiSessionSearchField /> : null}
{showAiField ? <AiSearchSection /> : null}
<div className="ml-auto" />
<SavedSearch />
<Tooltip title={t('Clear Search Filters')}>