refine: feedback and stage actions via right-click menu only
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -508,54 +508,25 @@ function DetailView({ task }: { task: TaskWithRelations }) {
|
|||||||
+
|
+
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div className="flex min-h-0 flex-1 flex-col overflow-y-auto pr-1">
|
||||||
className="flex min-h-0 flex-1 flex-col overflow-y-auto pr-1"
|
|
||||||
onContextMenu={(e) => {
|
|
||||||
if (!selectedId) return;
|
|
||||||
e.preventDefault();
|
|
||||||
setFeedbackCtx({ x: e.clientX, y: e.clientY });
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{sortedFeedbacks.length === 0 ? (
|
{sortedFeedbacks.length === 0 ? (
|
||||||
<p className="text-lg text-slate-400">+ 버튼 또는 빈 곳 우클릭으로 피드백을 추가하세요.</p>
|
<p className="text-lg text-slate-400">+ 버튼으로 피드백을 추가하세요.</p>
|
||||||
) : (
|
) : (
|
||||||
<div className="mb-2 min-h-0 flex-1 space-y-2">
|
<div className="mb-2 min-h-0 flex-1 space-y-2">
|
||||||
{sortedFeedbacks.map((f) => (
|
{sortedFeedbacks.map((f) => (
|
||||||
<div
|
<div
|
||||||
key={f.id}
|
key={f.id}
|
||||||
className="flex items-start justify-between gap-2 rounded-lg bg-slate-50 px-3 py-2"
|
className="rounded-lg bg-slate-50 px-3 py-2"
|
||||||
onContextMenu={(e) => {
|
onContextMenu={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
setFeedbackCtx({ x: e.clientX, y: e.clientY, detailId: f.id });
|
setFeedbackCtx({ x: e.clientX, y: e.clientY, detailId: f.id });
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<p className="min-w-0 flex-1 truncate text-2xl font-black leading-snug text-slate-700">
|
<p className="truncate text-2xl font-black leading-snug text-slate-700">
|
||||||
{f.content}
|
{f.content}
|
||||||
<span className="font-bold text-slate-400"> — {feedbackAuthorName(f)}</span>
|
<span className="font-bold text-slate-400"> — {feedbackAuthorName(f)}</span>
|
||||||
</p>
|
</p>
|
||||||
<div className="flex shrink-0 items-center gap-1 pt-0.5">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
title="피드백 수정"
|
|
||||||
onClick={() => setFeedbackModal({ mode: 'edit', detail: f })}
|
|
||||||
className="rounded px-2 py-0.5 text-xs font-bold text-slate-500 hover:bg-slate-100"
|
|
||||||
>
|
|
||||||
✏️
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
title="피드백 삭제"
|
|
||||||
onClick={() => {
|
|
||||||
if (window.confirm('이 피드백을 삭제하시겠습니까?')) {
|
|
||||||
deleteFeedback.mutate(f.id);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
className="rounded px-2 py-0.5 text-xs font-bold text-red-400 hover:bg-red-50 hover:text-red-600"
|
|
||||||
>
|
|
||||||
🗑
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@@ -659,7 +630,7 @@ function DetailView({ task }: { task: TaskWithRelations }) {
|
|||||||
onClose={() => setCtxMenu(null)}
|
onClose={() => setCtxMenu(null)}
|
||||||
items={[
|
items={[
|
||||||
{
|
{
|
||||||
label: '단계 수정',
|
label: '수정',
|
||||||
icon: '✏️',
|
icon: '✏️',
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
const ms = milestones.find((m) => m.id === ctxMenu.stageId);
|
const ms = milestones.find((m) => m.id === ctxMenu.stageId);
|
||||||
@@ -667,7 +638,7 @@ function DetailView({ task }: { task: TaskWithRelations }) {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: '단계 삭제',
|
label: '삭제',
|
||||||
icon: '🗑',
|
icon: '🗑',
|
||||||
danger: true,
|
danger: true,
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
@@ -696,41 +667,31 @@ function DetailView({ task }: { task: TaskWithRelations }) {
|
|||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{feedbackCtx && (
|
{feedbackCtx?.detailId && (
|
||||||
<ContextMenu
|
<ContextMenu
|
||||||
x={feedbackCtx.x}
|
x={feedbackCtx.x}
|
||||||
y={feedbackCtx.y}
|
y={feedbackCtx.y}
|
||||||
onClose={() => setFeedbackCtx(null)}
|
onClose={() => setFeedbackCtx(null)}
|
||||||
items={
|
items={[
|
||||||
feedbackCtx.detailId
|
{
|
||||||
? [
|
label: '수정',
|
||||||
{
|
icon: '✏️',
|
||||||
label: '피드백 수정',
|
onClick: () => {
|
||||||
icon: '✏️',
|
const d = details.find((item) => item.id === feedbackCtx.detailId);
|
||||||
onClick: () => {
|
if (d) setFeedbackModal({ mode: 'edit', detail: d });
|
||||||
const d = details.find((item) => item.id === feedbackCtx.detailId);
|
},
|
||||||
if (d) setFeedbackModal({ mode: 'edit', detail: d });
|
},
|
||||||
},
|
{
|
||||||
},
|
label: '삭제',
|
||||||
{
|
icon: '🗑',
|
||||||
label: '피드백 삭제',
|
danger: true,
|
||||||
icon: '🗑',
|
onClick: () => {
|
||||||
danger: true,
|
if (window.confirm('이 피드백을 삭제하시겠습니까?')) {
|
||||||
onClick: () => {
|
deleteFeedback.mutate(feedbackCtx.detailId!);
|
||||||
if (window.confirm('이 피드백을 삭제하시겠습니까?')) {
|
}
|
||||||
deleteFeedback.mutate(feedbackCtx.detailId!);
|
},
|
||||||
}
|
},
|
||||||
},
|
]}
|
||||||
},
|
|
||||||
]
|
|
||||||
: [
|
|
||||||
{
|
|
||||||
label: '피드백 추가',
|
|
||||||
icon: '➕',
|
|
||||||
onClick: () => setFeedbackModal({ mode: 'add' }),
|
|
||||||
},
|
|
||||||
]
|
|
||||||
}
|
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user