Skip to content

Commit e786fab

Browse files
committed
Resolve conflict.
1 parent 101ac7f commit e786fab

1 file changed

Lines changed: 32 additions & 51 deletions

File tree

  • com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat

com.microsoft.copilot.eclipse.ui/src/com/microsoft/copilot/eclipse/ui/chat/WarnWidget.java

Lines changed: 32 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
package com.microsoft.copilot.eclipse.ui.chat;
55

6-
import java.util.Locale;
6+
import java.util.List;
77

88
import org.eclipse.swt.SWT;
99
import org.eclipse.swt.custom.StyledText;
@@ -18,13 +18,15 @@
1818
import org.eclipse.ui.ISharedImages;
1919
import org.eclipse.ui.PlatformUI;
2020

21-
import com.microsoft.copilot.eclipse.ui.UiConstants;
22-
import com.microsoft.copilot.eclipse.ui.i18n.Messages;
21+
import com.microsoft.copilot.eclipse.core.lsp.protocol.quota.CopilotPlan;
22+
import com.microsoft.copilot.eclipse.ui.chat.QuotaActions.QuotaAction;
2323
import com.microsoft.copilot.eclipse.ui.swt.CssConstants;
2424
import com.microsoft.copilot.eclipse.ui.utils.UiUtils;
2525

2626
/**
27-
* Widget to display a message when the user has no quota.
27+
* Widget that displays a warning message under a chat turn, optionally followed by plan-driven action buttons sourced
28+
* from {@link QuotaActions#forPlan(CopilotPlan, boolean)}. Presentation-only: the caller decides the message and
29+
* whether to pass a plan.
2830
*/
2931
public class WarnWidget extends Composite {
3032
private int buttonLeftMargin;
@@ -33,28 +35,31 @@ public class WarnWidget extends Composite {
3335
* Create the composite.
3436
*
3537
* @param parent the parent composite
36-
* @param message the message to display
38+
* @param style the SWT style bits
39+
* @param message the message to display ({@code null} treated as empty)
40+
* @param userPlan the user's Copilot plan to render plan-driven action buttons, or {@code null} for no buttons
41+
* @param overageEnabled whether additional paid usage is already enabled for the user; switches the
42+
* "Enable Additional Usage" label to "Increase Budget"
3743
*/
38-
public WarnWidget(Composite parent, int style, String message, int code) {
44+
public WarnWidget(Composite parent, int style, String message, CopilotPlan userPlan, boolean overageEnabled) {
3945
super(parent, style | SWT.BORDER);
40-
setLayout(new GridLayout(1, true));
46+
GridLayout outerLayout = new GridLayout(1, true);
47+
outerLayout.verticalSpacing = 0;
48+
setLayout(outerLayout);
4149
setLayoutData(new GridData(SWT.FILL, SWT.NONE, true, false));
4250

4351
buildWarnLabelWithIcon(message);
4452

45-
// 402 = quota exceeded. The server bakes the recommended next steps into the message text itself
46-
// (see copilot-language-server-internal fetch.ts), so we drive button visibility off of message
47-
// content to keep parity with the IntelliJ UpgradeNotificationComponent#initTbb rendering. See:
48-
// https://github.com/microsoft/copilot-client/blob/77f8f28e1a1e2efb51b6f92649bd9d085b8b64f5/lib/src/conversation/fetchPostProcessor.ts#L232-L248
49-
if (code == 402) {
50-
buildActionButtonsFromMessage(message);
53+
if (userPlan != null) {
54+
buildActionButtons(userPlan, overageEnabled);
5155
}
5256
parent.layout();
5357
}
5458

5559
private void buildWarnLabelWithIcon(String message) {
5660
Composite composite = new Composite(this, SWT.NONE);
57-
composite.setLayout(new GridLayout(2, false));
61+
GridLayout warnLayout = new GridLayout(2, false);
62+
composite.setLayout(warnLayout);
5863
composite.setLayoutData(new GridData(SWT.LEFT, SWT.NONE, true, false));
5964

6065
Label iconLabel = new Label(composite, SWT.TOP);
@@ -63,7 +68,8 @@ private void buildWarnLabelWithIcon(String message) {
6368
GridData iconGd = new GridData(SWT.LEFT, SWT.TOP, false, false);
6469
iconGd.verticalIndent = 4;
6570
iconLabel.setLayoutData(iconGd);
66-
buttonLeftMargin = warnImage.getBounds().width + iconGd.verticalIndent;
71+
buttonLeftMargin = warnLayout.marginWidth + warnLayout.marginLeft + warnImage.getBounds().width
72+
+ warnLayout.horizontalSpacing;
6773

6874
ChatMarkupViewer textLabel = new ChatMarkupViewer(composite, SWT.LEFT | SWT.WRAP);
6975
StyledText styledText = textLabel.getTextWidget();
@@ -75,56 +81,31 @@ private void buildWarnLabelWithIcon(String message) {
7581
}
7682

7783
/**
78-
* Render action buttons based on phrases present in the 402 message body, mirroring the IntelliJ
79-
* {@code UpgradeNotificationComponent#initTbb} logic:
80-
* <ul>
81-
* <li>{@code "additional overage"} or {@code "additional usage"} &rarr; "Enable Additional Usage"
82-
* (manage-overage URL)</li>
83-
* <li>{@code "increase budget"} (when neither overage nor usage phrase is present) &rarr;
84-
* "Increase Budget" (manage-overage URL)</li>
85-
* <li>{@code "upgrade your plan"} or the legacy {@code "30-day free trial"} hint &rarr;
86-
* "Upgrade Plan" (upgrade-plan URL)</li>
87-
* </ul>
88-
*
89-
* <p>The overage button is shown as primary when present; the upgrade button is primary only when no
90-
* overage button is rendered, matching the IntelliJ button styling.
84+
* Render plan-driven action buttons for a quota-exceeded warning, kept in sync with the quota {@link StaticBanner}.
9185
*/
92-
private void buildActionButtonsFromMessage(String message) {
93-
if (message == null) {
94-
return;
95-
}
96-
String lower = message.toLowerCase(Locale.ROOT);
97-
boolean enableAdditionalUsage = lower.contains("additional overage") || lower.contains("additional usage");
98-
boolean increaseBudget = !enableAdditionalUsage && lower.contains("increase budget");
99-
boolean upgradePlan = lower.contains("upgrade your plan") || lower.contains("30-day free trial");
100-
if (!enableAdditionalUsage && !increaseBudget && !upgradePlan) {
86+
private void buildActionButtons(CopilotPlan userPlan, boolean overageEnabled) {
87+
List<QuotaAction> actions = QuotaActions.forPlan(userPlan, overageEnabled);
88+
if (actions.isEmpty()) {
10189
return;
10290
}
10391

104-
Composite composite = new Composite(this, SWT.NONE);
10592
RowLayout layout = new RowLayout(SWT.HORIZONTAL);
10693
layout.marginLeft = this.buttonLeftMargin; // Align with the message text
94+
layout.marginTop = 0;
10795
layout.spacing = 10;
96+
97+
Composite composite = new Composite(this, SWT.NONE);
10898
composite.setLayout(layout);
10999

110-
boolean overageButtonShown = enableAdditionalUsage || increaseBudget;
111-
if (enableAdditionalUsage) {
112-
addActionButton(composite, Messages.menu_quota_enableAdditionalUsage,
113-
UiConstants.MANAGE_COPILOT_OVERAGE_URL, true);
114-
} else if (increaseBudget) {
115-
addActionButton(composite, Messages.menu_quota_increaseBudget,
116-
UiConstants.MANAGE_COPILOT_OVERAGE_URL, true);
117-
}
118-
if (upgradePlan) {
119-
addActionButton(composite, Messages.menu_quota_upgradePlan,
120-
UiConstants.COPILOT_UPGRADE_PLAN_URL, !overageButtonShown);
100+
for (QuotaAction action : actions) {
101+
addButton(composite, action.label(), action.tooltip(), action.url(), action.primary());
121102
}
122103
}
123104

124-
private static void addActionButton(Composite parent, String label, String link, boolean primary) {
105+
private static void addButton(Composite parent, String label, String tooltip, String link, boolean primary) {
125106
Button button = new Button(parent, SWT.PUSH);
126107
button.setText(label);
127-
button.setToolTipText(label);
108+
button.setToolTipText(tooltip);
128109
button.addSelectionListener(new SelectionAdapter() {
129110
@Override
130111
public void widgetSelected(org.eclipse.swt.events.SelectionEvent event) {

0 commit comments

Comments
 (0)