Skip to content

Commit

Permalink
Refactor Root-Only Filter Logic in History Tab
Browse files Browse the repository at this point in the history
This commit refactors the Root-Only Filter feature in the History tab. The filter logic has been moved inside useTransactionEvents to prevent props drilling and to group related functionalities by domain.
  • Loading branch information
gwbaik9717 committed Jul 21, 2024
1 parent f5e538a commit 437fae5
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 65 deletions.
73 changes: 66 additions & 7 deletions tools/devtools/src/devtools/contexts/YorkieSource.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,30 @@
* limitations under the License.
*/

import type { ReactNode } from 'react';
import type { Dispatch, ReactNode, SetStateAction } from 'react';
import {
createContext,
useCallback,
useContext,
useEffect,
useMemo,
useState,
} from 'react';

import type { SDKToPanelMessage, TransactionEvent } from 'yorkie-js-sdk';
import {
DocEventType,
type SDKToPanelMessage,
type TransactionEvent,
} from 'yorkie-js-sdk';
import { connectPort, sendToSDK } from '../../port';

const DocKeyContext = createContext<string>(null);
const YorkieDocContext = createContext(null);
const TransactionEventsContext = createContext<Array<TransactionEvent>>(null);
const TransactionEventsContext = createContext<{
events: Array<TransactionEvent>;
hidePresenceEvents: boolean;
setHidePresenceEvents: Dispatch<SetStateAction<boolean>>;
}>(null);

type Props = {
children?: ReactNode;
Expand All @@ -41,6 +50,10 @@ export function YorkieSourceProvider({ children }: Props) {
Array<TransactionEvent>
>([]);

// filter out presence events
const [hideTransactionPresenceEvents, setHideTransactionPresenceEvents] =
useState(false);

const resetDocument = () => {
setCurrentDocKey('');
setTransactionEvents([]);
Expand Down Expand Up @@ -94,7 +107,13 @@ export function YorkieSourceProvider({ children }: Props) {

return (
<DocKeyContext.Provider value={currentDocKey}>
<TransactionEventsContext.Provider value={transactionEvents}>
<TransactionEventsContext.Provider
value={{
events: transactionEvents,
hidePresenceEvents: hideTransactionPresenceEvents,
setHidePresenceEvents: setHideTransactionPresenceEvents,
}}
>
<YorkieDocContext.Provider value={[doc, setDoc]}>
{children}
</YorkieDocContext.Provider>
Expand All @@ -121,12 +140,52 @@ export function useYorkieDoc() {
return value;
}

export enum TransactionEventType {
Document = 'document',
Presence = 'presence',
}

export const getTransactionEventType = (
event: TransactionEvent,
): TransactionEventType => {
for (const docEvent of event) {
if (
docEvent.type === DocEventType.StatusChanged ||
docEvent.type === DocEventType.Snapshot ||
docEvent.type === DocEventType.LocalChange ||
docEvent.type === DocEventType.RemoteChange
) {
return TransactionEventType.Document;
}
}

return TransactionEventType.Presence;
};

export function useTransactionEvents() {
const value = useContext(TransactionEventsContext);
if (value === undefined) {
const { events, hidePresenceEvents, setHidePresenceEvents } = useContext(
TransactionEventsContext,
);

if (events === undefined) {
throw new Error(
'useTransactionEvents should be used within YorkieSourceProvider',
);
}
return value;

const filteredEvents = useMemo(
() =>
events.filter(
(event) =>
!hidePresenceEvents ||
getTransactionEventType(event) === TransactionEventType.Document,
),
[events, hidePresenceEvents],
);

return {
events: filteredEvents,
hidePresenceEvents,
setHidePresenceEvents,
};
}
38 changes: 7 additions & 31 deletions tools/devtools/src/devtools/panel/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,12 @@ import {
} from '../contexts/YorkieSource';
import { Document } from '../tabs/Document';
import { Presence } from '../tabs/Presence';
import {
History,
TransactionEventType,
getTransactionEventType,
} from '../tabs/History';
import { History } from '../tabs/History';
import { Separator } from '../components/ResizableSeparator';

const Panel = () => {
const currentDocKey = useCurrentDocKey();
const events = useTransactionEvents();
const { events } = useTransactionEvents();
const [, setDoc] = useYorkieDoc();
const [selectedEventIndexInfo, setSelectedEventIndexInfo] = useState({
index: null,
Expand All @@ -62,25 +58,8 @@ const Panel = () => {
});
const [hidePresenceTab, setHidePresenceTab] = useState(false);

// filter out presence events in History tab
const [hidePresenceEvent, setHidePresenceEvent] = useState(false);
const filteredEvents = useMemo(
() =>
events.filter((event) => {
if (!hidePresenceEvent) {
return true;
}

if (getTransactionEventType(event) === TransactionEventType.Presence) {
return false;
}
return true;
}),
[events, hidePresenceEvent],
);

useEffect(() => {
if (filteredEvents.length === 0) {
if (events.length === 0) {
// NOTE(chacha912): If there are no events, reset the SelectedEventIndexInfo.
setSelectedEventIndexInfo({
index: null,
Expand All @@ -91,21 +70,21 @@ const Panel = () => {

if (selectedEventIndexInfo.isLast) {
setSelectedEventIndexInfo({
index: filteredEvents.length - 1,
index: events.length - 1,
isLast: true,
});
}
}, [filteredEvents]);
}, [events]);

useEffect(() => {
if (selectedEventIndexInfo.index === null) return;
const doc = new yorkie.Document(currentDocKey);
for (let i = 0; i <= selectedEventIndexInfo.index; i++) {
doc.applyTransactionEvent(filteredEvents[i]);
doc.applyTransactionEvent(events[i]);
}

setDoc(doc);
setSelectedEvent(filteredEvents[selectedEventIndexInfo.index]);
setSelectedEvent(events[selectedEventIndexInfo.index]);
}, [selectedEventIndexInfo]);

if (!currentDocKey) {
Expand Down Expand Up @@ -137,9 +116,6 @@ const Panel = () => {
selectedEvent={selectedEvent}
selectedEventIndexInfo={selectedEventIndexInfo}
setSelectedEventIndexInfo={setSelectedEventIndexInfo}
hidePresenceEvent={hidePresenceEvent}
setHidePresenceEvent={setHidePresenceEvent}
events={filteredEvents}
/>

<Separator
Expand Down
36 changes: 9 additions & 27 deletions tools/devtools/src/devtools/tabs/History.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ import { DocEventType, Change, type TransactionEvent } from 'yorkie-js-sdk';
import Slider from 'rc-slider';
import { JSONView } from '../components/JsonView';
import { CursorIcon, DocumentIcon } from '../icons';
import {
TransactionEventType,
getTransactionEventType,
useTransactionEvents,
} from '../contexts/YorkieSource';

const SLIDER_MARK_WIDTH = 24;

Expand Down Expand Up @@ -57,40 +62,17 @@ const getEventInfo = (event: TransactionEvent) => {
return info;
};

export enum TransactionEventType {
Document = 'document',
Presence = 'presence',
}

export const getTransactionEventType = (
event: TransactionEvent,
): TransactionEventType => {
for (const docEvent of event) {
if (
docEvent.type === DocEventType.StatusChanged ||
docEvent.type === DocEventType.Snapshot ||
docEvent.type === DocEventType.LocalChange ||
docEvent.type === DocEventType.RemoteChange
) {
return TransactionEventType.Document;
}
}

return TransactionEventType.Presence;
};

export function History({
style,
selectedEvent,
selectedEventIndexInfo,
setSelectedEventIndexInfo,
hidePresenceEvent,
setHidePresenceEvent,
events,
}) {
const [openHistory, setOpenHistory] = useState(false);
const [sliderMarks, setSliderMarks] = useState({});
const scrollRef = useRef(null);
const { events, hidePresenceEvents, setHidePresenceEvents } =
useTransactionEvents();

const handleSliderEvent = (value) => {
setSelectedEventIndexInfo({
Expand All @@ -104,7 +86,7 @@ export function History({
index: null,
isLast: true,
});
setHidePresenceEvent((prev: boolean) => !prev);
setHidePresenceEvents((prev: boolean) => !prev);
};

useEffect(() => {
Expand Down Expand Up @@ -210,7 +192,7 @@ export function History({
</button>
<button onClick={toggleHidePresenceEvent}>
{hidePresenceEvent ? '¥' : 'Y'}
{hidePresenceEvents ? '¥' : 'Y'}
</button>
</span>
</span>
Expand Down

0 comments on commit 437fae5

Please sign in to comment.