fi.evolver.ai.vaadin.view.ChatHistoryBaseView Maven / Gradle / Ivy
package fi.evolver.ai.vaadin.view;
import java.io.Serial;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.dialog.Dialog;
import com.vaadin.flow.component.html.H3;
import com.vaadin.flow.component.html.Hr;
import com.vaadin.flow.component.html.Span;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.textfield.TextArea;
import com.vaadin.flow.theme.lumo.LumoUtility;
import fi.evolver.ai.vaadin.ChatHistoryConfiguration;
import fi.evolver.ai.vaadin.ChatHistoryConfigurationProps;
import fi.evolver.ai.vaadin.ChatRepository;
import fi.evolver.ai.vaadin.component.ChatHistoryAvatarItem;
import fi.evolver.ai.vaadin.entity.Chat;
import fi.evolver.ai.vaadin.util.AuthUtils;
import fi.evolver.utils.string.StringUtils;
public abstract class ChatHistoryBaseView extends VerticalLayout implements ChatHistoryAction {
@Serial
private static final long serialVersionUID = 1L;
private static final int DEFAULT_DAYS_TO_SHOW = 30;
private final ChatRepository chatRepository;
private final ChatHistoryConfigurationProps chatHistoryConfigurationProps;
public ChatHistoryBaseView(ChatRepository chatRepository, ChatHistoryConfigurationProps chatHistoryConfigurationProps) {
this.chatRepository = chatRepository;
this.chatHistoryConfigurationProps = chatHistoryConfigurationProps;
createContent(false);
}
public void createContent(boolean isRefresh) {
if (isRefresh)
removeAll();
setWidth("100%");
getStyle().set("flex-grow", "1");
generateHistoryContent();
}
private void generateHistoryContent() {
List configs = chatHistoryConfigurationProps.getConfigurations();
if (configs == null || configs.isEmpty()) {
generateNoChatsMessage(getTranslation("view.chatHistory.noHistory"));
return;
}
generateFavoriteChatsContent();
generateChatHistoryContent();
}
private void generateFavoriteChatsContent() {
add(new H3(getTranslation("view.chatHistory.favorites")));
List chats = chatRepository.findFavoriteChats(AuthUtils.getEmail());
Map configsByType = chatHistoryConfigurationProps.getConfigurations().stream()
.collect(Collectors.toMap(ChatHistoryConfiguration::type, c -> c));
if (chats.isEmpty()) {
generateNoChatsMessage(getTranslation("view.chatHistory.noFavorites"));
}
else {
chats.stream()
.filter(c -> c.getSummary() != null && !c.getSummary().isEmpty())
.filter(c -> configsByType.get(c.getChatType()) != null)
.map(c -> new ChatHistoryAvatarItem(c, configsByType.get(c.getChatType()), this))
.forEach(this::add);
}
add(new Hr());
}
private void generateChatHistoryContent() {
for (ChatHistoryConfiguration config : chatHistoryConfigurationProps.getConfigurations()) {
String titleString = "";
if (StringUtils.hasText(config.translationKey()))
titleString = getTranslation(config.translationKey());
else
titleString = config.title();
add(new H3("%s".formatted(titleString)));
List chats = chatRepository.findNonFavoriteChats(
AuthUtils.getEmail(),
config.type(),
LocalDate.now().minusDays(Optional.ofNullable(config.daysToShow()).orElse(DEFAULT_DAYS_TO_SHOW)).atStartOfDay());
if (chats.isEmpty()) {
generateNoChatsMessage(getTranslation("view.chatHistory.noHistory"));
}
else {
chats.stream()
.filter(c -> c.getSummary() != null && !c.getSummary().isEmpty())
.map(c -> new ChatHistoryAvatarItem(c, config, this))
.forEach(this::add);
}
add(new Hr());
}
}
@Override
public void showEditDialog(Chat chat) {
Dialog editChatDialog = new Dialog();
editChatDialog.setWidth("400px");
editChatDialog.setHeaderTitle(getTranslation("view.chatHistory.renameChat"));
VerticalLayout contentLayout = new VerticalLayout();
contentLayout.setWidthFull();
contentLayout.setPadding(false);
contentLayout.setMargin(false);
TextArea updatedChatSummary = new TextArea(getTranslation("view.chatHistory.newName"));
updatedChatSummary.setWidthFull();
contentLayout.add(updatedChatSummary);
editChatDialog.add(contentLayout);
Button submitButton = new Button(getTranslation("common.save"), e -> {
String updatableValue = updatedChatSummary.getValue().trim();
if (!updatableValue.isEmpty()) {
renameChat(chat, updatableValue);
editChatDialog.close();
}
});
submitButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
submitButton.getStyle().set("margin-right", "auto");
editChatDialog.getFooter().add(submitButton);
Button cancelButton = new Button(getTranslation("common.cancel"), e -> editChatDialog.close());
cancelButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
editChatDialog.getFooter().add(cancelButton);
editChatDialog.open();
}
@Override
public void showRemovalDialog(Chat chat) {
Dialog removalDialog = new Dialog();
removalDialog.setHeaderTitle(getTranslation("view.chatHistory.confirmDelete.title"));
removalDialog.add(getTranslation("view.chatHistory.confirmDelete.dialog"));
Button deleteButton = new Button(getTranslation("common.delete"), e -> {
removeChat(chat);
removalDialog.close();
});
deleteButton.addThemeVariants(ButtonVariant.LUMO_PRIMARY, ButtonVariant.LUMO_ERROR);
deleteButton.getStyle().set("margin-right", "auto");
removalDialog.getFooter().add(deleteButton);
Button cancelButton = new Button(getTranslation("common.cancel"), e -> removalDialog.close());
cancelButton.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
removalDialog.getFooter().add(cancelButton);
removalDialog.open();
}
@Override
public void toggleFavorite(Chat chat) {
chat.setFavorite(!chat.isFavorite());
chatRepository.save(chat);
this.createContent(true);
showNotification(!chat.isFavorite() ?
getTranslation("view.chatHistory.removedFromFavorites") :
getTranslation("view.chatHistory.addedToFavorites"));
}
@Override
public void setChatRating(Chat chat, Integer rating) {
chat.setChatRating(rating);
chatRepository.save(chat);
}
private static void showNotification(String message) {
Notification.show(message, 3000, Notification.Position.MIDDLE);
}
private void renameChat(Chat chat, String updatedSummary) {
chat.setSummary(updatedSummary);
chatRepository.save(chat);
this.createContent(true);
}
private void removeChat(Chat chat) {
chatRepository.delete(chat);
this.createContent(true);
}
private void generateNoChatsMessage(String message) {
Span noChatHistory = new Span(message);
noChatHistory.addClassNames(LumoUtility.FontSize.LARGE, LumoUtility.TextColor.PRIMARY);
add(noChatHistory);
}
}