added reset AI credentials btn

This commit is contained in:
Sohaib Baig
2025-08-12 14:50:24 +02:00
parent b63acc0046
commit 4c3d8b66e7
6 changed files with 83 additions and 27 deletions
@@ -17,11 +17,13 @@ import com.google.gwt.user.cellview.client.Column;
import com.google.gwt.user.client.rpc.AsyncCallback; import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button; import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.CaptionPanel; import com.google.gwt.user.client.ui.CaptionPanel;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.HorizontalPanel; import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.TextArea; import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.VerticalPanel; import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.sap.sailing.gwt.ui.adminconsole.places.AdminConsoleView.Presenter; import com.sap.sailing.gwt.ui.adminconsole.places.AdminConsoleView.Presenter;
import com.sap.sailing.gwt.ui.client.Displayer; import com.sap.sailing.gwt.ui.client.Displayer;
import com.sap.sailing.gwt.ui.client.SailingServiceWriteAsync; import com.sap.sailing.gwt.ui.client.SailingServiceWriteAsync;
@@ -43,8 +45,6 @@ public class AIAgentConfigurationPanel extends SimplePanel {
private final ErrorReporter errorReporter; private final ErrorReporter errorReporter;
private final TableWrapperWithMultiSelectionAndFilterForSecuredDTO<EventDTO, StringMessages, AdminConsoleTableResources> eventsTableWrapper; private final TableWrapperWithMultiSelectionAndFilterForSecuredDTO<EventDTO, StringMessages, AdminConsoleTableResources> eventsTableWrapper;
private final Set<EventDTO> selectedEvents; private final Set<EventDTO> selectedEvents;
private final Label hasCredentialsLabel;
private final CaptionPanel eventsCaptionPanel;
private boolean selectionUpdatedAfterEventsHaveLoaded; private boolean selectionUpdatedAfterEventsHaveLoaded;
private boolean handleSelectionChangeEvents; private boolean handleSelectionChangeEvents;
private String languageModelName; private String languageModelName;
@@ -54,20 +54,22 @@ public class AIAgentConfigurationPanel extends SimplePanel {
this.stringMessages = stringMessages; this.stringMessages = stringMessages;
this.userService = presenter.getUserService(); this.userService = presenter.getUserService();
this.errorReporter = presenter.getErrorReporter(); this.errorReporter = presenter.getErrorReporter();
this.eventsTableWrapper = this.getEventsTableWrapper();
this.selectedEvents = new HashSet<>(); this.selectedEvents = new HashSet<>();
final VerticalPanel mainPanel = new VerticalPanel(); setWidget(this.getMainPanel(presenter));
mainPanel.setWidth("100%"); }
final AccessControlledButtonPanel buttonPanel = new AccessControlledButtonPanel(userService, EVENT);
private TableWrapperWithMultiSelectionAndFilterForSecuredDTO<EventDTO, StringMessages, AdminConsoleTableResources> getEventsTableWrapper() {
final AdminConsoleTableResources adminConsoleTableResources = GWT.create(AdminConsoleTableResources.class); final AdminConsoleTableResources adminConsoleTableResources = GWT.create(AdminConsoleTableResources.class);
hasCredentialsLabel = new Label(); final TableWrapperWithMultiSelectionAndFilterForSecuredDTO<EventDTO, StringMessages, AdminConsoleTableResources> eventsTableWrapper
final Label languageModelNameLabel = new Label(); = new TableWrapperWithMultiSelectionAndFilterForSecuredDTO<EventDTO, StringMessages, AdminConsoleTableResources>(
eventsTableWrapper = new TableWrapperWithMultiSelectionAndFilterForSecuredDTO<EventDTO, StringMessages, AdminConsoleTableResources>(stringMessages, this.errorReporter, this.stringMessages, this.errorReporter,
/* enablePager */ true, Optional.of(new EntityIdentityComparator<EventDTO>() { /* enablePager */ true, Optional.of(new EntityIdentityComparator<EventDTO>() {
@Override @Override
public boolean representSameEntity(EventDTO dto1, EventDTO dto2) { public boolean representSameEntity(EventDTO dto1, EventDTO dto2) {
return dto1.getId().equals(dto2.getId()); return dto1.getId().equals(dto2.getId());
} }
@Override @Override
public int hashCode(EventDTO t) { public int hashCode(EventDTO t) {
return t.getId().hashCode(); return t.getId().hashCode();
@@ -126,9 +128,16 @@ public class AIAgentConfigurationPanel extends SimplePanel {
})); }));
} }
}); });
return eventsTableWrapper;
}
private Widget getMainPanel(final Presenter presenter) {
final VerticalPanel mainPanel = new VerticalPanel();
mainPanel.setWidth("100%");
final AccessControlledButtonPanel buttonPanel = new AccessControlledButtonPanel(userService, EVENT);
final Button refresh = buttonPanel.addUnsecuredAction(stringMessages.refresh(), () -> presenter.getEventsRefresher().reloadAndCallFillAll()); final Button refresh = buttonPanel.addUnsecuredAction(stringMessages.refresh(), () -> presenter.getEventsRefresher().reloadAndCallFillAll());
refresh.ensureDebugId("RefreshEventsButton"); refresh.ensureDebugId("RefreshEventsButton");
eventsCaptionPanel = new CaptionPanel(stringMessages.selectEventsForWhichToUseAICommenting()); final CaptionPanel eventsCaptionPanel = new CaptionPanel(stringMessages.selectEventsForWhichToUseAICommenting());
eventsCaptionPanel.setWidth("100%"); eventsCaptionPanel.setWidth("100%");
final VerticalPanel contents = new VerticalPanel(); final VerticalPanel contents = new VerticalPanel();
contents.setWidth("100%"); contents.setWidth("100%");
@@ -139,22 +148,25 @@ public class AIAgentConfigurationPanel extends SimplePanel {
final CaptionPanel credentialsCaptionPanel = new CaptionPanel(stringMessages.credentials()); final CaptionPanel credentialsCaptionPanel = new CaptionPanel(stringMessages.credentials());
final VerticalPanel credentialsVP = new VerticalPanel(); final VerticalPanel credentialsVP = new VerticalPanel();
credentialsVP.setSpacing(5); credentialsVP.setSpacing(5);
final HorizontalPanel credentialsHP = new HorizontalPanel(); final HorizontalPanel hasOrResetCredentialsHP = new HorizontalPanel();
credentialsHP.setSpacing(5); hasOrResetCredentialsHP.setSpacing(5);
credentialsCaptionPanel.setContentWidget(credentialsVP); hasOrResetCredentialsHP.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE);
credentialsHP.add(credentialsTextArea); final Label hasCredentialsLabel = new Label();
final Button credentialsUpdateButton = new Button(stringMessages.updateCredentials()); hasOrResetCredentialsHP.add(hasCredentialsLabel);
eventsTableWrapper.getTable().setWidth("100%"); final Label languageModelNameLabel = new Label();
final Button resetCredentialsButton = new Button(stringMessages.resetCredentials());
final AsyncCallback<Boolean> hasAIAgentCredentialsCallback = new AsyncCallback<Boolean>() { final AsyncCallback<Boolean> hasAIAgentCredentialsCallback = new AsyncCallback<Boolean>() {
@Override @Override
public void onFailure(Throwable caught) { public void onFailure(Throwable caught) {
updateHasCredentialsLabelAndSetEventsCaptionVisibility(false); updateHasCredentialsLabelAndSetEventsCaptionVisibility(
false, hasCredentialsLabel, eventsCaptionPanel, resetCredentialsButton, languageModelNameLabel);
Notification.notify(stringMessages.errorTryingToCheckForAIAgentCredentials(caught.getMessage()), NotificationType.ERROR); Notification.notify(stringMessages.errorTryingToCheckForAIAgentCredentials(caught.getMessage()), NotificationType.ERROR);
} }
@Override @Override
public void onSuccess(Boolean result) { public void onSuccess(Boolean result) {
updateHasCredentialsLabelAndSetEventsCaptionVisibility(result); updateHasCredentialsLabelAndSetEventsCaptionVisibility(
result, hasCredentialsLabel, eventsCaptionPanel, resetCredentialsButton, languageModelNameLabel);
if (result) { if (result) {
sailingServiceWrite.getAIAgentLanguageModelName(new AsyncCallback<String>() { sailingServiceWrite.getAIAgentLanguageModelName(new AsyncCallback<String>() {
@Override @Override
@@ -180,6 +192,28 @@ public class AIAgentConfigurationPanel extends SimplePanel {
} }
} }
}; };
resetCredentialsButton.addClickHandler(e->sailingServiceWrite.resetAIAgentCredentials(
new AsyncCallback<Void>() {
@Override
public void onSuccess(Void result) {
sailingServiceWrite.hasAIAgentCredentials(hasAIAgentCredentialsCallback);
Notification.notify(stringMessages.successfullyResetAIAgentCredentials(), NotificationType.INFO);
}
@Override
public void onFailure(Throwable caught) {
sailingServiceWrite.hasAIAgentCredentials(hasAIAgentCredentialsCallback);
Notification.notify(stringMessages.errorUpdatingAIAgentCredentials(caught.getMessage()), NotificationType.ERROR);
}
}));
hasOrResetCredentialsHP.add(resetCredentialsButton);
credentialsVP.add(hasOrResetCredentialsHP);
final HorizontalPanel updateCredentialsHP = new HorizontalPanel();
updateCredentialsHP.setSpacing(5);
credentialsCaptionPanel.setContentWidget(credentialsVP);
updateCredentialsHP.add(credentialsTextArea);
final Button credentialsUpdateButton = new Button(stringMessages.updateCredentials());
eventsTableWrapper.getTable().setWidth("100%");
sailingServiceWrite.hasAIAgentCredentials(hasAIAgentCredentialsCallback); sailingServiceWrite.hasAIAgentCredentials(hasAIAgentCredentialsCallback);
credentialsUpdateButton.addClickHandler(e->sailingServiceWrite.setAIAgentCredentials( credentialsUpdateButton.addClickHandler(e->sailingServiceWrite.setAIAgentCredentials(
credentialsTextArea.getText(), new AsyncCallback<Void>() { credentialsTextArea.getText(), new AsyncCallback<Void>() {
@@ -197,13 +231,12 @@ public class AIAgentConfigurationPanel extends SimplePanel {
Notification.notify(stringMessages.errorUpdatingAIAgentCredentials(caught.getMessage()), NotificationType.ERROR); Notification.notify(stringMessages.errorUpdatingAIAgentCredentials(caught.getMessage()), NotificationType.ERROR);
} }
})); }));
credentialsHP.add(credentialsUpdateButton); updateCredentialsHP.add(credentialsUpdateButton);
credentialsVP.add(hasCredentialsLabel); credentialsVP.add(updateCredentialsHP);
credentialsVP.add(credentialsHP);
mainPanel.add(credentialsCaptionPanel); mainPanel.add(credentialsCaptionPanel);
mainPanel.add(languageModelNameLabel); mainPanel.add(languageModelNameLabel);
mainPanel.add(eventsCaptionPanel); mainPanel.add(eventsCaptionPanel);
setWidget(mainPanel); return mainPanel;
} }
public Displayer<EventDTO> getEventsDisplayer() { public Displayer<EventDTO> getEventsDisplayer() {
@@ -236,8 +269,16 @@ public class AIAgentConfigurationPanel extends SimplePanel {
}; };
} }
private void updateHasCredentialsLabelAndSetEventsCaptionVisibility(final boolean hasCredentials) { private void updateHasCredentialsLabelAndSetEventsCaptionVisibility(
hasCredentialsLabel.setText(hasCredentials ? stringMessages.hasAIAgentCredentials() : stringMessages.hasNoAIAgentCredentials()); final boolean hasCredentials,
final Label hasCredentialsLabel,
final CaptionPanel eventsCaptionPanel,
final Button resetCredentialsButton,
final Label languageModelNameLabel) {
final String label = hasCredentials ? stringMessages.hasAIAgentCredentials() : stringMessages.hasNoAIAgentCredentials();
hasCredentialsLabel.setText(label);
eventsCaptionPanel.setVisible(hasCredentials); eventsCaptionPanel.setVisible(hasCredentials);
resetCredentialsButton.setVisible(hasCredentials);
languageModelNameLabel.setVisible(hasCredentials);
} }
} }
@@ -758,4 +758,6 @@ public interface SailingServiceWrite extends FileStorageManagementGwtService, Sa
boolean hasAIAgentCredentials(); boolean hasAIAgentCredentials();
void setAIAgentCredentials(String credentials) throws Exception; void setAIAgentCredentials(String credentials) throws Exception;
void resetAIAgentCredentials();
} }
@@ -769,6 +769,8 @@ public interface SailingServiceWriteAsync extends FileStorageManagementGwtServic
void getAIAgentLanguageModelName(AsyncCallback<String> callback); void getAIAgentLanguageModelName(AsyncCallback<String> callback);
void hasAIAgentCredentials(AsyncCallback<Boolean> callback); void hasAIAgentCredentials(AsyncCallback<Boolean> callback);
void setAIAgentCredentials(String credentials, AsyncCallback<Void> callback); void setAIAgentCredentials(String credentials, AsyncCallback<Void> callback);
void resetAIAgentCredentials(AsyncCallback<Void> callback);
} }
@@ -2544,7 +2544,9 @@ public interface StringMessages extends com.sap.sse.gwt.client.StringMessages,
String placeholderAICoreCredentialsAsJSON(); String placeholderAICoreCredentialsAsJSON();
String credentials(); String credentials();
String updateCredentials(); String updateCredentials();
String resetCredentials();
String successfullyUpdatedAIAgentCredentials(); String successfullyUpdatedAIAgentCredentials();
String successfullyResetAIAgentCredentials();
String errorUpdatingAIAgentCredentials(String message); String errorUpdatingAIAgentCredentials(String message);
String corsAndCSPFilterConfiguration(); String corsAndCSPFilterConfiguration();
String corsAndCSPFilterConfigurationHint(); String corsAndCSPFilterConfigurationHint();
@@ -2582,7 +2582,9 @@ hasNoAIAgentCredentials=No AI Agent credentials available
placeholderAICoreCredentialsAsJSON=Provide AI Core credentials as JSON document placeholderAICoreCredentialsAsJSON=Provide AI Core credentials as JSON document
credentials=Credentials credentials=Credentials
updateCredentials=Update Credentials updateCredentials=Update Credentials
resetCredentials=Reset Credentials
successfullyUpdatedAIAgentCredentials=Successfully updated AI Agent credentials successfullyUpdatedAIAgentCredentials=Successfully updated AI Agent credentials
successfullyResetAIAgentCredentials=Successfully reset AI Agent credentials
errorUpdatingAIAgentCredentials=Error updating AI Agent credentials: {0} errorUpdatingAIAgentCredentials=Error updating AI Agent credentials: {0}
corsAndCSPFilterConfiguration=CORS and CSP "frame-ancestors" Filter Configuration corsAndCSPFilterConfiguration=CORS and CSP "frame-ancestors" Filter Configuration
corsAndCSPFilterConfigurationHint=Use carefully! You can use a wildcard to allow CORS requests to this server''s API and embedding of its pages in, e.g., IFrames from anywhere, or you can specify a set of allowed origin base URLs, as in https://www.example.org corsAndCSPFilterConfigurationHint=Use carefully! You can use a wildcard to allow CORS requests to this server''s API and embedding of its pages in, e.g., IFrames from anywhere, or you can specify a set of allowed origin base URLs, as in https://www.example.org
@@ -4156,11 +4156,18 @@ public class SailingServiceWriteImpl extends SailingServiceImpl implements Saili
throw new IllegalStateException("Credentials could not be parsed"); throw new IllegalStateException("Credentials could not be parsed");
} }
if (parsedCredentials != null) { if (parsedCredentials != null) {
aiAgent.setCredentials(parsedCredentials); aiAgent.setCredentials(parsedCredentials);
} }
} else { } else {
throw new IllegalStateException("Blank credentials received"); throw new IllegalStateException("Blank credentials received");
} }
} }
} }
@Override
public void resetAIAgentCredentials() {
checkAIAgentConfigPermission();
final AIAgent aiAgent = getAIAgent();
aiAgent.setCredentials(null);
}
} }