Refactor to function component

This commit is contained in:
Nathan Bierema 2023-08-07 10:30:21 -04:00
parent c3e7e8cf56
commit 5cb48ed15a

View File

@ -1,6 +1,4 @@
import React, { PureComponent, RefCallback } from 'react'; import React, { useCallback, useLayoutEffect, useRef } from 'react';
import { Drake } from 'dragula';
import dragula from 'react-dragula';
import { Action } from 'redux'; import { Action } from 'redux';
import { PerformAction } from '@redux-devtools/core'; import { PerformAction } from '@redux-devtools/core';
import { StylingFunction } from 'react-base16-styling'; import { StylingFunction } from 'react-base16-styling';
@ -44,152 +42,114 @@ interface Props<A extends Action<unknown>> {
lastActionId: number; lastActionId: number;
} }
export default class ActionList< function scrollToBottom(node: HTMLDivElement) {
A extends Action<unknown>, node.scrollTop = node.scrollHeight;
> extends PureComponent<Props<A>> { }
node?: HTMLDivElement | null;
scrollDown?: boolean; export default function ActionListFunction<A extends Action<unknown>>({
drake?: Drake; styling,
actions,
UNSAFE_componentWillReceiveProps(nextProps: Props<A>) { actionIds,
const node = this.node; isWideLayout,
if (!node) { onToggleAction,
this.scrollDown = true; skippedActionIds,
} else if (this.props.lastActionId !== nextProps.lastActionId) { selectedActionId,
const { scrollTop, offsetHeight, scrollHeight } = node; startActionId,
this.scrollDown = onSelect,
Math.abs(scrollHeight - (scrollTop + offsetHeight)) < 50; onSearch,
} else { searchValue,
this.scrollDown = false; currentActionId,
} hideMainButtons,
} hideActionButtons,
onCommit,
componentDidMount() { onSweep,
this.scrollDown = true; onJumpToState,
this.scrollToBottom(); lastActionId,
}: Props<A>) {
if (!this.props.draggableActions) return; const nodeRef = useRef<HTMLDivElement | null>(null);
const container = this.node!; const prevLastActionId = useRef<number | undefined>();
this.drake = dragula([container], {
copy: false, useLayoutEffect(() => {
copySortSource: false, if (nodeRef.current && prevLastActionId.current !== lastActionId) {
mirrorContainer: container, const { scrollTop, offsetHeight, scrollHeight } = nodeRef.current;
accepts: (el, target, source, sibling) => if (Math.abs(scrollHeight - (scrollTop + offsetHeight)) < 50) {
!sibling || !!parseInt(sibling.getAttribute('data-id')!), scrollToBottom(nodeRef.current);
moves: (el, source, handle) => }
!!parseInt(el!.getAttribute('data-id')!) && }
handle!.className.indexOf('selectorButton') !== 0,
}).on('drop', (el, target, source, sibling) => { prevLastActionId.current = lastActionId;
let beforeActionId = this.props.actionIds.length; }, [lastActionId]);
if (sibling && sibling.className.indexOf('gu-mirror') === -1) {
beforeActionId = parseInt(sibling.getAttribute('data-id')!); const setNodeRef = useCallback((node: HTMLDivElement | null) => {
} if (node && !nodeRef.current) {
const actionId = parseInt(el.getAttribute('data-id')!); scrollToBottom(node);
this.props.onReorderAction(actionId, beforeActionId); }
});
} nodeRef.current = node;
}, []);
componentWillUnmount() {
if (this.drake) this.drake.destroy(); const lowerSearchValue = searchValue && searchValue.toLowerCase();
} const filteredActionIds = searchValue
? actionIds.filter(
componentDidUpdate() { (id) =>
this.scrollToBottom(); (actions[id].action.type as string)
} .toLowerCase()
.indexOf(lowerSearchValue as string) !== -1,
scrollToBottom() { )
if (this.scrollDown && this.node) { : actionIds;
this.node.scrollTop = this.node.scrollHeight;
} return (
} <div
key="actionList"
getRef: RefCallback<HTMLDivElement> = (node) => { data-testid="actionList"
this.node = node; {...styling(
}; ['actionList', isWideLayout && 'actionListWide'],
isWideLayout,
render() { )}
const { >
styling, <ActionListHeader
actions, styling={styling}
actionIds, onSearch={onSearch}
isWideLayout, onCommit={onCommit}
onToggleAction, onSweep={onSweep}
skippedActionIds, hideMainButtons={hideMainButtons}
selectedActionId, hasSkippedActions={skippedActionIds.length > 0}
startActionId, hasStagedActions={actionIds.length > 1}
onSelect, searchValue={searchValue}
onSearch, />
searchValue, <div
currentActionId, data-testid="actionListRows"
hideMainButtons, {...styling('actionListRows')}
hideActionButtons, ref={setNodeRef}
onCommit, >
onSweep, {filteredActionIds.map((actionId) => (
onJumpToState, <ActionListRow
} = this.props; key={actionId}
const lowerSearchValue = searchValue && searchValue.toLowerCase(); styling={styling}
const filteredActionIds = searchValue actionId={actionId}
? actionIds.filter( isInitAction={!actionId}
(id) => isSelected={
(actions[id].action.type as string) (startActionId !== null &&
.toLowerCase() actionId >= startActionId &&
.indexOf(lowerSearchValue as string) !== -1, actionId <= (selectedActionId as number)) ||
) actionId === selectedActionId
: actionIds; }
isInFuture={
return ( actionIds.indexOf(actionId) > actionIds.indexOf(currentActionId)
<div }
key="actionList" onSelect={(e: React.MouseEvent<HTMLDivElement>) =>
data-testid="actionList" onSelect(e, actionId)
{...styling( }
['actionList', isWideLayout && 'actionListWide'], timestamps={getTimestamps(actions, actionIds, actionId)}
isWideLayout, action={actions[actionId].action}
)} onToggleClick={() => onToggleAction(actionId)}
> onJumpClick={() => onJumpToState(actionId)}
<ActionListHeader onCommitClick={() => onCommit()}
styling={styling} hideActionButtons={hideActionButtons}
onSearch={onSearch} isSkipped={skippedActionIds.indexOf(actionId) !== -1}
onCommit={onCommit} />
onSweep={onSweep} ))}
hideMainButtons={hideMainButtons} </div>
hasSkippedActions={skippedActionIds.length > 0} </div>
hasStagedActions={actionIds.length > 1} );
searchValue={searchValue}
/>
<div
data-testid="actionListRows"
{...styling('actionListRows')}
ref={this.getRef}
>
{filteredActionIds.map((actionId) => (
<ActionListRow
key={actionId}
styling={styling}
actionId={actionId}
isInitAction={!actionId}
isSelected={
(startActionId !== null &&
actionId >= startActionId &&
actionId <= (selectedActionId as number)) ||
actionId === selectedActionId
}
isInFuture={
actionIds.indexOf(actionId) > actionIds.indexOf(currentActionId)
}
onSelect={(e: React.MouseEvent<HTMLDivElement>) =>
onSelect(e, actionId)
}
timestamps={getTimestamps(actions, actionIds, actionId)}
action={actions[actionId].action}
onToggleClick={() => onToggleAction(actionId)}
onJumpClick={() => onJumpToState(actionId)}
onCommitClick={() => onCommit()}
hideActionButtons={hideActionButtons}
isSkipped={skippedActionIds.indexOf(actionId) !== -1}
/>
))}
</div>
</div>
);
}
} }