Skip to content

Commit afc872c

Browse files
authored
Merge pull request #1009 from nxnaxx/fix/#981_commit-display
fix(view): Detail, Cluster Graph Tooltip 커밋 메시지 표시 오류 수정
2 parents 453d8d8 + c27db54 commit afc872c

File tree

5 files changed

+162
-136
lines changed

5 files changed

+162
-136
lines changed

packages/view/src/components/Detail/Detail.scss

Lines changed: 18 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,11 @@
8181
margin-left: 0.125rem;
8282
min-width: 0;
8383
padding-top: 0.3rem;
84-
padding-right: 3.125rem;
84+
padding-right: 0.25rem;
8585

8686
.commit-message {
8787
position: relative;
88+
width: 100%;
8889

8990
.commit-message__header {
9091
display: flex;
@@ -150,28 +151,26 @@
150151
}
151152
}
152153

153-
.commit-message__body {
154-
max-height: 0;
155-
overflow: hidden;
156-
opacity: 0;
154+
%commit-message__body-base {
157155
background: rgba(0, 0, 0, 0.02);
158-
border: 1px solid var(--color-border);
159-
border-radius: 0.375rem;
160-
padding: 0;
156+
color: var(--color-text-secondary);
161157
font-size: 0.8125rem;
162158
line-height: 1.5;
163-
color: var(--color-text-secondary);
164159
transition: all 0.3s ease-in-out;
165160
white-space: pre-wrap;
166161
word-break: break-word;
167-
margin-top: 0;
168162
}
169163

170-
&:hover .commit-message__body {
171-
max-height: 200px;
164+
.commit-message__body {
165+
@extend %commit-message__body-base;
166+
opacity: 0;
167+
transform: translateY(-4px);
168+
}
169+
170+
.commit-message__body--visible {
171+
@extend %commit-message__body-base;
172172
opacity: 1;
173-
padding: 0.75rem;
174-
margin-top: 0.5rem;
173+
transform: translateY(0);
175174
}
176175
}
177176
}
@@ -214,7 +213,11 @@
214213
}
215214

216215
@keyframes bounce {
217-
0%, 20%, 50%, 80%, 100% {
216+
0%,
217+
20%,
218+
50%,
219+
80%,
220+
100% {
218221
transform: translateY(0);
219222
}
220223
40% {

packages/view/src/components/Detail/Detail.tsx

Lines changed: 62 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useCallback, useMemo } from "react";
1+
import React, { useCallback, useLayoutEffect, useMemo, useRef, useState } from "react";
22
import dayjs from "dayjs";
33
import {
44
AddCircleRounded,
@@ -14,7 +14,6 @@ import { List, AutoSizer, CellMeasurer } from "react-virtualized";
1414

1515
import { useGithubInfo, useDataStore } from "store";
1616
import { Author } from "components/Common/Author";
17-
import type { IssueLinkedMessage } from "components/Common/GithubIssueLink";
1817
import { renderIssueLinkedNodes } from "components/Common/GithubIssueLink";
1918

2019
import { getCommitListDetail } from "./Detail.util";
@@ -27,6 +26,10 @@ const Detail = ({ clusterId, authSrcMap }: DetailProps) => {
2726
const selectedData = useDataStore((state) => state.selectedData);
2827
const { owner, repo } = useGithubInfo();
2928

29+
const [hoverIndex, setHoverIndex] = useState<number | null>(null);
30+
const prevIndexRef = useRef<number | null>(null);
31+
const listRef = useRef<List>(null);
32+
3033
const commitNodeListInCluster = useMemo(
3134
() =>
3235
selectedData?.filter((selected) => selected.commitNodeList[0].clusterId === clusterId)[0].commitNodeList ?? [],
@@ -40,14 +43,35 @@ const Detail = ({ clusterId, authSrcMap }: DetailProps) => {
4043
const { cache, virtualizedItems, showScrollIndicator, handleRowsRendered } =
4144
useVirtualizedList(commitNodeListInCluster);
4245

46+
useLayoutEffect(() => {
47+
const [currentIndex, prevIndex] = [hoverIndex, prevIndexRef.current];
48+
const refreshRowHeight = (index: number) => {
49+
cache.clear(index, 0);
50+
listRef.current?.recomputeRowHeights(index);
51+
};
52+
53+
requestAnimationFrame(() => {
54+
if (prevIndex != null) refreshRowHeight(prevIndex);
55+
if (currentIndex != null) {
56+
refreshRowHeight(currentIndex);
57+
requestAnimationFrame(() => {
58+
listRef.current?.scrollToRow?.(currentIndex);
59+
});
60+
}
61+
prevIndexRef.current = currentIndex;
62+
});
63+
}, [hoverIndex, cache]);
64+
4365
const renderCommitItem = useCallback(
44-
(props: { index: number; key: string }) => {
45-
const { index, key } = props;
66+
(props: { index: number; key: string; expanded: boolean }) => {
67+
const { index, key, expanded } = props;
4668
const item = virtualizedItems[index];
69+
const showMessageBody = !(index === 1 && commitNodeListInCluster.length > 1);
4770

4871
if (item.type === "summary") {
4972
return <DetailSummary commitNodeListInCluster={item.data} />;
5073
}
74+
5175
return (
5276
<MemoizedCommitItem
5377
key={key}
@@ -56,7 +80,8 @@ const Detail = ({ clusterId, authSrcMap }: DetailProps) => {
5680
repo={repo}
5781
authSrcMap={authSrcMap}
5882
handleCommitIdCopy={handleCommitIdCopy}
59-
linkedMessage={issueLinkedMessage}
83+
showMessageBody={showMessageBody}
84+
expanded={expanded}
6085
/>
6186
);
6287
},
@@ -72,25 +97,18 @@ const Detail = ({ clusterId, authSrcMap }: DetailProps) => {
7297
columnIndex={0}
7398
rowIndex={index}
7499
>
75-
<div style={style}>{renderCommitItem({ index, key })}</div>
100+
<div
101+
style={style}
102+
onMouseEnter={() => setHoverIndex(index)}
103+
onMouseLeave={() => setHoverIndex(null)}
104+
>
105+
{renderCommitItem({ index, key, expanded: hoverIndex === index })}
106+
</div>
76107
</CellMeasurer>
77108
),
78-
[cache, renderCommitItem]
109+
[cache, renderCommitItem, hoverIndex]
79110
);
80111

81-
const issueLinkedMessage: IssueLinkedMessage = useMemo(() => {
82-
const message = commitNodeListInCluster?.[0]?.commit?.message;
83-
if (!message) return { title: [], body: null };
84-
85-
const [title, ...rest] = message.split("\n");
86-
const body = rest.filter((line) => line.trim()).join("\n");
87-
88-
return {
89-
title: renderIssueLinkedNodes(title, owner, repo),
90-
body: body ? renderIssueLinkedNodes(body, owner, repo) : null,
91-
};
92-
}, [commitNodeListInCluster, owner, repo]);
93-
94112
if (!selectedData || selectedData.length === 0) return null;
95113

96114
return (
@@ -99,6 +117,7 @@ const Detail = ({ clusterId, authSrcMap }: DetailProps) => {
99117
{({ height, width }) => {
100118
return (
101119
<List
120+
ref={listRef}
102121
height={height}
103122
width={width}
104123
rowCount={virtualizedItems.length}
@@ -107,6 +126,7 @@ const Detail = ({ clusterId, authSrcMap }: DetailProps) => {
107126
onRowsRendered={handleRowsRendered}
108127
className="detail__virtualized-list"
109128
estimatedRowSize={120}
129+
deferredMeasurementCache={cache}
110130
/>
111131
);
112132
}}
@@ -123,8 +143,25 @@ const Detail = ({ clusterId, authSrcMap }: DetailProps) => {
123143

124144
export default Detail;
125145

126-
function CommitItem({ commit, owner, repo, authSrcMap, handleCommitIdCopy, linkedMessage }: CommitItemProps) {
146+
function CommitItem({
147+
commit,
148+
owner,
149+
repo,
150+
authSrcMap,
151+
handleCommitIdCopy,
152+
showMessageBody,
153+
expanded,
154+
}: CommitItemProps) {
127155
const { id, message, author, commitDate } = commit;
156+
157+
const { issueLinkedTitle, body } = useMemo(() => {
158+
const [title, ...bodyLines] = message.split("\n");
159+
return {
160+
issueLinkedTitle: renderIssueLinkedNodes(title, owner, repo),
161+
body: bodyLines.filter(Boolean).join("\n"),
162+
};
163+
}, [message, owner, repo]);
164+
128165
return (
129166
<div className="detail__commit-item">
130167
<div className="commit-item__detail">
@@ -137,13 +174,7 @@ function CommitItem({ commit, owner, repo, authSrcMap, handleCommitIdCopy, linke
137174
src={authSrcMap[author.names.toString()]}
138175
/>
139176
)}
140-
<div className="commit-message__title">
141-
{(() => {
142-
const messageLines = message.split("\n");
143-
const title = messageLines[0];
144-
return linkedMessage.title.length > 0 ? linkedMessage.title : title;
145-
})()}
146-
</div>
177+
<div className="commit-message__title">{issueLinkedTitle}</div>
147178
<div className="commit-item__meta">
148179
<span className="commit-item__author-name">{author.names[0]}</span>
149180
<span className="commit-item__date">{dayjs(commitDate).format("YY. M. DD. a h:mm")}</span>
@@ -167,17 +198,9 @@ function CommitItem({ commit, owner, repo, authSrcMap, handleCommitIdCopy, linke
167198
</div>
168199
</div>
169200
</div>
170-
{(() => {
171-
const messageLines = message.split("\n");
172-
const body = messageLines
173-
.slice(1)
174-
.filter((line: string) => line.trim())
175-
.join("\n");
176-
177-
return body ? (
178-
<div className="commit-message__body">{linkedMessage.body ? linkedMessage.body : body}</div>
179-
) : null;
180-
})()}
201+
{showMessageBody && body && (
202+
<div className={`commit-message__body${expanded ? "--visible" : ""}`}>{expanded ? body : null}</div>
203+
)}
181204
</div>
182205
</div>
183206
</div>

packages/view/src/components/Detail/Detail.type.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import type { ReactNode } from "react";
33
import type { ClusterNode } from "types";
44
import type { Commit } from "types/Commit";
55
import type { AuthSrcMap } from "components/VerticalClusterList/Summary/Summary.type";
6-
import type { IssueLinkedMessage } from "components/Common/GithubIssueLink";
76

87
export type DetailProps = {
98
clusterId: number;
@@ -25,7 +24,8 @@ export interface CommitItemProps {
2524
repo: string;
2625
authSrcMap: AuthSrcMap | null;
2726
handleCommitIdCopy: (id: string) => () => Promise<void>;
28-
linkedMessage: IssueLinkedMessage;
27+
showMessageBody: boolean;
28+
expanded: boolean;
2929
}
3030

3131
export type VirtualizedItem =

packages/view/src/components/VerticalClusterList/ClusterGraph/Draws/drawSubGraph.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const tooltip = d3
1313
.append("div")
1414
.attr("class", "cluster-graph__tooltip")
1515
.style("visibility", "hidden")
16+
.style("white-space", "pre-line")
1617
.text("Tooltip");
1718

1819
const calculateCirclePositions = (numOfCircles: number, startY: number, endY: number, gap: number) => {
@@ -60,13 +61,12 @@ export const drawSubGraph = (
6061
.on("mouseover", (_, { clusterData, circleIndex }) => {
6162
const { commitNodeList } = clusterData.cluster;
6263
const { message } = commitNodeList[circleIndex].commit;
63-
const messageLines = message.split("\n");
64-
const title = messageLines[0];
65-
const body = messageLines
66-
.slice(1)
67-
.filter((line) => line.trim())
68-
.join("\n");
69-
const tooltipText = body ? `${title}\n\n${body}` : title;
64+
65+
const [title, ...bodyLines] = message.split("\n");
66+
const body = bodyLines.filter(Boolean).join("\n");
67+
const showMessageBody = !(circleIndex === 0 && commitNodeList.length > 1) && !!body;
68+
const tooltipText = showMessageBody ? `${title}\n${body}` : title;
69+
7070
tooltip.text(tooltipText);
7171
return tooltip.style("visibility", "visible");
7272
})

0 commit comments

Comments
 (0)