style(FN-698): audit and clean up dashboard styles and engine code

- Systematic component review of Header, PrSection, TaskComments, and MergeDetails
- Design token audit replacing hardcoded colors/spacing with CSS variables
- Inline style audit migrating inline styles to stylesheet classes
- Remove dead code: rate-limit-retry module and unused test files
- Consolidate and reorganize styles.css with improved token usage
This commit is contained in:
gsxdsm
2026-04-02 14:04:46 -07:00
parent 974ffc2ef6
commit 98dd0fad01
5 changed files with 714 additions and 542 deletions

View File

@@ -19,7 +19,7 @@ export function MergeDetails({ task }: MergeDetailsProps) {
return (
<div className="detail-section">
<h4>Merge Details</h4>
<div className="pr-card" style={{ border: "1px solid var(--border, #333)", borderRadius: 8, padding: 12 }}>
<div className="pr-card merge-details-card">
<div className="detail-log-entry">
<div className="detail-log-header">
<span className="detail-log-action">Status</span>

View File

@@ -275,6 +275,7 @@ export function ModelSelectorTab({ task, addToast }: ModelSelectorTabProps) {
.catch((err) => setModelsError(err.message))
.finally(() => setModelsLoading(false));
}}
className="btn btn-sm"
style={{ marginLeft: "8px" }}
>
Retry

View File

@@ -79,10 +79,10 @@ export function PrSection({
return (
<div className="pr-section">
<h4>
<GitPullRequest size={16} style={{ verticalAlign: "middle", marginRight: 8 }} />
<GitPullRequest size={16} className="pr-section-icon" />
Pull Request
</h4>
<div className="pr-hint" style={{ opacity: 0.8, fontSize: 13 }}>
<div className="pr-hint pr-hint--muted">
kb is creating a pull request automatically for this task.
</div>
</div>
@@ -93,7 +93,7 @@ export function PrSection({
return (
<div className="pr-section">
<h4>
<GitPullRequest size={16} style={{ verticalAlign: "middle", marginRight: 8 }} />
<GitPullRequest size={16} className="pr-section-icon" />
Create Pull Request
</h4>
<div className="pr-form">
@@ -137,7 +137,7 @@ export function PrSection({
return (
<div className="pr-section">
<h4>
<GitPullRequest size={16} style={{ verticalAlign: "middle", marginRight: 8 }} />
<GitPullRequest size={16} className="pr-section-icon" />
Pull Request
</h4>
<button
@@ -146,11 +146,11 @@ export function PrSection({
disabled={!hasGitHubToken}
title={hasGitHubToken ? "Create a PR for this task" : "GitHub token not configured"}
>
<Plus size={14} style={{ verticalAlign: "middle", marginRight: 4 }} />
<Plus size={14} className="pr-section-icon--sm" />
Create PR
</button>
{!hasGitHubToken && (
<div className="pr-hint" style={{ marginTop: 8, opacity: 0.7, fontSize: 12 }}>
<div className="pr-hint pr-hint--subtle">
Set GITHUB_TOKEN env var to enable PR creation
</div>
)}
@@ -165,76 +165,58 @@ export function PrSection({
return (
<div className="pr-section">
<h4>
<GitPullRequest size={16} style={{ verticalAlign: "middle", marginRight: 8 }} />
<GitPullRequest size={16} className="pr-section-icon" />
Pull Request
</h4>
<div
className="pr-card"
style={{
border: "1px solid var(--border, #333)",
borderRadius: 8,
padding: 12,
background: statusStyle.bg,
}}
className="pr-card pr-card--status"
style={{ background: statusStyle.bg }}
>
<div className="pr-header" style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 8 }}>
<span style={{ fontSize: 16 }}>{statusStyle.icon}</span>
<div className="pr-header">
<span className="pr-status-icon">{statusStyle.icon}</span>
<span
className="pr-status-badge"
style={{
background: statusStyle.bg,
color: statusStyle.text,
padding: "2px 8px",
borderRadius: 12,
fontSize: 12,
fontWeight: 500,
textTransform: "capitalize",
}}
style={{ background: statusStyle.bg, color: statusStyle.text }}
>
{prInfo.status}
</span>
<span className="pr-number" style={{ fontSize: 14, opacity: 0.8 }}>
#{prInfo.number}
</span>
<div style={{ flex: 1 }} />
<span className="pr-number">#{prInfo.number}</span>
<div className="pr-spacer" />
<button
className="btn btn-sm"
className="btn btn-sm pr-refresh-btn"
onClick={handleRefresh}
disabled={isRefreshing}
title="Refresh PR status"
style={{ padding: "4px 8px" }}
>
<RefreshCw size={14} style={{ verticalAlign: "middle", opacity: isRefreshing ? 0.5 : 1 }} />
</button>
</div>
<div className="pr-title" style={{ fontWeight: 500, marginBottom: 8 }}>
{prInfo.title}
</div>
<div className="pr-meta" style={{ fontSize: 12, opacity: 0.7, marginBottom: 8 }}>
<div className="pr-title">{prInfo.title}</div>
<div className="pr-meta">
<span>{prInfo.headBranch}</span>
<span style={{ margin: "0 8px" }}></span>
<span className="pr-meta-arrow"></span>
<span>{prInfo.baseBranch}</span>
</div>
{automationStatus === "merging-pr" && (
<div className="pr-hint" style={{ marginBottom: 8, fontSize: 12 }}>
<div className="pr-hint pr-hint--info">
kb is merging this pull request automatically.
</div>
)}
{automationStatus === "awaiting-pr-checks" && (
<div className="pr-hint" style={{ marginBottom: 8, fontSize: 12 }}>
<div className="pr-hint pr-hint--info">
{blockingReasons.length > 0
? `Waiting for: ${blockingReasons.join("; ")}`
: "Waiting for required checks or review feedback before auto-merge."}
</div>
)}
{prInfo.status === "merged" && (
<div className="pr-hint" style={{ marginBottom: 8, fontSize: 12 }}>
<div className="pr-hint pr-hint--info">
This PR is merged. kb will finish local cleanup and move the task to Done.
</div>
)}
<div className="pr-footer" style={{ display: "flex", alignItems: "center", gap: 12 }}>
<div className="pr-footer">
{prInfo.commentCount > 0 && (
<span className="pr-comments" style={{ display: "flex", alignItems: "center", gap: 4 }}>
<span className="pr-comments">
<MessageSquare size={14} />
{prInfo.commentCount}
</span>
@@ -244,14 +226,6 @@ export function PrSection({
target="_blank"
rel="noopener noreferrer"
className="pr-link"
style={{
display: "flex",
alignItems: "center",
gap: 4,
color: "var(--link, #58a6ff)",
textDecoration: "none",
fontSize: 12,
}}
>
<ExternalLink size={14} />
View on GitHub

View File

@@ -117,19 +117,19 @@ export function TaskComments({ task, onTaskUpdated, addToast, currentAuthor = "u
const isAIGuidance = isAIGuidanceComment(comment.author);
return (
<div key={comment.id} className="detail-log-entry">
<div className="detail-log-header" style={{ justifyContent: "space-between", gap: 12 }}>
<div style={{ display: "flex", alignItems: "center", gap: 8 }}>
<div className="detail-log-header comments-header-row">
<div className="comments-author-row">
{isAIGuidance ? (
<span className="ai-guidance-badge" data-testid="ai-guidance-badge">AI Guidance</span>
) : (
<strong>{comment.author}</strong>
)}
<span className="detail-log-timestamp" style={{ marginLeft: isAIGuidance ? 0 : 8 }}>
<span className="detail-log-timestamp">
{formatCommentTimestamp(comment)}
</span>
</div>
{canEdit && !isEditing ? (
<div style={{ display: "flex", gap: 8 }}>
<div className="comments-actions-row">
<button className="btn btn-sm" onClick={() => {
setEditingId(comment.id);
setEditingText(comment.text);
@@ -147,14 +147,14 @@ export function TaskComments({ task, onTaskUpdated, addToast, currentAuthor = "u
) : null}
</div>
{isEditing ? (
<div style={{ display: "grid", gap: 8, marginTop: 8 }}>
<div className="comments-edit-form">
<textarea
value={editingText}
onChange={(event) => setEditingText(event.target.value)}
rows={3}
className="spec-editor-feedback"
/>
<div style={{ display: "flex", gap: 8, justifyContent: "flex-end" }}>
<div className="comments-edit-actions">
<button
className="btn btn-sm"
onClick={() => {
@@ -175,7 +175,7 @@ export function TaskComments({ task, onTaskUpdated, addToast, currentAuthor = "u
</div>
</div>
) : (
<div className="detail-log-outcome" style={{ whiteSpace: "pre-wrap" }}>
<div className="detail-log-outcome comments-outcome-text">
{comment.text}
</div>
)}
@@ -185,8 +185,8 @@ export function TaskComments({ task, onTaskUpdated, addToast, currentAuthor = "u
</div>
)}
<div style={{ display: "grid", gap: 8, marginTop: 12 }}>
<div style={{ display: "flex", gap: 8 }}>
<div className="comments-compose-form">
<div className="comments-type-toggle">
<button
className={`btn btn-sm ${commentType === "comment" ? "btn-primary" : ""}`}
onClick={() => setCommentType("comment")}
@@ -201,7 +201,7 @@ export function TaskComments({ task, onTaskUpdated, addToast, currentAuthor = "u
</button>
</div>
{commentType === "guidance" && (
<div style={{ fontSize: "0.875rem", color: "var(--color-text-muted, #666)" }}>
<div className="comments-guidance-hint">
AI Guidance comments are injected into the task execution context
</div>
)}
@@ -213,8 +213,8 @@ export function TaskComments({ task, onTaskUpdated, addToast, currentAuthor = "u
placeholder={placeholder}
className="spec-editor-feedback"
/>
<div style={{ display: "flex", justifyContent: "space-between", alignItems: "center" }}>
<span style={{ fontSize: "0.75rem", color: isOverLimit ? "var(--color-danger, red)" : undefined }}>
<div className="comments-footer-row">
<span className={`comments-char-count${isOverLimit ? " comments-char-count--over" : ""}`}>
{draft.length} / {MAX_COMMENT_LENGTH}
</span>
<button

File diff suppressed because it is too large Load Diff