paperclip-github-plugin 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -65,7 +65,7 @@ The plugin does more than mirror issue text. It looks at linked pull requests, C
65
65
 
66
66
  ### Project pull request command center
67
67
 
68
- Each mapped project can expose a **Pull Requests** entry in the sidebar that opens a live GitHub queue page for that repository. The sidebar badge uses a lightweight total-count read, while the queue keeps the default view fast by loading only the current 10-row page, uses a repo-wide metrics read for the summary cards, reuses that cached metrics scan to keep filtered views fast by fetching only the visible filtered rows, keeps repo-scoped count, metrics, and per-PR review/check insight caches warm for repeat visits, lets operators explicitly bust those caches with Refresh when they want a live reread, shows total, mergeable, reviewable, and failing cards that filter the table, includes an **Up to date** column that distinguishes current branches, clean update candidates, conflict cases, and unknown freshness when GitHub cannot confirm the comparison, shows the PR target branch with a highlighted default-branch badge, keeps the list sorted by most recently updated first, paginates larger repositories, keeps a compact bottom detail pane with markdown-and-HTML-rendered conversation plus an inline comment composer, supports deterministic **Update branch** actions for clean behind-base pull requests, adds Copilot quick actions that post `@copilot` requests for **Fix CI**, **Rebase**, and **Address review feedback**, requests Copilot through GitHub’s native reviewer flow for **Review**, keeps the existing comment, review, re-run CI, merge, and close actions, hides any pull request action whose required GitHub permission is not verified for the saved token, and opens linked Paperclip issues in a plugin-provided right drawer so operators can stay on the queue page.
68
+ Each mapped project can expose a **Pull Requests** entry in the sidebar that opens a live GitHub queue page for that repository. The sidebar badge uses a lightweight total-count read, while the queue keeps the default view fast by loading only the current 10-row page, uses a repo-wide metrics read for the summary cards, reuses that cached metrics scan to keep filtered views fast by fetching only the visible filtered rows, keeps repo-scoped count, metrics, and per-PR review/check insight caches warm for repeat visits, lets operators explicitly bust those caches with Refresh when they want a live reread, shows total, mergeable, reviewable, and failing cards that filter the table, includes an **Up to date** column that distinguishes current branches, clean update candidates, conflict cases, and unknown freshness when GitHub cannot confirm the comparison, shows the PR target branch with a highlighted default-branch badge, keeps the list sorted by most recently updated first, paginates larger repositories, keeps a compact bottom detail pane with markdown-and-HTML-rendered conversation plus an inline comment composer, supports deterministic **Update branch** actions for clean behind-base pull requests, adds Copilot quick actions that post `@copilot` requests for **Fix CI**, **Rebase**, and **Address review feedback**, requests Copilot through GitHub’s native reviewer flow for **Review**, keeps comment, review, quick approve/request-changes, re-run CI, merge, and close actions available, lets the review modal submit comment-only, approve, or request-changes reviews, hides any pull request action whose required GitHub permission is not verified for the saved token, and opens linked Paperclip issues in a plugin-provided right drawer so operators can stay on the queue page.
69
69
 
70
70
  Paperclip issue linkage on the queue prefers the GitHub issue that the pull request closes, so imported GitHub issues and delivery work stay connected in the same project view. If a pull request has no closing-issue-backed link yet, the queue falls back to the Paperclip issue created directly from that pull request and updates the table immediately when that create action returns.
71
71
 
package/dist/manifest.js CHANGED
@@ -511,7 +511,7 @@ var require2 = createRequire(import.meta.url);
511
511
  var packageJson = require2("../package.json");
512
512
  var DASHBOARD_WIDGET_CAPABILITY = "ui.dashboardWidget.register";
513
513
  var SCHEDULE_TICK_CRON = "* * * * *";
514
- var MANIFEST_VERSION = "0.5.0"?.trim() || typeof packageJson.version === "string" && packageJson.version.trim() || process.env.npm_package_version?.trim() || "0.0.0-dev";
514
+ var MANIFEST_VERSION = "0.5.1"?.trim() || typeof packageJson.version === "string" && packageJson.version.trim() || process.env.npm_package_version?.trim() || "0.0.0-dev";
515
515
  var manifest = {
516
516
  id: "paperclip-github-plugin",
517
517
  apiVersion: 1,
package/dist/ui/index.js CHANGED
@@ -22817,6 +22817,14 @@ var HOST_DESTRUCTIVE_BUTTON_CLASSNAME = [
22817
22817
  "bg-destructive text-white hover:bg-destructive/90",
22818
22818
  "focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40"
22819
22819
  ].join(" ");
22820
+ var HOST_SUCCESS_BUTTON_CLASSNAME = [
22821
+ HOST_BUTTON_BASE_CLASSNAME,
22822
+ "ghsync__button-tone ghsync__button-tone--success"
22823
+ ].join(" ");
22824
+ var HOST_WARNING_BUTTON_CLASSNAME = [
22825
+ HOST_BUTTON_BASE_CLASSNAME,
22826
+ "ghsync__button-tone ghsync__button-tone--warning"
22827
+ ].join(" ");
22820
22828
  var HOST_TOOLBAR_BUTTON_SIZE_CLASSNAME = "px-3 has-[>svg]:px-2.5";
22821
22829
  var HOST_ACTION_BUTTON_SIZE_CLASSNAME = "h-9 px-4 py-2 has-[>svg]:px-3";
22822
22830
  var HOST_INLINE_BUTTON_SIZE_CLASSNAME = "h-8 px-3 has-[>svg]:px-2.5";
@@ -22845,7 +22853,7 @@ var PREVIEW_MARKDOWN_REHYPE_PLUGINS = [rehypeRaw, PREVIEW_MARKDOWN_SANITIZE_REHY
22845
22853
  function getPluginActionClassName(options) {
22846
22854
  const variant = options?.variant ?? "secondary";
22847
22855
  const size = options?.size ?? "default";
22848
- const variantClassName = variant === "primary" ? HOST_DEFAULT_BUTTON_CLASSNAME : variant === "danger" ? HOST_DESTRUCTIVE_BUTTON_CLASSNAME : HOST_OUTLINE_BUTTON_CLASSNAME;
22856
+ const variantClassName = variant === "primary" ? HOST_DEFAULT_BUTTON_CLASSNAME : variant === "success" ? HOST_SUCCESS_BUTTON_CLASSNAME : variant === "warning" ? HOST_WARNING_BUTTON_CLASSNAME : variant === "danger" ? HOST_DESTRUCTIVE_BUTTON_CLASSNAME : HOST_OUTLINE_BUTTON_CLASSNAME;
22849
22857
  const sizeClassName = size === "sm" ? HOST_INLINE_BUTTON_SIZE_CLASSNAME : HOST_ACTION_BUTTON_SIZE_CLASSNAME;
22850
22858
  return ["ghsync__button", variantClassName, sizeClassName, options?.extraClassName].filter(Boolean).join(" ");
22851
22859
  }
@@ -22882,6 +22890,7 @@ function GitHubButtonLabel(props) {
22882
22890
  ] });
22883
22891
  }
22884
22892
  var PROJECT_PULL_REQUESTS_PAGE_ROUTE_PATH = "github-pull-requests";
22893
+ var QUICK_REQUEST_CHANGES_REVIEW_SUMMARY = "Requested changes.";
22885
22894
  var LIGHT_PALETTE = {
22886
22895
  text: "#18181b",
22887
22896
  title: "#09090b",
@@ -23356,6 +23365,32 @@ var SHARED_LOADING_STYLES = `
23356
23365
  min-width: 0;
23357
23366
  }
23358
23367
 
23368
+ .ghsync__button-tone {
23369
+ border: 1px solid transparent;
23370
+ }
23371
+
23372
+ .ghsync__button-tone--success {
23373
+ border-color: var(--ghsync-success-border);
23374
+ background: var(--ghsync-success-bg);
23375
+ color: var(--ghsync-success-text);
23376
+ }
23377
+
23378
+ .ghsync__button-tone--success:hover {
23379
+ background: color-mix(in srgb, var(--ghsync-success-bg) 72%, var(--ghsync-success-border));
23380
+ color: var(--ghsync-success-text);
23381
+ }
23382
+
23383
+ .ghsync__button-tone--warning {
23384
+ border-color: var(--ghsync-warning-border);
23385
+ background: var(--ghsync-warning-bg);
23386
+ color: var(--ghsync-warning-text);
23387
+ }
23388
+
23389
+ .ghsync__button-tone--warning:hover {
23390
+ background: color-mix(in srgb, var(--ghsync-warning-bg) 72%, var(--ghsync-warning-border));
23391
+ color: var(--ghsync-warning-text);
23392
+ }
23393
+
23359
23394
  .ghsync__loading-inline {
23360
23395
  display: inline-flex;
23361
23396
  align-items: center;
@@ -25063,6 +25098,36 @@ var PROJECT_PULL_REQUESTS_PAGE_STYLES = `
25063
25098
  opacity: 0.42;
25064
25099
  }
25065
25100
 
25101
+ .ghsync-prs-table__icon-button--success {
25102
+ color: var(--ghsync-success-text);
25103
+ }
25104
+
25105
+ .ghsync-prs-table__icon-button--warning {
25106
+ color: var(--ghsync-warning-text);
25107
+ }
25108
+
25109
+ .ghsync-prs-table__icon-button--danger {
25110
+ color: var(--ghsync-danger-text);
25111
+ }
25112
+
25113
+ .ghsync-prs-table__icon-button--success:hover {
25114
+ color: var(--ghsync-success-text);
25115
+ border-color: var(--ghsync-success-border);
25116
+ background: color-mix(in srgb, var(--ghsync-success-bg) 68%, var(--ghsync-surfaceRaised));
25117
+ }
25118
+
25119
+ .ghsync-prs-table__icon-button--warning:hover {
25120
+ color: var(--ghsync-warning-text);
25121
+ border-color: var(--ghsync-warning-border);
25122
+ background: color-mix(in srgb, var(--ghsync-warning-bg) 68%, var(--ghsync-surfaceRaised));
25123
+ }
25124
+
25125
+ .ghsync-prs-table__icon-button--danger:hover {
25126
+ color: var(--ghsync-danger-text);
25127
+ border-color: var(--ghsync-danger-border);
25128
+ background: color-mix(in srgb, var(--ghsync-danger-bg) 68%, var(--ghsync-surfaceRaised));
25129
+ }
25130
+
25066
25131
  .ghsync-prs-table__status--passed {
25067
25132
  color: var(--ghsync-success-text);
25068
25133
  }
@@ -27560,6 +27625,16 @@ function getPreviewPullRequestCheckToneClass(status) {
27560
27625
  return "ghsync-prs-table__status--pending";
27561
27626
  }
27562
27627
  }
27628
+ function getPreviewPullRequestInlineActionToneClass(tone) {
27629
+ switch (tone) {
27630
+ case "success":
27631
+ return "ghsync-prs-table__icon-button--success";
27632
+ case "warning":
27633
+ return "ghsync-prs-table__icon-button--warning";
27634
+ default:
27635
+ return "ghsync-prs-table__icon-button--danger";
27636
+ }
27637
+ }
27563
27638
  function getPreviewPullRequestUpToDateMeta(status) {
27564
27639
  switch (status) {
27565
27640
  case "up_to_date":
@@ -29353,6 +29428,7 @@ function GitHubSyncProjectPullRequestsPage() {
29353
29428
  const issueModalPending = issueModalPullRequest ? pendingActionKey === `create-issue:${issueModalPullRequest.id}` : false;
29354
29429
  const commentModalPending = commentModalPullRequest ? pendingActionKey === `comment-modal:${commentModalPullRequest.id}` : false;
29355
29430
  const reviewModalApprovePending = reviewModalPullRequest ? pendingActionKey === `review:${reviewModalPullRequest.id}:approve` : false;
29431
+ const reviewModalCommentPending = reviewModalPullRequest ? pendingActionKey === `review:${reviewModalPullRequest.id}:comment` : false;
29356
29432
  const reviewModalRequestChangesPending = reviewModalPullRequest ? pendingActionKey === `review:${reviewModalPullRequest.id}:request_changes` : false;
29357
29433
  const reviewModalPending = reviewModalPullRequest ? Boolean(pendingActionKey?.startsWith(`review:${reviewModalPullRequest.id}:`)) : false;
29358
29434
  const rerunCiModalPending = rerunCiModalPullRequest ? pendingActionKey === `rerun-ci:${rerunCiModalPullRequest.id}` : false;
@@ -29515,6 +29591,10 @@ function GitHubSyncProjectPullRequestsPage() {
29515
29591
  setCommentModalPullRequestId(pullRequestId);
29516
29592
  setCommentModalDraft("");
29517
29593
  }
29594
+ function openReviewModal(pullRequestId) {
29595
+ setReviewModalPullRequestId(pullRequestId);
29596
+ setReviewModalDraft("");
29597
+ }
29518
29598
  function openClosePullRequestModal(pullRequest) {
29519
29599
  setCloseModalPullRequest(pullRequest);
29520
29600
  }
@@ -29801,23 +29881,42 @@ function GitHubSyncProjectPullRequestsPage() {
29801
29881
  setPendingActionKey((current) => current === actionKey ? null : current);
29802
29882
  }
29803
29883
  }
29804
- async function handleReviewPullRequest(review) {
29805
- if (!reviewModalPullRequest || !hostContext.companyId || !projectId) {
29884
+ function getSubmittedReviewToast(review, pullRequestNumber) {
29885
+ switch (review) {
29886
+ case "approved":
29887
+ return {
29888
+ title: `Approved #${pullRequestNumber}`,
29889
+ body: "GitHub review submitted."
29890
+ };
29891
+ case "changes_requested":
29892
+ return {
29893
+ title: `Requested changes on #${pullRequestNumber}`,
29894
+ body: "GitHub change request submitted."
29895
+ };
29896
+ default:
29897
+ return {
29898
+ title: `Commented on #${pullRequestNumber}`,
29899
+ body: "GitHub review comment submitted."
29900
+ };
29901
+ }
29902
+ }
29903
+ async function submitPullRequestReview(pullRequest, review, body, options) {
29904
+ if (!hostContext.companyId || !projectId) {
29806
29905
  return;
29807
29906
  }
29808
- const actionKey = `review:${reviewModalPullRequest.id}:${review}`;
29907
+ const actionKey = `review:${pullRequest.id}:${review}`;
29809
29908
  setPendingActionKey(actionKey);
29810
29909
  try {
29811
29910
  const result = await reviewPullRequest({
29812
29911
  companyId: hostContext.companyId,
29813
29912
  projectId,
29814
29913
  repositoryUrl: pageData.repositoryUrl,
29815
- pullRequestNumber: reviewModalPullRequest.number,
29914
+ pullRequestNumber: pullRequest.number,
29816
29915
  review,
29817
- body: reviewModalDraft.trim()
29916
+ body
29818
29917
  });
29819
29918
  const updatedAt = (/* @__PURE__ */ new Date()).toISOString();
29820
- patchPullRequestRow(reviewModalPullRequest.id, (current) => {
29919
+ patchPullRequestRow(pullRequest.id, (current) => {
29821
29920
  const nextReviewApprovals = current.reviewApprovals + (result.review === "approved" ? 1 : 0);
29822
29921
  const nextReviewChangesRequested = current.reviewChangesRequested + (result.review === "changes_requested" ? 1 : 0);
29823
29922
  const nextRecord = {
@@ -29832,13 +29931,16 @@ function GitHubSyncProjectPullRequestsPage() {
29832
29931
  mergeable: resolvePreviewPullRequestMergeable(nextRecord)
29833
29932
  };
29834
29933
  });
29835
- closeReviewModal();
29836
- refreshSelectedPullRequestDetails(reviewModalPullRequest.id);
29934
+ if (options?.closeModal) {
29935
+ closeReviewModal();
29936
+ }
29937
+ refreshSelectedPullRequestDetails(pullRequest.id);
29837
29938
  refreshPullRequestMetricsPanel();
29838
29939
  notifyGitHubSyncPullRequestsChanged();
29940
+ const submittedReviewToast = getSubmittedReviewToast(result.review, pullRequest.number);
29839
29941
  toast({
29840
- title: result.review === "approved" ? `Approved #${reviewModalPullRequest.number}` : `Requested changes on #${reviewModalPullRequest.number}`,
29841
- body: result.review === "approved" ? "GitHub review submitted." : "GitHub change request submitted.",
29942
+ title: submittedReviewToast.title,
29943
+ body: submittedReviewToast.body,
29842
29944
  tone: "success"
29843
29945
  });
29844
29946
  } catch (error) {
@@ -29851,6 +29953,19 @@ function GitHubSyncProjectPullRequestsPage() {
29851
29953
  setPendingActionKey((current) => current === actionKey ? null : current);
29852
29954
  }
29853
29955
  }
29956
+ async function handleReviewPullRequest(review) {
29957
+ if (!reviewModalPullRequest) {
29958
+ return;
29959
+ }
29960
+ await submitPullRequestReview(reviewModalPullRequest, review, reviewModalDraft.trim(), { closeModal: true });
29961
+ }
29962
+ async function handleQuickPullRequestReview(pullRequest, review) {
29963
+ await submitPullRequestReview(
29964
+ pullRequest,
29965
+ review,
29966
+ review === "request_changes" ? QUICK_REQUEST_CHANGES_REVIEW_SUMMARY : ""
29967
+ );
29968
+ }
29854
29969
  async function handleRerunCi() {
29855
29970
  if (!rerunCiModalPullRequest || !hostContext.companyId || !projectId) {
29856
29971
  return;
@@ -29908,7 +30023,7 @@ function GitHubSyncProjectPullRequestsPage() {
29908
30023
  /* @__PURE__ */ jsx2("th", { scope: "col", className: "ghsync-prs-table__cell--center", children: "Checks" }),
29909
30024
  /* @__PURE__ */ jsx2("th", { scope: "col", className: "ghsync-prs-table__cell--center", children: "Up to date" }),
29910
30025
  /* @__PURE__ */ jsx2("th", { scope: "col", className: "ghsync-prs-table__cell--center", children: "Target branch" }),
29911
- /* @__PURE__ */ jsx2("th", { scope: "col", className: "ghsync-prs-table__cell--center", children: "Reviews" }),
30026
+ /* @__PURE__ */ jsx2("th", { scope: "col", className: "ghsync-prs-table__cell--center", children: "Approvals" }),
29912
30027
  /* @__PURE__ */ jsx2("th", { scope: "col", className: "ghsync-prs-table__cell--center", children: "Review threads" }),
29913
30028
  /* @__PURE__ */ jsx2("th", { scope: "col", className: "ghsync-prs-table__cell--center", children: "Comments" }),
29914
30029
  /* @__PURE__ */ jsx2("th", { scope: "col", className: "ghsync-prs-table__cell--center", children: "Last updated" }),
@@ -30130,12 +30245,16 @@ function GitHubSyncProjectPullRequestsPage() {
30130
30245
  const mergeActionKey = `merge:${pullRequest.id}`;
30131
30246
  const commentModalActionKey = `comment-modal:${pullRequest.id}`;
30132
30247
  const reviewActionPrefix = `review:${pullRequest.id}:`;
30248
+ const reviewApproveActionKey = `review:${pullRequest.id}:approve`;
30249
+ const reviewRequestChangesActionKey = `review:${pullRequest.id}:request_changes`;
30133
30250
  const rerunCiActionKey = `rerun-ci:${pullRequest.id}`;
30134
30251
  const updateBranchActionKey = `update-branch:${pullRequest.id}`;
30135
30252
  const closeActionKey = `close:${pullRequest.id}`;
30136
30253
  const copilotPending = Boolean(pendingActionKey?.startsWith(copilotActionPrefix));
30137
30254
  const commentModalPending2 = pendingActionKey === commentModalActionKey;
30138
30255
  const reviewPending = Boolean(pendingActionKey?.startsWith(reviewActionPrefix));
30256
+ const reviewApprovePending = pendingActionKey === reviewApproveActionKey;
30257
+ const reviewRequestChangesPending = pendingActionKey === reviewRequestChangesActionKey;
30139
30258
  const rerunCiPending = pendingActionKey === rerunCiActionKey;
30140
30259
  const updateBranchPending = pendingActionKey === updateBranchActionKey;
30141
30260
  const mergePending = pendingActionKey === mergeActionKey;
@@ -30216,7 +30335,7 @@ function GitHubSyncProjectPullRequestsPage() {
30216
30335
  "button",
30217
30336
  {
30218
30337
  type: "button",
30219
- className: "ghsync-prs-table__icon-button",
30338
+ className: `ghsync-prs-table__icon-button ${getPreviewPullRequestInlineActionToneClass("warning")}`,
30220
30339
  title: `Re-run CI for #${pullRequest.number}`,
30221
30340
  onClick: () => setRerunCiPullRequestId(pullRequest.id),
30222
30341
  disabled: rerunCiPending,
@@ -30272,40 +30391,82 @@ function GitHubSyncProjectPullRequestsPage() {
30272
30391
  /* @__PURE__ */ jsx2("td", { className: "ghsync-prs-table__cell--center", children: /* @__PURE__ */ jsxs2("div", { className: "ghsync-prs-table__metric-group", children: [
30273
30392
  hasReviewSummary ? /* @__PURE__ */ jsxs2("a", { className: "ghsync-prs-table__metric-link", href: pullRequest.reviewsUrl, target: "_blank", rel: "noreferrer", children: [
30274
30393
  pullRequest.reviewApprovals > 0 ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
30275
- /* @__PURE__ */ jsx2(CheckPassedIcon, { className: "ghsync-prs-icon" }),
30394
+ /* @__PURE__ */ jsx2(CheckPassedIcon, { className: "ghsync-prs-icon ghsync-prs-table__status--passed" }),
30276
30395
  /* @__PURE__ */ jsx2("span", { children: pullRequest.reviewApprovals })
30277
30396
  ] }) : null,
30278
30397
  pullRequest.reviewChangesRequested > 0 ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
30279
- /* @__PURE__ */ jsx2(CheckFailedIcon, { className: "ghsync-prs-icon" }),
30398
+ /* @__PURE__ */ jsx2(CheckFailedIcon, { className: "ghsync-prs-icon ghsync-prs-table__status--failed" }),
30280
30399
  /* @__PURE__ */ jsx2("span", { children: pullRequest.reviewChangesRequested })
30281
30400
  ] }) : null
30282
30401
  ] }) : null,
30283
- pullRequest.reviewable && canReviewPullRequests ? /* @__PURE__ */ jsx2(
30284
- "button",
30285
- {
30286
- type: "button",
30287
- className: "ghsync-prs-table__icon-button",
30288
- title: `Review #${pullRequest.number}`,
30289
- onClick: () => {
30290
- setReviewModalPullRequestId(pullRequest.id);
30291
- setReviewModalDraft("");
30292
- },
30293
- disabled: reviewPending,
30294
- children: /* @__PURE__ */ jsx2(
30295
- LoadingIconButtonContent,
30296
- {
30297
- busy: reviewPending,
30298
- busyLabel: `Reviewing #${pullRequest.number}`,
30299
- icon: /* @__PURE__ */ jsx2(ReviewIcon, { className: "ghsync-prs-icon" })
30300
- }
30301
- )
30302
- }
30303
- ) : null
30402
+ pullRequest.reviewable && canReviewPullRequests ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
30403
+ /* @__PURE__ */ jsx2(
30404
+ "button",
30405
+ {
30406
+ type: "button",
30407
+ className: "ghsync-prs-table__icon-button",
30408
+ title: `Review #${pullRequest.number}`,
30409
+ "aria-label": `Review #${pullRequest.number}`,
30410
+ onClick: () => openReviewModal(pullRequest.id),
30411
+ disabled: reviewPending,
30412
+ children: /* @__PURE__ */ jsx2(
30413
+ LoadingIconButtonContent,
30414
+ {
30415
+ busy: false,
30416
+ busyLabel: `Reviewing #${pullRequest.number}`,
30417
+ icon: /* @__PURE__ */ jsx2(ReviewIcon, { className: "ghsync-prs-icon" })
30418
+ }
30419
+ )
30420
+ }
30421
+ ),
30422
+ /* @__PURE__ */ jsx2(
30423
+ "button",
30424
+ {
30425
+ type: "button",
30426
+ className: `ghsync-prs-table__icon-button ${getPreviewPullRequestInlineActionToneClass("success")}`,
30427
+ title: `Approve #${pullRequest.number}`,
30428
+ "aria-label": `Approve #${pullRequest.number}`,
30429
+ onClick: () => {
30430
+ void handleQuickPullRequestReview(pullRequest, "approve");
30431
+ },
30432
+ disabled: reviewPending,
30433
+ children: /* @__PURE__ */ jsx2(
30434
+ LoadingIconButtonContent,
30435
+ {
30436
+ busy: reviewApprovePending,
30437
+ busyLabel: `Approving #${pullRequest.number}`,
30438
+ icon: /* @__PURE__ */ jsx2(CheckPassedIcon, { className: "ghsync-prs-icon" })
30439
+ }
30440
+ )
30441
+ }
30442
+ ),
30443
+ /* @__PURE__ */ jsx2(
30444
+ "button",
30445
+ {
30446
+ type: "button",
30447
+ className: `ghsync-prs-table__icon-button ${getPreviewPullRequestInlineActionToneClass("danger")}`,
30448
+ title: `Request changes on #${pullRequest.number}`,
30449
+ "aria-label": `Request changes on #${pullRequest.number}`,
30450
+ onClick: () => {
30451
+ void handleQuickPullRequestReview(pullRequest, "request_changes");
30452
+ },
30453
+ disabled: reviewPending,
30454
+ children: /* @__PURE__ */ jsx2(
30455
+ LoadingIconButtonContent,
30456
+ {
30457
+ busy: reviewRequestChangesPending,
30458
+ busyLabel: `Requesting changes on #${pullRequest.number}`,
30459
+ icon: /* @__PURE__ */ jsx2(CheckFailedIcon, { className: "ghsync-prs-icon" })
30460
+ }
30461
+ )
30462
+ }
30463
+ )
30464
+ ] }) : null
30304
30465
  ] }) }),
30305
30466
  /* @__PURE__ */ jsx2("td", { className: "ghsync-prs-table__cell--center", children: pullRequest.unresolvedReviewThreads > 0 ? /* @__PURE__ */ jsxs2("a", { className: "ghsync-prs-table__metric-link", href: pullRequest.reviewThreadsUrl, target: "_blank", rel: "noreferrer", children: [
30306
30467
  /* @__PURE__ */ jsx2(CommentIcon, { className: "ghsync-prs-icon" }),
30307
30468
  /* @__PURE__ */ jsx2("span", { children: pullRequest.unresolvedReviewThreads })
30308
- ] }) : hasResolvedReviewThreads ? /* @__PURE__ */ jsx2("a", { className: "ghsync-prs-table__metric-link", href: pullRequest.reviewThreadsUrl, target: "_blank", rel: "noreferrer", children: /* @__PURE__ */ jsx2(CheckPassedIcon, { className: "ghsync-prs-icon" }) }) : null }),
30469
+ ] }) : hasResolvedReviewThreads ? /* @__PURE__ */ jsx2("a", { className: "ghsync-prs-table__metric-link", href: pullRequest.reviewThreadsUrl, target: "_blank", rel: "noreferrer", children: /* @__PURE__ */ jsx2(CheckPassedIcon, { className: "ghsync-prs-icon ghsync-prs-table__status--passed" }) }) : null }),
30309
30470
  /* @__PURE__ */ jsx2("td", { className: "ghsync-prs-table__cell--center", children: /* @__PURE__ */ jsxs2("div", { className: "ghsync-prs-table__metric-group", children: [
30310
30471
  /* @__PURE__ */ jsxs2("a", { className: "ghsync-prs-table__metric-link", href: pullRequest.commentsUrl, target: "_blank", rel: "noreferrer", children: [
30311
30472
  /* @__PURE__ */ jsx2(CommentIcon, { className: "ghsync-prs-icon" }),
@@ -30369,7 +30530,7 @@ function GitHubSyncProjectPullRequestsPage() {
30369
30530
  "button",
30370
30531
  {
30371
30532
  type: "button",
30372
- className: "ghsync-prs-table__icon-button",
30533
+ className: `ghsync-prs-table__icon-button ${getPreviewPullRequestInlineActionToneClass("success")}`,
30373
30534
  title: `Merge #${pullRequest.number}`,
30374
30535
  onClick: () => {
30375
30536
  void handleMergePullRequest(pullRequest);
@@ -30389,7 +30550,7 @@ function GitHubSyncProjectPullRequestsPage() {
30389
30550
  "button",
30390
30551
  {
30391
30552
  type: "button",
30392
- className: "ghsync-prs-table__icon-button",
30553
+ className: `ghsync-prs-table__icon-button ${getPreviewPullRequestInlineActionToneClass("danger")}`,
30393
30554
  title: `Close PR #${pullRequest.number}`,
30394
30555
  "aria-label": `Close PR #${pullRequest.number}`,
30395
30556
  onClick: () => {
@@ -30513,10 +30674,7 @@ function GitHubSyncProjectPullRequestsPage() {
30513
30674
  {
30514
30675
  type: "button",
30515
30676
  className: getPluginActionClassName({ variant: "secondary", size: "sm" }),
30516
- onClick: () => {
30517
- setReviewModalPullRequestId(selectedPullRequest.id);
30518
- setReviewModalDraft("");
30519
- },
30677
+ onClick: () => openReviewModal(selectedPullRequest.id),
30520
30678
  disabled: selectedPullRequestReviewPending,
30521
30679
  children: /* @__PURE__ */ jsx2(
30522
30680
  LoadingButtonContent,
@@ -30533,7 +30691,7 @@ function GitHubSyncProjectPullRequestsPage() {
30533
30691
  "button",
30534
30692
  {
30535
30693
  type: "button",
30536
- className: getPluginActionClassName({ variant: "secondary", size: "sm" }),
30694
+ className: getPluginActionClassName({ variant: "warning", size: "sm" }),
30537
30695
  onClick: () => setRerunCiPullRequestId(selectedPullRequest.id),
30538
30696
  disabled: selectedPullRequestRerunCiPending,
30539
30697
  children: /* @__PURE__ */ jsx2(
@@ -30571,7 +30729,7 @@ function GitHubSyncProjectPullRequestsPage() {
30571
30729
  "button",
30572
30730
  {
30573
30731
  type: "button",
30574
- className: getPluginActionClassName({ variant: "primary", size: "sm" }),
30732
+ className: getPluginActionClassName({ variant: "success", size: "sm" }),
30575
30733
  onClick: () => {
30576
30734
  void handleMergePullRequest(selectedPullRequest);
30577
30735
  },
@@ -31200,7 +31358,7 @@ function GitHubSyncProjectPullRequestsPage() {
31200
31358
  className: "ghsync-prs-modal__textarea",
31201
31359
  value: reviewModalDraft,
31202
31360
  onChange: (event) => setReviewModalDraft(event.currentTarget.value),
31203
- placeholder: "Optional comment"
31361
+ placeholder: "Required for Comment and Request changes. Optional for Approve."
31204
31362
  }
31205
31363
  )
31206
31364
  ] }),
@@ -31215,6 +31373,25 @@ function GitHubSyncProjectPullRequestsPage() {
31215
31373
  }
31216
31374
  ),
31217
31375
  /* @__PURE__ */ jsxs2("div", { className: "ghsync-prs-modal__split-actions", children: [
31376
+ /* @__PURE__ */ jsx2(
31377
+ "button",
31378
+ {
31379
+ type: "button",
31380
+ className: getPluginActionClassName({ variant: "secondary" }),
31381
+ onClick: () => {
31382
+ void handleReviewPullRequest("comment");
31383
+ },
31384
+ disabled: !reviewModalDraft.trim() || reviewModalPending,
31385
+ children: /* @__PURE__ */ jsx2(
31386
+ LoadingButtonContent,
31387
+ {
31388
+ busy: reviewModalCommentPending,
31389
+ label: "Comment",
31390
+ busyLabel: "Commenting\u2026"
31391
+ }
31392
+ )
31393
+ }
31394
+ ),
31218
31395
  /* @__PURE__ */ jsx2(
31219
31396
  "button",
31220
31397
  {
@@ -31223,7 +31400,7 @@ function GitHubSyncProjectPullRequestsPage() {
31223
31400
  onClick: () => {
31224
31401
  void handleReviewPullRequest("request_changes");
31225
31402
  },
31226
- disabled: reviewModalPending,
31403
+ disabled: !reviewModalDraft.trim() || reviewModalPending,
31227
31404
  children: /* @__PURE__ */ jsx2(
31228
31405
  LoadingButtonContent,
31229
31406
  {
@@ -31238,7 +31415,7 @@ function GitHubSyncProjectPullRequestsPage() {
31238
31415
  "button",
31239
31416
  {
31240
31417
  type: "button",
31241
- className: getPluginActionClassName({ variant: "primary" }),
31418
+ className: getPluginActionClassName({ variant: "success" }),
31242
31419
  onClick: () => {
31243
31420
  void handleReviewPullRequest("approve");
31244
31421
  },
@@ -31295,7 +31472,7 @@ function GitHubSyncProjectPullRequestsPage() {
31295
31472
  "button",
31296
31473
  {
31297
31474
  type: "button",
31298
- className: getPluginActionClassName({ variant: "primary" }),
31475
+ className: getPluginActionClassName({ variant: "warning" }),
31299
31476
  onClick: () => {
31300
31477
  void handleRerunCi();
31301
31478
  },