fix(ui): bookmarks separation and other page titles

This commit is contained in:
Shekar Siri 2025-01-02 15:07:43 +01:00
parent e7e821daee
commit 22d04436c0
8 changed files with 135 additions and 17 deletions

View file

@ -2,8 +2,10 @@ import React from 'react';
import LiveSessionList from 'Shared/LiveSessionList';
import LiveSessionSearch from 'Shared/LiveSessionSearch';
import AssistSearchField from './AssistSearchField';
import usePageTitle from '@/hooks/usePageTitle';
function AssistView() {
usePageTitle('Co-Browse - OpenReplay');
return (
<div className="w-full mx-auto" style={{ maxWidth: '1360px'}}>
<AssistSearchField />

View file

@ -1,6 +1,5 @@
import React from 'react';
import { numberWithCommas } from 'App/utils';
import withPageTitle from 'HOCs/withPageTitle';
import withPermissions from 'HOCs/withPermissions';
import FFlagsListHeader from 'Components/FFlags/FFlagsListHeader';
import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG';
@ -9,8 +8,10 @@ import FFlagItem from './FFlagItem';
import { useStore } from 'App/mstore';
import { observer } from 'mobx-react-lite';
import Select from 'Shared/Select';
import usePageTitle from '@/hooks/usePageTitle';
function FFlagsList({ siteId }: { siteId: string }) {
usePageTitle('Feature Flags - OpenReplay');
const { featureFlagsStore, userStore } = useStore();
React.useEffect(() => {
@ -31,7 +32,7 @@ function FFlagsList({ siteId }: { siteId: string }) {
options={[
{ label: 'All', value: '0' as const },
{ label: 'Enabled', value: '1' as const },
{ label: 'Disabled', value: '2' as const },
{ label: 'Disabled', value: '2' as const }
]}
defaultValue={featureFlagsStore.activity}
plain
@ -45,7 +46,7 @@ function FFlagsList({ siteId }: { siteId: string }) {
<Select
options={[
{ label: 'Newest', value: 'DESC' },
{ label: 'Oldest', value: 'ASC' },
{ label: 'Oldest', value: 'ASC' }
]}
defaultValue={featureFlagsStore.sort.order}
plain
@ -65,7 +66,7 @@ function FFlagsList({ siteId }: { siteId: string }) {
<AnimatedSVG name={ICONS.NO_FFLAGS} size={60} />
<div className="text-center mt-4 text-lg font-medium">
{featureFlagsStore.sort.query === ''
? "You haven't created any feature flags yet"
? 'You haven\'t created any feature flags yet'
: 'No matching results'}
</div>
</div>
@ -121,6 +122,4 @@ function FFlagsList({ siteId }: { siteId: string }) {
);
}
export default withPageTitle('Feature Flags')(
withPermissions(['FEATURE_FLAGS'])(observer(FFlagsList))
);
export default withPermissions(['FEATURE_FLAGS'])(observer(FFlagsList));

View file

@ -1,8 +1,5 @@
import React, { useEffect } from 'react';
import React from 'react';
import withPageTitle from 'HOCs/withPageTitle';
import NoSessionsMessage from 'Shared/NoSessionsMessage';
import MainSearchBar from 'Shared/MainSearchBar';
import SessionSearch from 'Shared/SessionSearch';
import SessionsTabOverview from 'Shared/SessionsTabOverview/SessionsTabOverview';
import FFlagsList from 'Components/FFlags';
import NewFFlag from 'Components/FFlags/NewFFlag';
@ -13,7 +10,7 @@ import FlagView from 'Components/FFlags/FlagView/FlagView';
import { observer } from 'mobx-react-lite';
import { useStore } from '@/mstore';
import NotesList from 'Shared/SessionsTabOverview/components/Notes/NoteList';
import NoteTags from 'Shared/SessionsTabOverview/components/Notes/NoteTags';
import Bookmarks from 'Shared/SessionsTabOverview/components/Bookmarks/Bookmarks';
// @ts-ignore
interface IProps extends RouteComponentProps {
@ -38,11 +35,17 @@ function Overview({ match: { params } }: IProps) {
return (
<Switch>
<Route exact strict
path={[withSiteId(sessions(), siteId), withSiteId(bookmarks(), siteId)]}>
path={withSiteId(sessions(), siteId)}>
<div className="mb-5 w-full mx-auto" style={{ maxWidth: '1360px' }}>
<SessionsTabOverview />
</div>
</Route>
<Route exact strict
path={withSiteId(bookmarks(), siteId)}>
<div className="mb-5 w-full mx-auto" style={{ maxWidth: '1360px' }}>
<Bookmarks />
</div>
</Route>
<Route exact strict path={withSiteId(notes(), siteId)}>
<div className="mb-5 w-full mx-auto" style={{ maxWidth: '1360px' }}>
<NotesList />

View file

@ -9,11 +9,13 @@ import { observer } from 'mobx-react-lite';
import NoSessionsMessage from 'Shared/NoSessionsMessage/NoSessionsMessage';
import MainSearchBar from 'Shared/MainSearchBar/MainSearchBar';
import SessionSearch from 'Shared/SessionSearch/SessionSearch';
import usePageTitle from '@/hooks/usePageTitle';
function SessionsTabOverview() {
const [query, setQuery] = React.useState('');
const { aiFiltersStore, searchStore } = useStore();
const appliedFilter = searchStore.instance;
usePageTitle('Sessions - OpenReplay');
const handleKeyDown = (event: any) => {
if (event.key === 'Enter') {

View file

@ -0,0 +1,78 @@
import React, { useEffect } from 'react';
import SessionList from 'Shared/SessionsTabOverview/components/SessionList/SessionList';
import NoteTags from 'Shared/SessionsTabOverview/components/Notes/NoteTags';
import { Loader, NoContent, Pagination } from 'UI';
import AnimatedSVG from 'Shared/AnimatedSVG';
import { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG';
import NoteItem from 'Shared/SessionsTabOverview/components/Notes/NoteItem';
import { useStore } from '@/mstore';
import { observer } from 'mobx-react-lite';
import SessionItem from 'Shared/SessionItem/SessionItem';
import usePageTitle from '@/hooks/usePageTitle';
function Bookmarks() {
const { projectsStore, sessionStore, customFieldStore, userStore, searchStore } = useStore();
const isEnterprise = userStore.isEnterprise;
const isLoggedIn = userStore.isLoggedIn;
const bookmarks = sessionStore.bookmarks;
usePageTitle('Bookmarks - OpenReplay');
useEffect(() => {
void sessionStore.fetchBookmarkedSessions();
}, []);
return (
<div className="widget-wrapper">
<div className="flex items-center px-4 py-1 justify-between w-full">
<h2 className="text-2xl capitalize mr-4">Bookmarks</h2>
</div>
<div className="border-b" />
<Loader loading={bookmarks.loading}>
<NoContent
show={bookmarks.list.length === 0}
title={
<div className="flex flex-col items-center justify-center">
{/* <Icon name="no-dashboard" size={80} color="figmaColors-accent-secondary" /> */}
<AnimatedSVG name={ICONS.NO_BOOKMARKS} size={60} />
<div className="text-center mt-4 text-lg font-medium">No sessions bookmarked</div>
</div>
}
>
<div className="border-b rounded bg-white">
{bookmarks.list.map((session: any) => (
<div key={session.sessionId} className="border-b">
<SessionItem
session={session}
hasUserFilter={false}
// onUserClick={() => {}}
// metaList={metaList}
// lastPlayedSessionId={lastPlayedSessionId}
bookmarked={true}
// toggleFavorite={toggleFavorite}
/>
</div>
))}
</div>
<div className="w-full flex items-center justify-between py-4 px-6">
<div className="text-disabled-text">
Showing{' '}
<span className="font-semibold">{Math.min(bookmarks.list.length, bookmarks.pageSize)}</span> out
of <span className="font-semibold">{bookmarks.total}</span> sessions.
</div>
<Pagination
page={bookmarks.page}
total={bookmarks.total}
onPageChange={(page) => sessionStore.updateBookmarksPage(page)}
limit={bookmarks.pageSize}
debounceRequest={100}
/>
</div>
</NoContent>
</Loader>
</div>
);
}
export default observer(Bookmarks);

View file

@ -6,8 +6,10 @@ import { observer } from 'mobx-react-lite';
import { useStore } from 'App/mstore';
import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG';
import NoteTags from 'Shared/SessionsTabOverview/components/Notes/NoteTags';
import usePageTitle from '@/hooks/usePageTitle';
function NotesList() {
usePageTitle('Notes - OpenReplay');
const { notesStore } = useStore();
React.useEffect(() => {

View file

@ -16,11 +16,12 @@ function SessionHeader() {
const period = Period({ start: startDate, end: endDate, rangeName: rangeValue });
const title = useMemo(() => {
if (!activeTab) return;
if (activeTab.type === 'bookmarks') {
return isEnterprise ? 'Vault' : 'Bookmarks';
}
return 'Sessions';
}, [activeTab.type, isEnterprise]);
}, [isEnterprise, activeTab]);
const onDateChange = (e: any) => {
const dateValues = e.toJSON();
@ -32,10 +33,10 @@ function SessionHeader() {
<div className="flex items-center px-4 py-1 justify-between w-full">
<h2 className="text-2xl capitalize mr-4">{title}</h2>
<div className="flex items-center w-full justify-end">
{activeTab.type !== 'bookmarks' && <SessionTags />}
{activeTab?.type !== 'bookmarks' && <SessionTags />}
<div className="mr-auto" />
<Space>
{activeTab.type !== 'bookmarks' &&
{activeTab?.type !== 'bookmarks' &&
<SelectDateRange isAnt period={period} onChange={onDateChange} right={true} />}
<SessionSort />
</Space>

View file

@ -94,12 +94,19 @@ class DevTools {
}
}
interface Bookmarks {
list: Session[];
page: number;
total: number;
pageSize: number;
loading: boolean;
}
export default class SessionStore {
userFilter: UserFilter = new UserFilter();
devTools: DevTools = new DevTools();
list: Session[] = [];
bookmarks: Bookmarks = { list: [], page: 1, total: 0, pageSize: 10, loading: false };
sessionIds: string[] = [];
current = new Session();
total = 0;
@ -529,9 +536,33 @@ export default class SessionStore {
this.list = [];
this.total = 0;
this.sessionIds = [];
this.bookmarks = { list: [], page: 1, total: 0, pageSize: 10, loading: false };
}
setLastPlayedSessionId = (sessionId: string) => {
this.lastPlayedSessionId = sessionId;
}
async fetchBookmarkedSessions() {
try {
this.bookmarks.loading = true;
const params = {
page: this.bookmarks.page,
limit: this.bookmarks.pageSize,
bookmarked: true,
}
const data = await sessionService.getSessions(params);
this.bookmarks.list = data.sessions.map((s: any) => new Session(s));
this.bookmarks.total = data.total;
} catch (e) {
console.error(e);
} finally {
this.bookmarks.loading = false;
}
}
updateBookmarksPage(page: number) {
this.bookmarks.page = page;
void this.fetchBookmarkedSessions();
}
}