diff --git a/AxonIvyPortal/portal-components/config/variables/Assistants.json b/AxonIvyPortal/portal-components/config/variables/Assistants.json
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/AxonIvyPortal/portal-components/config/variables/Collections.json b/AxonIvyPortal/portal-components/config/variables/Collections.json
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/AxonIvyPortal/portal-components/config/variables/IvyTools.json b/AxonIvyPortal/portal-components/config/variables/IvyTools.json
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/AxonIvyPortal/portal-components/config/variables/RetrievalTools.json b/AxonIvyPortal/portal-components/config/variables/RetrievalTools.json
deleted file mode 100644
index e69de29bb2d..00000000000
diff --git a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/enums/PortalVariable.java b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/enums/PortalVariable.java
index 6432a077a7a..d3fcb1cbc05 100644
--- a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/enums/PortalVariable.java
+++ b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/enums/PortalVariable.java
@@ -13,8 +13,7 @@ public enum PortalVariable {
DASHBOARD("Portal.Dashboard"),
DASHBOARD_ORDER("Portal.Dashboard.Order"),
DASHBOARD_TEMPLATES("Portal.DashboardTemplates"),
- USER_MENU("Portal.UserMenu"),
- CHATBOT_ENDPOINT("PortalAiUrl");
+ USER_MENU("Portal.UserMenu");
public String key;
diff --git a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/enums/ai/IvyToolResultType.java b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/enums/ai/IvyToolResultType.java
deleted file mode 100644
index 3305caed83a..00000000000
--- a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/enums/ai/IvyToolResultType.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package com.axonivy.portal.components.enums.ai;
-
-public enum IvyToolResultType {
-
- JSON("%s"), IFRAME(""), ERROR("%s");
-
- private IvyToolResultType(String resultPattern) {
- this.resultPattern = resultPattern;
- }
-
- private String resultPattern;
-
- public String getResultPattern() {
- return resultPattern;
- }
-
- public void setResultPattern(String resultPattern) {
- this.resultPattern = resultPattern;
- }
-
- public String format(String content) {
- return String.format(this.resultPattern, content);
- }
-}
diff --git a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/enums/ai/RunState.java b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/enums/ai/RunState.java
deleted file mode 100644
index 977dfa9f835..00000000000
--- a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/enums/ai/RunState.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package com.axonivy.portal.components.enums.ai;
-
-public enum RunState {
- OPEN, IN_PROGRESS, DONE, ERROR;
-}
diff --git a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/util/AssistantUtils.java b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/publicapi/AiAssistantAPI.java
similarity index 62%
rename from AxonIvyPortal/portal-components/src/com/axonivy/portal/components/util/AssistantUtils.java
rename to AxonIvyPortal/portal-components/src/com/axonivy/portal/components/publicapi/AiAssistantAPI.java
index 8ef6372a50d..18cf3415d99 100644
--- a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/util/AssistantUtils.java
+++ b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/publicapi/AiAssistantAPI.java
@@ -1,26 +1,27 @@
-package com.axonivy.portal.components.util;
+package com.axonivy.portal.components.publicapi;
import java.util.Map;
import org.apache.commons.lang3.StringUtils;
-import com.axonivy.portal.components.enums.ai.IvyToolResultType;
import com.axonivy.portal.components.service.impl.ProcessService;
import ch.ivyteam.ivy.environment.Ivy;
import ch.ivyteam.ivy.workflow.start.IWebStartable;
-public class AssistantUtils {
+public class AiAssistantAPI {
+ private static final String IFRAME_RESULT_PATTERN = "";
+ private static final String ERROR_RESULT_PATTERN = "%s";
public static String generateLinkToIvyProcess(String link,
Map params) {
try {
IWebStartable process = initWebStartable(link);
- return IvyToolResultType.IFRAME
- .format(process.getLink().queryParams(params).getRelative());
+ return String.format(IFRAME_RESULT_PATTERN,
+ process.getLink().queryParams(params).getRelative());
} catch (Exception e) {
- return IvyToolResultType.ERROR
- .format(Ivy.cms().co("/Labels/AI/Error/ErrorWhenProceedRequest"));
+ return String.format(ERROR_RESULT_PATTERN,
+ Ivy.cms().co("/Labels/AI/Error/ErrorWhenProceedRequest"));
}
}
@@ -38,6 +39,6 @@ public static String generateErrorResult(String error) {
if (StringUtils.isBlank(error)) {
return "";
}
- return IvyToolResultType.ERROR.format(error);
+ return String.format(ERROR_RESULT_PATTERN, error);
}
}
diff --git a/AxonIvyPortal/portal/config/variables.yaml b/AxonIvyPortal/portal/config/variables.yaml
index 44af0c087d0..4db3de34879 100644
--- a/AxonIvyPortal/portal/config/variables.yaml
+++ b/AxonIvyPortal/portal/config/variables.yaml
@@ -200,9 +200,6 @@ Variables:
# [enum: 1, 2, 3, 4, 5]
MaxConnection: 3
- # Endpoint URL for the RESTful service of Portal chatbot
- ChatBotEndpoint: localhost:8018
-
Histories:
# If true, case note does not display any system tasks for non-administrator users.
HideSystemTasks: true
@@ -302,17 +299,6 @@ Variables:
# Set this property to true to enable the DeepL translation support
Enable: false
- # You can define AI assistants here
- # [file: json]
- Assistant:
-
- # You can define AI Tools
- # [file: json]
- AiTool:
-
- #URL to the REST service endpoint of Portal AI
- PortalAiUrl: 'http://localhost:8018'
-
# You can define the application name via this JSON file.
# It will be shown with the page title
ApplicationName: Axon Ivy
diff --git a/AxonIvyPortal/portal/config/variables/Portal/AiTool.json b/AxonIvyPortal/portal/config/variables/Portal/AiTool.json
deleted file mode 100644
index 47ebb9892cb..00000000000
--- a/AxonIvyPortal/portal/config/variables/Portal/AiTool.json
+++ /dev/null
@@ -1,71 +0,0 @@
-[
- {
- "id" : "find-tasks",
- "name" : "Find tasks",
- "type" : "IVY",
- "signature" : "findTasks(String,String,String,String)",
- "permissions" : ["Everybody"],
- "description" : "This tool is helpful when user want to find tasks by attributes. ONLY useful for task",
- "attributes" : [
- {
- "name" : "taskName",
- "description" : "Name of the task"
- } , {
- "name" : "taskDescription",
- "description" : "Description of the task"
- } , {
- "name" : "taskPriority",
- "description" : "Priority of a task. Valid values for this attribute: low, normal, high, exception"
- } , {
- "name" : "taskState",
- "description" : "State of the task. Valid values for this attribute: open, in progress, done"
- }
-
- ]
- } , {
- "id" : "find-cases",
- "name" : "Find cases",
- "type" : "IVY",
- "signature" : "findCases(String,String,String)",
- "permissions" : ["Everybody"],
- "description" : "This tool is helpful when user want to find cases by attributes. ONLY useful for case",
- "attributes" : [
- {
- "name" : "caseName",
- "description" : "Name of the case"
- } , {
- "name" : "caseDescription",
- "description" : "Description of the case"
- } , {
- "name" : "caseState",
- "description" : "State of the case. Valid values for this attribute: open, done, destroyed"
- }
-
- ]
- } , {
- "id" : "portal-support",
- "name" : "Portal support",
- "type" : "RETRIEVAL_QA",
- "default" : true,
- "description" : "Helpful when user ask questions.",
- "permissions" : ["Everybody"],
- "collection" : "portal-user-guide"
- } , {
- "id" : "find-users",
- "name" : "Find users",
- "type" : "IVY",
- "signature" : "findUsers(String,String)",
- "permissions" : ["Everybody"],
- "description" : "This is a tool to find information of users.",
- "attributes" : [
- {
- "name" : "username",
- "description" : "Name of user"
- } , {
- "name" : "role",
- "description" : "Role of user"
- }
- ],
- "postAction" : "ONLY use data from the from the result, show as list these informations: name, display name, email, status (field enabled), if any field is null or empty, show blank space instead. Format: \nName: name\nDisplay Name: displayname\n Email: email\n... and so on"
- }
-]
\ No newline at end of file
diff --git a/AxonIvyPortal/portal/config/variables/Portal/Assistant.json b/AxonIvyPortal/portal/config/variables/Portal/Assistant.json
deleted file mode 100644
index 803275bb37f..00000000000
--- a/AxonIvyPortal/portal/config/variables/Portal/Assistant.json
+++ /dev/null
@@ -1,7 +0,0 @@
-[
- {
- "id" : "assistant-1",
- "name" : "Portal Assistant",
- "tools" : ["find-tasks", "portal-support"]
- }
-]
\ No newline at end of file
diff --git a/AxonIvyPortal/portal/dataclasses/portalkit/PortalToolsData.ivyClass b/AxonIvyPortal/portal/dataclasses/portalkit/PortalToolsData.ivyClass
index db9943cc304..a4da3493fb3 100644
--- a/AxonIvyPortal/portal/dataclasses/portalkit/PortalToolsData.ivyClass
+++ b/AxonIvyPortal/portal/dataclasses/portalkit/PortalToolsData.ivyClass
@@ -1,6 +1,5 @@
PortalToolsData #class
portalkit #namespace
-tool ch.ivy.addon.portalkit.dto.ai.IvyTool #field
taskDashboardWidget ch.ivy.addon.portalkit.dto.dashboard.TaskDashboardWidget #field
name String #field
description String #field
diff --git a/AxonIvyPortal/portal/processes/AI Tool Processes/PortalCallableTools.p.json b/AxonIvyPortal/portal/processes/AI Tool Processes/PortalCallableTools.p.json
index 23851d582fa..fd3828fd9d5 100644
--- a/AxonIvyPortal/portal/processes/AI Tool Processes/PortalCallableTools.p.json
+++ b/AxonIvyPortal/portal/processes/AI Tool Processes/PortalCallableTools.p.json
@@ -49,7 +49,7 @@
"config" : {
"output" : {
"code" : [
- "import com.axonivy.portal.components.util.AssistantUtils;",
+ "import com.axonivy.portal.components.publicapi.AiAssistantAPI;",
"import org.apache.commons.collections4.CollectionUtils;",
"import com.axonivy.portal.components.persistence.converter.BusinessEntityConverter;",
"import org.apache.commons.lang3.StringUtils;",
@@ -65,7 +65,7 @@
"if (CollectionUtils.isNotEmpty(in.users)) {",
" in.result = BusinessEntityConverter.entityToJsonValue(in.users);",
"} else {",
- " in.result = AssistantUtils.generateErrorResult(ivy.cms.co(\"/Labels/AI/Error/CannotFindUser\"));",
+ " in.result = AiAssistantAPI.generateErrorResult(ivy.cms.co(\"/Labels/AI/Error/CannotFindUser\"));",
"}"
]
},
@@ -126,8 +126,8 @@
"config" : {
"output" : {
"code" : [
+ "import com.axonivy.portal.components.publicapi.AiAssistantAPI;",
"import ch.ivyteam.ivy.application.IApplication;",
- "import com.axonivy.portal.components.util.AssistantUtils;",
"import java.util.HashMap;",
"import java.util.Map;",
"",
@@ -137,7 +137,7 @@
"params.put(\"taskState\", in.taskState);",
"params.put(\"taskPriority\", in.taskPriority);",
"",
- "in.result = AssistantUtils.generateLinkToIvyProcess(IApplication.current().getName() + \"/portal/AI Tool Processes/PortalTools/findTasksTool.ivp\", params);"
+ "in.result = AiAssistantAPI.generateLinkToIvyProcess(IApplication.current().getName() + \"/portal/AI Tool Processes/PortalTools/findTasksTool.ivp\", params);"
]
}
},
@@ -154,8 +154,8 @@
"config" : {
"output" : {
"code" : [
+ "import com.axonivy.portal.components.publicapi.AiAssistantAPI;",
"import org.apache.commons.lang3.StringUtils;",
- "import com.axonivy.portal.components.util.AssistantUtils;",
"import com.axonivy.portal.util.AiToolUtils;",
"",
"in.validationError = AiToolUtils.validateTaskState(in.taskState);",
@@ -164,7 +164,7 @@
"}",
"",
"if(StringUtils.isNotBlank(in.validationError)) {",
- " in.result = AssistantUtils.generateErrorResult(in.validationError);",
+ " in.result = AiAssistantAPI.generateErrorResult(in.validationError);",
"}"
]
}
@@ -247,13 +247,13 @@
"config" : {
"output" : {
"code" : [
+ "import com.axonivy.portal.components.publicapi.AiAssistantAPI;",
"import org.apache.commons.lang3.StringUtils;",
"import com.axonivy.portal.util.AiToolUtils;",
- "import com.axonivy.portal.components.util.AssistantUtils;",
"",
"in.validationError = AiToolUtils.validateCaseState(in.taskState);",
"if(StringUtils.isNotBlank(in.validationError)) {",
- " in.result = AssistantUtils.generateErrorResult(in.validationError);",
+ " in.result = AiAssistantAPI.generateErrorResult(in.validationError);",
"}"
]
}
@@ -293,8 +293,8 @@
"config" : {
"output" : {
"code" : [
+ "import com.axonivy.portal.components.publicapi.AiAssistantAPI;",
"import ch.ivyteam.ivy.application.IApplication;",
- "import com.axonivy.portal.components.util.AssistantUtils;",
"import java.util.HashMap;",
"import java.util.Map;",
"",
@@ -303,7 +303,7 @@
"params.put(\"caseDescription\", in.taskDescription);",
"params.put(\"caseState\", in.taskState);",
"",
- "in.result = AssistantUtils.generateLinkToIvyProcess(IApplication.current().getName() + \"/portal/AI Tool Processes/PortalTools/findCasesTool.ivp\", params);"
+ "in.result = AiAssistantAPI.generateLinkToIvyProcess(IApplication.current().getName() + \"/portal/AI Tool Processes/PortalTools/findCasesTool.ivp\", params);"
]
}
},
diff --git a/AxonIvyPortal/portal/processes/Start Processes/PortalStart.p.json b/AxonIvyPortal/portal/processes/Start Processes/PortalStart.p.json
index 430df54cf49..ffe639b03aa 100644
--- a/AxonIvyPortal/portal/processes/Start Processes/PortalStart.p.json
+++ b/AxonIvyPortal/portal/processes/Start Processes/PortalStart.p.json
@@ -4906,37 +4906,5 @@
"connect" : [
{ "id" : "f294", "to" : "f271" }
]
- }, {
- "id" : "f282",
- "type" : "RequestStart",
- "name" : "PortalChatDashboard",
- "config" : {
- "signature" : "PortalChatDashboard"
- },
- "visual" : {
- "at" : { "x" : 96, "y" : 4192 }
- },
- "connect" : [
- { "id" : "f287", "to" : "f285" }
- ]
- }, {
- "id" : "f285",
- "type" : "DialogCall",
- "name" : "ChatDashboard",
- "config" : {
- "dialog" : "com.axonivy.portal.component.ChatDashboard:start()"
- },
- "visual" : {
- "at" : { "x" : 280, "y" : 4192 }
- },
- "connect" : [
- { "id" : "f290", "to" : "f286" }
- ]
- }, {
- "id" : "f286",
- "type" : "TaskEnd",
- "visual" : {
- "at" : { "x" : 464, "y" : 4192 }
- }
} ]
}
\ No newline at end of file
diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/ChatRendererBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/ChatRendererBean.java
index 944b83c4161..b276595f8d2 100644
--- a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/ChatRendererBean.java
+++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/ChatRendererBean.java
@@ -2,6 +2,7 @@
import java.io.Serializable;
import java.util.Map;
+import java.util.Optional;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
@@ -12,9 +13,11 @@
import com.axonivy.portal.components.service.IvyAdapterService;
import ch.ivy.addon.portalkit.enums.GlobalVariable;
-import ch.ivy.addon.portalkit.enums.PortalVariable;
+import ch.ivy.addon.portalkit.service.AiProcessService;
import ch.ivy.addon.portalkit.service.GlobalSettingService;
import ch.ivyteam.ivy.environment.Ivy;
+import ch.ivyteam.ivy.model.value.WebLink;
+import ch.ivyteam.ivy.workflow.IProcessStart;
@ManagedBean
@ViewScoped
@@ -25,6 +28,7 @@ public class ChatRendererBean implements Serializable {
private Boolean isGroupChatRendered;
private Boolean isPrivateChatRendered;
+ private IProcessStart assistantDashboardProcess;
public boolean getIsChatRendered() {
return getIsGroupChatRendered() || getIsPrivateChatRendered();
@@ -62,7 +66,14 @@ public boolean isExpressCreationTask() {
return Ivy.wfTask().customFields().stringField(EXPRESS_CREATION_TASK).get().isPresent();
}
- public boolean getIsChatbotRendered() {
- return !StringUtils.isBlank(Ivy.var().get(PortalVariable.CHATBOT_ENDPOINT.key));
+ public boolean getIsAssistantDashboardRendered() {
+ if (this.assistantDashboardProcess == null) {
+ this.assistantDashboardProcess = AiProcessService.getInstance()
+ .findAssistantDashboardProcess();
+ }
+ return StringUtils.isNotBlank(Optional.ofNullable(assistantDashboardProcess)
+ .map(IProcessStart::getLinkEmbedded).map(WebLink::getRelative)
+ .orElse(""));
}
+
}
diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/DashboardBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/DashboardBean.java
index 107d1b85e80..e6261363352 100644
--- a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/DashboardBean.java
+++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/DashboardBean.java
@@ -1,12 +1,8 @@
package ch.ivy.addon.portal.generic.bean;
-import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
-import java.util.Random;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
@@ -17,13 +13,11 @@
import org.apache.commons.lang3.StringUtils;
import org.primefaces.event.SelectEvent;
-import com.axonivy.portal.components.util.HtmlUtils;
import com.axonivy.portal.dto.dashboard.filter.DashboardFilter;
import com.axonivy.portal.service.DeepLTranslationService;
import ch.addon.portal.generic.menu.MenuView;
import ch.ivy.addon.portal.generic.navigation.PortalNavigator;
-import ch.ivy.addon.portalkit.constant.PortalConstants;
import ch.ivy.addon.portalkit.dto.DisplayName;
import ch.ivy.addon.portalkit.dto.dashboard.CaseDashboardWidget;
import ch.ivy.addon.portalkit.dto.dashboard.ColumnModel;
@@ -34,31 +28,23 @@
import ch.ivy.addon.portalkit.dto.dashboard.SingleProcessDashboardWidget;
import ch.ivy.addon.portalkit.dto.dashboard.TaskDashboardWidget;
import ch.ivy.addon.portalkit.dto.dashboard.WidgetFilterModel;
-import ch.ivy.addon.portalkit.enums.BehaviourWhenClickingOnLineInTaskList;
-import ch.ivy.addon.portalkit.enums.CaseEmptyMessage;
import ch.ivy.addon.portalkit.enums.DashboardWidgetType;
-import ch.ivy.addon.portalkit.enums.GlobalVariable;
-import ch.ivy.addon.portalkit.enums.PortalPage;
import ch.ivy.addon.portalkit.enums.PortalVariable;
import ch.ivy.addon.portalkit.enums.SessionAttribute;
-import ch.ivy.addon.portalkit.enums.TaskEmptyMessage;
import ch.ivy.addon.portalkit.exporter.Exporter;
import ch.ivy.addon.portalkit.ivydata.service.impl.LanguageService;
import ch.ivy.addon.portalkit.jsf.ManagedBeans;
import ch.ivy.addon.portalkit.persistence.converter.BusinessEntityConverter;
-import ch.ivy.addon.portalkit.service.GlobalSettingService;
import ch.ivy.addon.portalkit.service.WidgetFilterService;
import ch.ivy.addon.portalkit.support.HtmlParser;
import ch.ivy.addon.portalkit.util.DashboardUtils;
import ch.ivy.addon.portalkit.util.DashboardWidgetUtils;
import ch.ivy.addon.portalkit.util.PermissionUtils;
-import ch.ivy.addon.portalkit.util.TaskUtils;
import ch.ivy.addon.portalkit.util.UrlUtils;
import ch.ivy.addon.portalkit.util.UserUtils;
import ch.ivyteam.ivy.environment.Ivy;
import ch.ivyteam.ivy.security.ISecurityConstants;
import ch.ivyteam.ivy.security.IUser;
-import ch.ivyteam.ivy.workflow.ICase;
import ch.ivyteam.ivy.workflow.ITask;
@ViewScoped
@@ -75,10 +61,6 @@ public class DashboardBean implements Serializable {
private int currentDashboardIndex;
private List widgetFilters;
private List deleteFilters;
- private ITask selectedTask;
- private boolean isRunningTaskWhenClickingOnTaskInList;
- private CaseEmptyMessage noCasesMessage;
- private TaskEmptyMessage noTasksMessage;
private List dashboardTemplates;
protected String translatedText;
protected String warningText;
@@ -116,9 +98,6 @@ public void init() {
}
}
buildWidgetModels(selectedDashboard);
- isRunningTaskWhenClickingOnTaskInList = GlobalSettingService.getInstance()
- .findGlobalSettingValue(GlobalVariable.DEFAULT_BEHAVIOUR_WHEN_CLICKING_ON_LINE_IN_TASK_LIST)
- .equals(BehaviourWhenClickingOnLineInTaskList.RUN_TASK.name());
buildClientStatisticApiUri();
}
@@ -185,38 +164,6 @@ public void navigateToSelectedTaskDetails(SelectEvent