From cbc78659b4186e75d0bdd3f6cad26e31f7ade5c1 Mon Sep 17 00:00:00 2001 From: Leander Rodrigues Date: Tue, 10 Dec 2024 16:24:15 -0500 Subject: [PATCH 1/5] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Convert=20MergedItem?= =?UTF-8?q?=20to=20FC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../issueDetails/groupMerged/mergedItem.tsx | 187 ++++++++---------- .../issueDetails/groupMerged/mergedList.tsx | 1 - 2 files changed, 86 insertions(+), 102 deletions(-) diff --git a/static/app/views/issueDetails/groupMerged/mergedItem.tsx b/static/app/views/issueDetails/groupMerged/mergedItem.tsx index 7b6a4f5a84329d..f36318daefff21 100644 --- a/static/app/views/issueDetails/groupMerged/mergedItem.tsx +++ b/static/app/views/issueDetails/groupMerged/mergedItem.tsx @@ -1,4 +1,4 @@ -import {Component} from 'react'; +import {useEffect, useState} from 'react'; import styled from '@emotion/styled'; import {Button} from 'sentry/components/button'; @@ -10,35 +10,24 @@ import {t} from 'sentry/locale'; import type {Fingerprint} from 'sentry/stores/groupingStore'; import GroupingStore from 'sentry/stores/groupingStore'; import {space} from 'sentry/styles/space'; -import type {Organization} from 'sentry/types/organization'; +import useOrganization from 'sentry/utils/useOrganization'; -type Props = { +interface Props { fingerprint: Fingerprint; - organization: Organization; totalFingerprint: number; -}; - -type State = { - busy: boolean; - checked: boolean; - collapsed: boolean; -}; - -class MergedItem extends Component { - state: State = { - collapsed: false, - checked: false, - busy: false, - }; +} - listener = GroupingStore.listen(data => this.onGroupChange(data), undefined); +export function MergedItem({fingerprint, totalFingerprint}: Props) { + const organization = useOrganization(); + const [busy, setBusy] = useState(false); + const [collapsed, setCollapsed] = useState(false); + const [checked, setChecked] = useState(false); - onGroupChange = ({unmergeState}) => { + function onGroupChange({unmergeState}) { if (!unmergeState) { return; } - const {fingerprint} = this.props; const stateForId = unmergeState.has(fingerprint.id) ? unmergeState.get(fingerprint.id) : undefined; @@ -48,42 +37,37 @@ class MergedItem extends Component { } Object.keys(stateForId).forEach(key => { - if (stateForId[key] === this.state[key]) { - return; + if (key === 'collapsed') { + setCollapsed(Boolean(stateForId[key])); + } else if (key === 'checked') { + setChecked(Boolean(stateForId[key])); + } else if (key === 'busy') { + setBusy(Boolean(stateForId[key])); } - - this.setState(prevState => ({...prevState, [key]: stateForId[key]})); }); - }; + } - handleToggleEvents = () => { - const {fingerprint} = this.props; + function handleToggleEvents() { GroupingStore.onToggleCollapseFingerprint(fingerprint.id); - }; - - // Disable default behavior of toggling checkbox - handleLabelClick(event: React.MouseEvent) { - event.preventDefault(); } - handleToggle = () => { - const {fingerprint} = this.props; + function handleToggle() { const {latestEvent} = fingerprint; - if (this.state.busy) { + if (busy) { return; } // clicking anywhere in the row will toggle the checkbox GroupingStore.onToggleUnmerge([fingerprint.id, latestEvent.id]); - }; + } - handleCheckClick() { + function handleCheckClick() { // noop because of react warning about being a controlled input without `onChange` // we handle change via row click } - renderFingerprint(id: string, label?: string) { + function renderFingerprint(id: string, label?: string) { if (!label) { return id; } @@ -95,69 +79,70 @@ class MergedItem extends Component { ); } - render() { - const {fingerprint, organization, totalFingerprint} = this.props; - const {latestEvent, id, label} = fingerprint; - const {collapsed, busy, checked} = this.state; - const checkboxDisabled = busy || totalFingerprint === 1; - - // `latestEvent` can be null if last event w/ fingerprint is not within retention period - return ( - - - - - - - - {this.renderFingerprint(id, label)} - - -