openreplay/frontend/app/components/Session/Player/SharedComponents/SessionTabs.tsx
Delirium 960da9f037
Tracker 14.x.x changes (#2240)
* feat tracker: add document titles to tabs

* feat: titles for tabs

* feat tracker: send initial title, parse titles better

* feat ui: tab name styles

* feat tracker: update changelogs

* fix tracker: fix tests

* fix tracker: fix failing tests, add some coverage

* fix tracker: fix failing tests, add some coverage

* Heatmaps  (#2264)

* feat ui: start heatmaps ui and tracker update

* fix ui: drop clickmap from session

* fix ui: refactor heatmap painter

* fix ui: store click coords as int percent

* feat(backend): insert normalized x and y to PG

* feat(backend): insert normalized x and y to CH

* feat(connector): added missing import

* feat(backend): fixed different uint type issue

* fix tracker: use max scrollable size for doc

* fix gen files

* fix ui: fix random crash, remove demo data generator

* fix ui: rm some dead code

---------

Co-authored-by: Alexander <zavorotynskiy@pm.me>

* fix tracker: add heatmap changelog to tracker CHANGELOG.md

* fix tracker: fix peerjs version to 1.5.4 (was 1.5.1)

* fix document height calculation

* Crossdomain tracking (#2277)

* feat tracker: crossdomain tracking (start commit)

* catch crossdomain messages, add nodeid placeholder

* click scroll

* frame placeholder number -> dynamic

* click rewriter, fix scroll prop

* some docs

* some docs

* fix options merging

* CHANGELOG.md update

* checking that crossdomain will not fire automatically

* simplify func declaration

* update test data

* change clickmap document height calculation to scrollheight (which should be true height)

---------

Co-authored-by: Alexander <zavorotynskiy@pm.me>
2024-06-24 13:49:26 +02:00

107 lines
2.9 KiB
TypeScript

import React from 'react';
import { observer } from 'mobx-react-lite';
import cn from 'classnames';
import Tab from './Tab';
import { PlayerContext } from 'Components/Session/playerContext';
import { useModal } from 'Components/Modal';
interface Props {
tabs: { tab: string; idx: number }[];
currentTab: string;
changeTab: (tab: string) => void;
hideModal: () => void;
}
function Modal({ tabs, currentTab, changeTab, hideModal }: Props) {
return (
<div className={'h-screen overflow-y-scroll'}>
<div className={'text-2xl font-semibold p-4'}>{tabs.length} Tabs</div>
{tabs.map((tab, i) => (
<div
key={tab.idx}
onClick={() => {
changeTab(tab.tab);
hideModal();
}}
className={cn(
currentTab === tab.tab ? 'font-semibold ' : 'text-disabled-text',
'cursor-pointer border-b p-4 hover:bg-active-blue'
)}
>
Tab {i + 1}
</div>
))}
</div>
);
}
function SessionTabs({ isLive }: { isLive?: boolean }) {
const { showModal, hideModal } = useModal();
const { player, store } = React.useContext(PlayerContext);
const { tabs = new Set('back-compat'), currentTab, closedTabs, tabNames } = store.get();
const tabsArr = Array.from(tabs).map((tab, idx) => ({
tab,
idx,
isClosed: closedTabs.includes(tab)
}));
const shouldTruncate = tabsArr.length > 10;
const actualTabs = shouldTruncate ? tabsArr.slice(0, 10) : tabsArr;
const shownTabs =
actualTabs.findIndex((el) => el.tab === currentTab) !== -1
? actualTabs
: actualTabs.concat({
tab: currentTab,
isClosed: false,
idx: tabsArr.findIndex((tEl) => tEl.tab === currentTab),
});
const changeTab = (tab: string) => {
if (isLive) return;
player.changeTab(tab);
};
const openModal = () => {
showModal(
<Modal hideModal={hideModal} currentTab={currentTab} changeTab={changeTab} tabs={tabsArr} />,
{
right: true,
}
);
};
return (
<>
{shownTabs.map((tab, i) => (
<React.Fragment key={tab.tab}>
<Tab
i={tab.idx}
tab={tab.tab}
currentTab={actualTabs.length === 1 ? tab.tab : currentTab}
changeTab={changeTab}
isLive={isLive}
isClosed={tab.isClosed}
name={tabNames[tab.tab]}
/>
</React.Fragment>
))}
{shouldTruncate ? (
<>
{tabsArr.length > 11 ? (
<div
onClick={openModal}
className={cn(
'self-end py-1 px-4 text-sm',
'cursor-pointer bg-active-blue text-blue',
'!border-t-transparent !border-l-transparent !border-r-transparent'
)}
>
+{tabsArr.length - 11} More
</div>
) : null}
</>
) : null}
</>
);
}
export default observer(SessionTabs);