import React from 'react'; import { observer } from 'mobx-react-lite'; import { iTag } from 'App/services/NotesService'; import { useStore } from 'App/mstore'; import { numberWithCommas } from 'App/utils'; import { Pagination, NoContent, Loader } from 'UI'; import cn from 'classnames'; import { useQuery } from '@tanstack/react-query'; import { toast } from 'react-toastify'; import withPermissions from 'HOCs/withPermissions'; import { useHistory } from 'react-router'; import { highlights, withSiteId } from 'App/routes'; import HighlightsListHeader from './HighlightsListHeader'; import EditHlModal from './EditHlModal'; import HighlightPlayer from './HighlightPlayer'; import HighlightClip from './HighlightClip'; import { useTranslation } from 'react-i18next'; function HighlightsList() { const { t } = useTranslation(); const history = useHistory(); const params = new URLSearchParams(window.location.search); const hlId = params.get('highlight'); const { notesStore, projectsStore, userStore } = useStore(); const [activeId, setActiveId] = React.useState(null); const [editModalOpen, setEditModalOpen] = React.useState(false); const [editHl, setEditHl] = React.useState>({ message: '', isPublic: false, }); const currentUserId = userStore.account.id; React.useEffect(() => { if (hlId) { setActiveId(hlId); history.replace(withSiteId(highlights(), projectsStore.siteId)); } }, [hlId]); const activeProject = projectsStore.activeSiteId; const { query } = notesStore; const limit = notesStore.pageSize; const listLength = notesStore.notes.length; const { activeTags } = notesStore; const { page } = notesStore; const { ownOnly } = notesStore; const { data = { notes: [], total: 0 }, isPending, refetch, } = useQuery({ queryKey: ['notes', page, query, activeTags, activeProject], queryFn: () => notesStore.fetchNotes(), retry: 3, }); const { total, notes } = data; const debounceTimeout = React.useRef(0); const onSearch = (value: string) => { notesStore.setQuery(value); }; const handleInputChange = (e: React.ChangeEvent) => { const { value } = e.target; if (debounceTimeout.current) clearTimeout(debounceTimeout.current); debounceTimeout.current = window.setTimeout(() => { notesStore.setQuery(value); }, 500); }; const toggleTag = (tag?: iTag) => { notesStore.toggleTag(tag); }; const onPageChange = (page: number) => { notesStore.changePage(page); }; const onDelete = async (id: number) => { await notesStore.deleteNote(id); refetch(); toast.success(t('Highlight deleted successfully')); }; const onItemClick = (id: string) => { setActiveId(id); }; const onClose = () => { setActiveId(null); }; const onEdit = (id: string) => { const hl = notesStore.getNoteById(id); if (!hl) { return toast.error(t('Highlight not found in the list')); } setEditHl(hl); setEditModalOpen(true); }; const onSave = async (noteText: string, visible: boolean) => { if (!editHl) { return; } const newNote = { ...editHl, message: noteText, isPublic: visible, }; try { await notesStore.updateNote(editHl.noteId, newNote); toast.success(t('Highlight updated successfully')); } catch (e) { console.error(e); toast.error(t('Error updating highlight')); } setEditModalOpen(false); }; const toggleShared = (val: boolean) => { notesStore.toggleShared(val); refetch(); }; const isEmpty = !isPending && total === 0; return (
{activeId && }
{t('Highlight and note observations during session replays and share them with your team.')}
} > {notes.map((note) => ( onEdit(note.noteId)} onDelete={() => onDelete(note.noteId)} onItemClick={() => onItemClick(note.noteId)} /> ))} setEditModalOpen(false)} text={editHl?.message} visible={editHl?.isPublic} onSave={onSave} />
{t('Showing')}  {(page - 1) * limit + 1}  {t('to')}  {(page - 1) * limit + listLength}  {t('of')}  {numberWithCommas(total)}  {t('highlights')}.
); } export default withPermissions( ['SESSION_REPLAY', 'SERVICE_SESSION_REPLAY'], '', false, false, )(observer(HighlightsList));