diff --git a/AxonIvyPortal/PortalKitTestHelper/.settings/ch.ivyteam.ivy.designer.prefs b/AxonIvyPortal/PortalKitTestHelper/.settings/ch.ivyteam.ivy.designer.prefs index 9ac8d07f626..690f6b2e7dd 100644 --- a/AxonIvyPortal/PortalKitTestHelper/.settings/ch.ivyteam.ivy.designer.prefs +++ b/AxonIvyPortal/PortalKitTestHelper/.settings/ch.ivyteam.ivy.designer.prefs @@ -1,4 +1,3 @@ -ch.ivyteam.ivy.designer.preferences.DataClassPreferencePage\:DEFAULT_DATA_CLASS=portalKit_test.Data ch.ivyteam.ivy.designer.preferences.DataClassPreferencePage\:DEFAULT_NAMESPACE=portalKit_test ch.ivyteam.ivy.designer.preferences.editor.ProcessEditorPreferencePage\:ELEMENT_STYLE=BPMN ch.ivyteam.ivy.designer.preferences.editor.ProcessEditorPreferencePage\:NET_BACKGROUND_COLOR=255,255,255 @@ -7,5 +6,5 @@ ch.ivyteam.ivy.designer.preferences.editor.ProcessEditorPreferencePage\:SHOW_GRI ch.ivyteam.ivy.designer.preferences.editor.ProcessEditorPreferencePage\:useProjectSettings=true ch.ivyteam.ivy.project.preferences\:PORTAL_VERSION=10 ch.ivyteam.ivy.project.preferences\:PRIMEFACES_VERSION=13 -ch.ivyteam.ivy.project.preferences\:PROJECT_VERSION=114006 +ch.ivyteam.ivy.project.preferences\:PROJECT_VERSION=120001 eclipse.preferences.version=1 diff --git a/AxonIvyPortal/PortalKitTestHelper/dataclasses/ch/ivy/add/portalkit/task/TaskGenerationData.d.json b/AxonIvyPortal/PortalKitTestHelper/dataclasses/ch/ivy/add/portalkit/task/TaskGenerationData.d.json index 8d84481f2fe..98d111c2e36 100644 --- a/AxonIvyPortal/PortalKitTestHelper/dataclasses/ch/ivy/add/portalkit/task/TaskGenerationData.d.json +++ b/AxonIvyPortal/PortalKitTestHelper/dataclasses/ch/ivy/add/portalkit/task/TaskGenerationData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "TaskGenerationData", "namespace" : "ch.ivy.add.portalkit.task", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/PortalKitTestHelper/dataclasses/ch/ivy/add/portalkit/task/TaskGenerationDataRange.d.json b/AxonIvyPortal/PortalKitTestHelper/dataclasses/ch/ivy/add/portalkit/task/TaskGenerationDataRange.d.json index 015ee11be9c..80ae5ce8b92 100644 --- a/AxonIvyPortal/PortalKitTestHelper/dataclasses/ch/ivy/add/portalkit/task/TaskGenerationDataRange.d.json +++ b/AxonIvyPortal/PortalKitTestHelper/dataclasses/ch/ivy/add/portalkit/task/TaskGenerationDataRange.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "TaskGenerationDataRange", "namespace" : "ch.ivy.add.portalkit.task", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/PortalKitTestHelper/dataclasses/ch/ivy/addon/portalkit/showroom/ExtendedTask.d.json b/AxonIvyPortal/PortalKitTestHelper/dataclasses/ch/ivy/addon/portalkit/showroom/ExtendedTask.d.json deleted file mode 100644 index 19ebaa9322c..00000000000 --- a/AxonIvyPortal/PortalKitTestHelper/dataclasses/ch/ivy/addon/portalkit/showroom/ExtendedTask.d.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", - "simpleName" : "ExtendedTask", - "namespace" : "ch.ivy.addon.portalkit.showroom", - "isBusinessCaseData" : false, - "fields" : [ { - "name" : "iTask", - "type" : "ch.ivyteam.ivy.workflow.ITask", - "modifiers" : [ "PERSISTENT" ] - }, { - "name" : "taskId", - "type" : "Number", - "modifiers" : [ "PERSISTENT" ] - }, { - "name" : "caseId", - "type" : "Number", - "modifiers" : [ "PERSISTENT" ] - } ] -} \ No newline at end of file diff --git a/AxonIvyPortal/PortalKitTestHelper/dataclasses/internaltest/Data.d.json b/AxonIvyPortal/PortalKitTestHelper/dataclasses/internaltest/Data.d.json index 48ecc0dbb3c..4e4181f3def 100644 --- a/AxonIvyPortal/PortalKitTestHelper/dataclasses/internaltest/Data.d.json +++ b/AxonIvyPortal/PortalKitTestHelper/dataclasses/internaltest/Data.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "Data", "namespace" : "internaltest", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/AdminSettingsData.d.json b/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/AdminSettingsData.d.json index 790bf8f3498..5ce7dc9231f 100644 --- a/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/AdminSettingsData.d.json +++ b/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/AdminSettingsData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "AdminSettingsData", "namespace" : "portalKit_test", "isBusinessCaseData" : false diff --git a/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/DashboardCreationData.d.json b/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/DashboardCreationData.d.json index 7ed0f1c8c71..a8f2841329d 100644 --- a/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/DashboardCreationData.d.json +++ b/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/DashboardCreationData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "DashboardCreationData", "namespace" : "portalKit_test", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/Data.d.json b/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/Data.d.json index a87a7018eee..3b8602647d0 100644 --- a/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/Data.d.json +++ b/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/Data.d.json @@ -1,13 +1,9 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "Data", "namespace" : "portalKit_test", "isBusinessCaseData" : false, "fields" : [ { - "name" : "iTask", - "type" : "ch.ivyteam.ivy.workflow.ITask", - "modifiers" : [ "PERSISTENT" ] - }, { "name" : "taskId", "type" : "Number", "modifiers" : [ "PERSISTENT" ] @@ -33,15 +29,13 @@ "modifiers" : [ "PERSISTENT" ] }, { "name" : "cases", - "type" : "List", - "modifiers" : [ "PERSISTENT" ] + "type" : "List" }, { "name" : "count", "type" : "Integer", "modifiers" : [ "PERSISTENT" ] }, { "name" : "workingCase", - "type" : "ch.ivyteam.ivy.workflow.ICase", - "modifiers" : [ "PERSISTENT" ] + "type" : "ch.ivyteam.ivy.workflow.ICase" } ] } \ No newline at end of file diff --git a/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/DataCreationData.d.json b/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/DataCreationData.d.json index 4eca3878b45..c4840de0bb5 100644 --- a/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/DataCreationData.d.json +++ b/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/DataCreationData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "DataCreationData", "namespace" : "portalKit_test", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/GrantPermissionsData.d.json b/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/GrantPermissionsData.d.json index b854d580096..9cc6316175b 100644 --- a/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/GrantPermissionsData.d.json +++ b/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/GrantPermissionsData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "GrantPermissionsData", "namespace" : "portalKit_test", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/LoginData.d.json b/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/LoginData.d.json index 9a12eae475f..bdf18ee753c 100644 --- a/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/LoginData.d.json +++ b/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/LoginData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "LoginData", "namespace" : "portalKit_test", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/PortalGlobalVariableHelperData.d.json b/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/PortalGlobalVariableHelperData.d.json index a9b74614e36..639710719ed 100644 --- a/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/PortalGlobalVariableHelperData.d.json +++ b/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/PortalGlobalVariableHelperData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "PortalGlobalVariableHelperData", "namespace" : "portalKit_test", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/PortalSettingHelperData.d.json b/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/PortalSettingHelperData.d.json index 39cb085e682..b698594a111 100644 --- a/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/PortalSettingHelperData.d.json +++ b/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/PortalSettingHelperData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "PortalSettingHelperData", "namespace" : "portalKit_test", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/PortalKitTestHelper/processes/Business Processes/createARangeOfTasks.p.json b/AxonIvyPortal/PortalKitTestHelper/processes/Business Processes/createARangeOfTasks.p.json index 8c4c64e8c5a..f83a3a0195b 100644 --- a/AxonIvyPortal/PortalKitTestHelper/processes/Business Processes/createARangeOfTasks.p.json +++ b/AxonIvyPortal/PortalKitTestHelper/processes/Business Processes/createARangeOfTasks.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "14B2A3DC7173EA26", "config" : { "data" : "ch.ivy.add.portalkit.task.TaskGenerationDataRange" diff --git a/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/CleanData.p.json b/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/CleanData.p.json index bff17dc39aa..4b0dc1fad4f 100644 --- a/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/CleanData.p.json +++ b/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/CleanData.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "1511A66AF619A768", "config" : { "data" : "portalKit_test.Data" diff --git a/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/CreateDataForComplexFilter.p.json b/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/CreateDataForComplexFilter.p.json index fae0e0fbb23..15442a11185 100644 --- a/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/CreateDataForComplexFilter.p.json +++ b/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/CreateDataForComplexFilter.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "18B031C59C3C7814", "config" : { "data" : "portalKit_test.Data" diff --git a/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/DashboardCreation.p.json b/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/DashboardCreation.p.json index a771247272b..24ee4fb887b 100644 --- a/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/DashboardCreation.p.json +++ b/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/DashboardCreation.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "17F2050944B46BB0", "config" : { "data" : "portalKit_test.DashboardCreationData" diff --git a/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/DataCreation.p.json b/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/DataCreation.p.json index a997ff5ece9..b948a8a66b2 100644 --- a/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/DataCreation.p.json +++ b/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/DataCreation.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "153CACC26D0D4C3D", "config" : { "data" : "portalKit_test.DataCreationData" diff --git a/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/GrantPermissions.p.json b/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/GrantPermissions.p.json index 63cd31fd2c9..1b896e1d6cb 100644 --- a/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/GrantPermissions.p.json +++ b/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/GrantPermissions.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "14DE09882B540AD5", "config" : { "data" : "portalKit_test.GrantPermissionsData" @@ -2088,7 +2088,7 @@ "type" : "RequestStart", "name" : "denyTaskDetailsShareLinkPermission.ivp", "config" : { - "signature" : "denyTaskDetailsShareLinkPermission2", + "signature" : "denyTaskDetailsShareLinkPermission", "request" : { "name" : "Deny Share Link Task Details Permision" } diff --git a/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/Login.p.json b/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/Login.p.json index 56af0fac32f..c57e25d5a8a 100644 --- a/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/Login.p.json +++ b/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/Login.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "1636734E13CEC872", "config" : { "data" : "portalKit_test.LoginData" diff --git a/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/PasswordReset.p.json b/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/PasswordReset.p.json index cf3e6af1c8c..1293d738929 100644 --- a/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/PasswordReset.p.json +++ b/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/PasswordReset.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "176463FD4BBF6C93", "config" : { "data" : "portalKit_test.Data" diff --git a/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/PortalCustomErrorHandler.p.json b/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/PortalCustomErrorHandler.p.json index 975e1299054..b5a8b3daa64 100644 --- a/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/PortalCustomErrorHandler.p.json +++ b/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/PortalCustomErrorHandler.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "18D596926C35B1DB", "config" : { "data" : "portalKit_test.Data" @@ -9,7 +9,12 @@ "type" : "RequestStart", "name" : "testPortalCustomErrorHandler.ivp", "config" : { - "signature" : "testPortalCustomErrorHandler" + "signature" : "testPortalCustomErrorHandler", + "task" : { + "customFields" : [ + { "name" : "embedInFrame", "type" : "STRING", "value" : "\"false\"" } + ] + } }, "visual" : { "at" : { "x" : 96, "y" : 64 } diff --git a/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/PortalGlobalVariableHelper.p.json b/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/PortalGlobalVariableHelper.p.json index d4d573c7c70..f7242f52198 100644 --- a/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/PortalGlobalVariableHelper.p.json +++ b/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/PortalGlobalVariableHelper.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "1749B87B8C1B77BE", "config" : { "data" : "portalKit_test.PortalGlobalVariableHelperData" diff --git a/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/PortalSettingHelper.p.json b/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/PortalSettingHelper.p.json index 691c649ce60..3bcc6c01c64 100644 --- a/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/PortalSettingHelper.p.json +++ b/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/PortalSettingHelper.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "17208192E0AF4185", "config" : { "data" : "portalKit_test.PortalSettingHelperData" diff --git a/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/Showcases.p.json b/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/Showcases.p.json index 2b04bbe2f22..b09a07d5009 100644 --- a/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/Showcases.p.json +++ b/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/Showcases.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "169BDE2F368D6EC4", "config" : { "data" : "portalKit_test.Data" diff --git a/AxonIvyPortal/PortalKitTestHelper/src/ch/ivy/addon/portalkit/test/util/TaskUtils.java b/AxonIvyPortal/PortalKitTestHelper/src/ch/ivy/addon/portalkit/test/util/TaskUtils.java index 7f94965af72..429ce1816d6 100644 --- a/AxonIvyPortal/PortalKitTestHelper/src/ch/ivy/addon/portalkit/test/util/TaskUtils.java +++ b/AxonIvyPortal/PortalKitTestHelper/src/ch/ivy/addon/portalkit/test/util/TaskUtils.java @@ -1,83 +1,34 @@ package ch.ivy.addon.portalkit.test.util; -import java.util.ArrayList; import java.util.List; import ch.ivyteam.ivy.environment.Ivy; -import ch.ivyteam.ivy.persistence.IQueryResult; import ch.ivyteam.ivy.security.exec.Sudo; -import ch.ivyteam.ivy.workflow.CaseProperty; import ch.ivyteam.ivy.workflow.CaseState; import ch.ivyteam.ivy.workflow.ICase; -import ch.ivyteam.ivy.workflow.IPropertyFilter; import ch.ivyteam.ivy.workflow.ITask; -import ch.ivyteam.ivy.workflow.TaskProperty; -import ch.ivyteam.ivy.workflow.TaskState; +import ch.ivyteam.ivy.workflow.query.CaseQuery; import ch.ivyteam.ivy.workflow.query.TaskQuery; public class TaskUtils { - public static List destroyAllCase() { - try { - return Sudo.call(() -> { - try { - IPropertyFilter noFilter = null; - IQueryResult qr = Ivy.wf().findCases(noFilter, null, 0, -1, true); - List names = new ArrayList(); - for (ICase ivyCase : qr.getResultList()) { - try { - if (ivyCase.getState().intValue() != TaskState.DESTROYED.intValue() - && ivyCase.getState().intValue() != TaskState.DONE.intValue()) { - ivyCase.destroy(); - } - } catch (Exception e1) { - Ivy.log().error(e1); - } - } - return names; - } catch (Exception e2) { - Ivy.log().error(e2); - return null; - } - }); - } catch (Exception e) { - Ivy.log().error(e); + public static void destroyAllCase() throws Exception { + Sudo.call(() -> { + List result = Ivy.wf().getCaseQueryExecutor() + .getResults(CaseQuery.create().where().state().isNotIn(CaseState.DESTROYED, CaseState.DONE)); + for (ICase iCaze : result) { + iCaze.destroy(); + } return null; - } - } - - public static boolean resumeFirstTask() { - try { - Sudo.call(() -> { - try { - IPropertyFilter filter = null; - IQueryResult result = Ivy.wf().findTasks(filter, null, 0, -1, true); - List tasks = result.getResultList(); - for (ITask task : tasks) { - if (TaskState.SUSPENDED == task.getState()) { - Ivy.session().resumeTask(task.getId()); - break; - } - } - return true; - } catch (Exception e) { - return false; - } - }); - } catch (Exception e) { - return false; - } - return false; + }); } public static void deleteCompletedCases() throws Exception { Sudo.call(() -> { - IPropertyFilter noFilter = null; - IQueryResult qr = Ivy.wf().findCases(noFilter, null, 0, -1, true); - for (ICase ivyCase : qr.getResultList()) { - if (ivyCase.getState() == CaseState.DESTROYED || ivyCase.getState() == CaseState.DONE) { - Ivy.wf().deleteCompletedCase(ivyCase); - } + List result = Ivy.wf().getCaseQueryExecutor() + .getResults(CaseQuery.create().where().state().isIn(CaseState.DESTROYED, CaseState.DONE)); + for (ICase iCaze : result) { + Ivy.wf().deleteCompletedCase(iCaze); } return null; }); @@ -85,12 +36,10 @@ public static void deleteCompletedCases() throws Exception { public static void deleteDestroyedCases() throws Exception { Sudo.call(() -> { - IPropertyFilter noFilter = null; - IQueryResult qr = Ivy.wf().findCases(noFilter, null, 0, -1, true); - for (ICase ivyCase : qr.getResultList()) { - if (ivyCase.getState() == CaseState.DESTROYED) { - Ivy.wf().deleteCompletedCase(ivyCase); - } + List result = Ivy.wf().getCaseQueryExecutor() + .getResults(CaseQuery.create().where().state().isEqual(CaseState.DESTROYED)); + for (ICase iCaze : result) { + Ivy.wf().deleteCompletedCase(iCaze); } return null; }); @@ -98,8 +47,8 @@ public static void deleteDestroyedCases() throws Exception { public static void destroyTaskByCustomField(String customFieldName) throws Exception { Sudo.call(() -> { - ITask selectedTask = TaskQuery.create().where().customField() - .stringField(customFieldName).isNotNull().executor().firstResult(); + ITask selectedTask = + TaskQuery.create().where().customField().stringField(customFieldName).isNotNull().executor().firstResult(); if (selectedTask != null) { selectedTask.destroy(); selectedTask.customFields().stringField(customFieldName).delete(); diff --git a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/showroom/multiapp/tasks/DestroyTaskPage/DestroyTaskPageData.d.json b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/showroom/multiapp/tasks/DestroyTaskPage/DestroyTaskPageData.d.json index aff7e52b62e..94d55b4dee3 100644 --- a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/showroom/multiapp/tasks/DestroyTaskPage/DestroyTaskPageData.d.json +++ b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/showroom/multiapp/tasks/DestroyTaskPage/DestroyTaskPageData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "DestroyTaskPageData", "namespace" : "ch.ivy.addon.portalkit.showroom.multiapp.tasks.DestroyTaskPage", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/showroom/multiapp/tasks/DestroyTaskPage/DestroyTaskPageProcess.p.json b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/showroom/multiapp/tasks/DestroyTaskPage/DestroyTaskPageProcess.p.json index 613b321a5ea..bcfddf906ab 100644 --- a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/showroom/multiapp/tasks/DestroyTaskPage/DestroyTaskPageProcess.p.json +++ b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/showroom/multiapp/tasks/DestroyTaskPage/DestroyTaskPageProcess.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "1559AE0A76284C44", "kind" : "HTML_DIALOG", "config" : { diff --git a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/Confirmation/ConfirmationData.d.json b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/Confirmation/ConfirmationData.d.json index 88b07051e4f..8e5a704499b 100644 --- a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/Confirmation/ConfirmationData.d.json +++ b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/Confirmation/ConfirmationData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "ConfirmationData", "namespace" : "ch.ivy.addon.portalkit.test.Confirmation", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/Confirmation/ConfirmationProcess.p.json b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/Confirmation/ConfirmationProcess.p.json index 9dcc3ea0486..60b3e57e531 100644 --- a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/Confirmation/ConfirmationProcess.p.json +++ b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/Confirmation/ConfirmationProcess.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "14B7775CB7A22AF4", "kind" : "HTML_DIALOG", "config" : { diff --git a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/CreateHiddenTasksAndCases/CreateHiddenTasksAndCasesData.d.json b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/CreateHiddenTasksAndCases/CreateHiddenTasksAndCasesData.d.json index 68d8e4a5295..d40eeba7059 100644 --- a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/CreateHiddenTasksAndCases/CreateHiddenTasksAndCasesData.d.json +++ b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/CreateHiddenTasksAndCases/CreateHiddenTasksAndCasesData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "CreateHiddenTasksAndCasesData", "namespace" : "ch.ivy.addon.portalkit.test.CreateHiddenTasksAndCases", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/CreateHiddenTasksAndCases/CreateHiddenTasksAndCasesProcess.p.json b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/CreateHiddenTasksAndCases/CreateHiddenTasksAndCasesProcess.p.json index f68c1672a36..08a1a363bae 100644 --- a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/CreateHiddenTasksAndCases/CreateHiddenTasksAndCasesProcess.p.json +++ b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/CreateHiddenTasksAndCases/CreateHiddenTasksAndCasesProcess.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "167BAF785E543C28", "kind" : "HTML_DIALOG", "config" : { diff --git a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/CreateMultipleTestUsers/CreateMultipleTestUsersData.d.json b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/CreateMultipleTestUsers/CreateMultipleTestUsersData.d.json index a1f107c99fd..5cb1f7ebdc2 100644 --- a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/CreateMultipleTestUsers/CreateMultipleTestUsersData.d.json +++ b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/CreateMultipleTestUsers/CreateMultipleTestUsersData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "CreateMultipleTestUsersData", "namespace" : "ch.ivy.addon.portalkit.test.CreateMultipleTestUsers", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/CreateMultipleTestUsers/CreateMultipleTestUsersProcess.p.json b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/CreateMultipleTestUsers/CreateMultipleTestUsersProcess.p.json index db353828c9d..a6b76ae87fe 100644 --- a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/CreateMultipleTestUsers/CreateMultipleTestUsersProcess.p.json +++ b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/CreateMultipleTestUsers/CreateMultipleTestUsersProcess.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "167A72C8DB0B15A6", "kind" : "HTML_DIALOG", "config" : { diff --git a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/DataCreation/DataCreation.xhtml b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/DataCreation/DataCreation.xhtml index 9fb09525011..b55830140b8 100644 --- a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/DataCreation/DataCreation.xhtml +++ b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/DataCreation/DataCreation.xhtml @@ -1,25 +1,37 @@ - -

Create tasks

- - - - - - - - - - - - - - - - + + Create tasks + + +
+ + + + + + + + + + + + + + +
+
+ +
+
- \ No newline at end of file + + diff --git a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/DataCreation/DataCreationData.d.json b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/DataCreation/DataCreationData.d.json index cd4f561ebd2..c2b4fd27c78 100644 --- a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/DataCreation/DataCreationData.d.json +++ b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/DataCreation/DataCreationData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "DataCreationData", "namespace" : "ch.ivy.addon.portalkit.test.DataCreation", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/DataCreation/DataCreationProcess.p.json b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/DataCreation/DataCreationProcess.p.json index 304761867bd..8dc343b74c3 100644 --- a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/DataCreation/DataCreationProcess.p.json +++ b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/DataCreation/DataCreationProcess.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "153CBA4AE9F19221", "kind" : "HTML_DIALOG", "config" : { diff --git a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/DefaultDialog/DefaultDialogData.d.json b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/DefaultDialog/DefaultDialogData.d.json index 7b64ff69cc1..22f2be8fd1e 100644 --- a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/DefaultDialog/DefaultDialogData.d.json +++ b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/DefaultDialog/DefaultDialogData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "DefaultDialogData", "namespace" : "ch.ivy.addon.portalkit.test.DefaultDialog", "isBusinessCaseData" : false diff --git a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/DefaultDialog/DefaultDialogProcess.p.json b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/DefaultDialog/DefaultDialogProcess.p.json index 0ca80bb95b8..7baf4a21b83 100644 --- a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/DefaultDialog/DefaultDialogProcess.p.json +++ b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/DefaultDialog/DefaultDialogProcess.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "1622D86CE0C61E23", "kind" : "HTML_DIALOG", "config" : { diff --git a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/GrantOrDenySpecificPermission/GrantOrDenySpecificPermissionData.d.json b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/GrantOrDenySpecificPermission/GrantOrDenySpecificPermissionData.d.json index 99ecbb21dd2..36dc6784924 100644 --- a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/GrantOrDenySpecificPermission/GrantOrDenySpecificPermissionData.d.json +++ b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/GrantOrDenySpecificPermission/GrantOrDenySpecificPermissionData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "GrantOrDenySpecificPermissionData", "namespace" : "ch.ivy.addon.portalkit.test.GrantOrDenySpecificPermission", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/GrantOrDenySpecificPermission/GrantOrDenySpecificPermissionProcess.p.json b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/GrantOrDenySpecificPermission/GrantOrDenySpecificPermissionProcess.p.json index 9abeee33a17..ffb1701bd05 100644 --- a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/GrantOrDenySpecificPermission/GrantOrDenySpecificPermissionProcess.p.json +++ b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/GrantOrDenySpecificPermission/GrantOrDenySpecificPermissionProcess.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "168DF9B20193A93C", "kind" : "HTML_DIALOG", "config" : { diff --git a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/HideOrUnHideTaskCase/HideOrUnHideTaskCaseData.d.json b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/HideOrUnHideTaskCase/HideOrUnHideTaskCaseData.d.json index 854698e76a3..fa334e8df15 100644 --- a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/HideOrUnHideTaskCase/HideOrUnHideTaskCaseData.d.json +++ b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/HideOrUnHideTaskCase/HideOrUnHideTaskCaseData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "HideOrUnHideTaskCaseData", "namespace" : "ch.ivy.addon.portalkit.test.HideOrUnHideTaskCase", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/HideOrUnHideTaskCase/HideOrUnHideTaskCaseProcess.p.json b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/HideOrUnHideTaskCase/HideOrUnHideTaskCaseProcess.p.json index 581890a1e51..6195a25ec91 100644 --- a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/HideOrUnHideTaskCase/HideOrUnHideTaskCaseProcess.p.json +++ b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/HideOrUnHideTaskCase/HideOrUnHideTaskCaseProcess.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "169137A20654C01B", "kind" : "HTML_DIALOG", "config" : { diff --git a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/PortalCustomErrorHandler/PortalCustomErrorHandlerData.d.json b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/PortalCustomErrorHandler/PortalCustomErrorHandlerData.d.json index e0b9a2d6ed5..65b469e188b 100644 --- a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/PortalCustomErrorHandler/PortalCustomErrorHandlerData.d.json +++ b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/PortalCustomErrorHandler/PortalCustomErrorHandlerData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "PortalCustomErrorHandlerData", "namespace" : "ch.ivy.addon.portalkit.test.PortalCustomErrorHandler", "isBusinessCaseData" : false diff --git a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/PortalCustomErrorHandler/PortalCustomErrorHandlerProcess.p.json b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/PortalCustomErrorHandler/PortalCustomErrorHandlerProcess.p.json index b4c2b1628be..2c93d2785fe 100644 --- a/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/PortalCustomErrorHandler/PortalCustomErrorHandlerProcess.p.json +++ b/AxonIvyPortal/PortalKitTestHelper/src_hd/ch/ivy/addon/portalkit/test/PortalCustomErrorHandler/PortalCustomErrorHandlerProcess.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "18DC0AD8321B5FC8", "kind" : "HTML_DIALOG", "config" : { diff --git a/AxonIvyPortal/PortalKitTestHelper/webContent/layouts/OneComponent.xhtml b/AxonIvyPortal/PortalKitTestHelper/webContent/layouts/OneComponent.xhtml index d3580d9ba05..38adbe5ed6c 100644 --- a/AxonIvyPortal/PortalKitTestHelper/webContent/layouts/OneComponent.xhtml +++ b/AxonIvyPortal/PortalKitTestHelper/webContent/layouts/OneComponent.xhtml @@ -9,7 +9,7 @@ - + Portalkit component diff --git a/AxonIvyPortal/PortalKitTestHelper/webContent/layouts/basic.xhtml b/AxonIvyPortal/PortalKitTestHelper/webContent/layouts/basic.xhtml index cf13511b499..997d46a3fab 100644 --- a/AxonIvyPortal/PortalKitTestHelper/webContent/layouts/basic.xhtml +++ b/AxonIvyPortal/PortalKitTestHelper/webContent/layouts/basic.xhtml @@ -14,7 +14,7 @@ - + <ui:insert name="title">Axon Ivy Portal</ui:insert> diff --git a/AxonIvyPortal/PortalKitTestHelper/webContent/layouts/frame-10.xhtml b/AxonIvyPortal/PortalKitTestHelper/webContent/layouts/frame-10.xhtml new file mode 100644 index 00000000000..4f33eb13ed2 --- /dev/null +++ b/AxonIvyPortal/PortalKitTestHelper/webContent/layouts/frame-10.xhtml @@ -0,0 +1,60 @@ + + + + + + + + + + <ui:insert name="title">Ivy Html Dialog</ui:insert> + + + + + + + + + +
+ + default content + +
+ + + + + + + +
+ diff --git a/AxonIvyPortal/PortalKitTestHelper/webContent/layouts/includes/exception.xhtml b/AxonIvyPortal/PortalKitTestHelper/webContent/layouts/includes/exception.xhtml index 2303e7c1732..dc3f5d44b1b 100644 --- a/AxonIvyPortal/PortalKitTestHelper/webContent/layouts/includes/exception.xhtml +++ b/AxonIvyPortal/PortalKitTestHelper/webContent/layouts/includes/exception.xhtml @@ -9,10 +9,11 @@ + + onexception="parent.PF && parent.PF('portal-view-expired-exception-dialog') ? parent.PF('portal-view-expired-exception-dialog').show() : PF('viewExpiredExceptionDialog').show()" /> '. # Variables: - #myVariable: value \ No newline at end of file diff --git a/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/DeleteDocumentItemData.d.json b/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/DeleteDocumentItemData.d.json index 312c6593b80..37a238111bc 100644 --- a/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/DeleteDocumentItemData.d.json +++ b/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/DeleteDocumentItemData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "DeleteDocumentItemData", "namespace" : "com.axonivy.portal.components", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/DownloadDocumentItemData.d.json b/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/DownloadDocumentItemData.d.json index fed7bcc6f0c..49a8ecba466 100644 --- a/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/DownloadDocumentItemData.d.json +++ b/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/DownloadDocumentItemData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "DownloadDocumentItemData", "namespace" : "com.axonivy.portal.components", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/ErrorHandlerData.d.json b/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/ErrorHandlerData.d.json index 214bf33cd43..d936cecc546 100644 --- a/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/ErrorHandlerData.d.json +++ b/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/ErrorHandlerData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "ErrorHandlerData", "namespace" : "com.axonivy.portal.components", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/GetDocumentItemsData.d.json b/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/GetDocumentItemsData.d.json index 9614961ee99..f088ba49ac8 100644 --- a/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/GetDocumentItemsData.d.json +++ b/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/GetDocumentItemsData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "GetDocumentItemsData", "namespace" : "com.axonivy.portal.components", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/OpenCaseDetailsHookData.d.json b/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/OpenCaseDetailsHookData.d.json index 541e6bb81c1..caf754ff242 100644 --- a/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/OpenCaseDetailsHookData.d.json +++ b/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/OpenCaseDetailsHookData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "OpenCaseDetailsHookData", "namespace" : "com.axonivy.portal.components", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/SetBusinessDetailsPageData.d.json b/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/SetBusinessDetailsPageData.d.json index bc1ce77e073..f32446b6819 100644 --- a/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/SetBusinessDetailsPageData.d.json +++ b/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/SetBusinessDetailsPageData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "SetBusinessDetailsPageData", "namespace" : "com.axonivy.portal.components", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/SetCaseBusinessEntityData.d.json b/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/SetCaseBusinessEntityData.d.json index 88d6cbbd4fe..8a6d0c945d5 100644 --- a/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/SetCaseBusinessEntityData.d.json +++ b/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/SetCaseBusinessEntityData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "SetCaseBusinessEntityData", "namespace" : "com.axonivy.portal.components", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/UploadDocumentItemCheckerData.d.json b/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/UploadDocumentItemCheckerData.d.json index 6e6503dcf9d..317f5df337e 100644 --- a/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/UploadDocumentItemCheckerData.d.json +++ b/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/UploadDocumentItemCheckerData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "UploadDocumentItemCheckerData", "namespace" : "com.axonivy.portal.components", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/UploadDocumentItemData.d.json b/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/UploadDocumentItemData.d.json index 0f6a1c47d39..397a9493e2c 100644 --- a/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/UploadDocumentItemData.d.json +++ b/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/UploadDocumentItemData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "UploadDocumentItemData", "namespace" : "com.axonivy.portal.components", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/service/PortalComponentSecurityServiceData.d.json b/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/service/PortalComponentSecurityServiceData.d.json index be6cc94a6b4..5908c21d0ec 100644 --- a/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/service/PortalComponentSecurityServiceData.d.json +++ b/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/service/PortalComponentSecurityServiceData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "PortalComponentSecurityServiceData", "namespace" : "com.axonivy.portal.components.service", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/service/PortalConponentCaseServiceData.d.json b/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/service/PortalConponentCaseServiceData.d.json index a5add99197e..ed517bd8202 100644 --- a/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/service/PortalConponentCaseServiceData.d.json +++ b/AxonIvyPortal/portal-components/dataclasses/com/axonivy/portal/components/service/PortalConponentCaseServiceData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "PortalConponentCaseServiceData", "namespace" : "com.axonivy.portal.components.service", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal-components/jar.xml b/AxonIvyPortal/portal-components/jar.xml new file mode 100644 index 00000000000..b0e863ac7de --- /dev/null +++ b/AxonIvyPortal/portal-components/jar.xml @@ -0,0 +1,18 @@ + + jar + false + + + jar + + + + + ./target/classes + + META-INF/ + + + + + diff --git a/AxonIvyPortal/portal-components/pom.xml b/AxonIvyPortal/portal-components/pom.xml index 139eb783612..50204f3e8b6 100644 --- a/AxonIvyPortal/portal-components/pom.xml +++ b/AxonIvyPortal/portal-components/pom.xml @@ -52,6 +52,7 @@ + src com.axonivy.ivy.ci @@ -62,6 +63,37 @@ false + + maven-assembly-plugin + 3.4.2 + + + make-assembly + package + + single + + + false + + jar.xml + + + + + + + maven-source-plugin + 3.3.0 + + + attach-sources + + jar-no-fork + + + + \ No newline at end of file diff --git a/AxonIvyPortal/portal-components/processes/Functional Processes/DeleteDocumentItem.p.json b/AxonIvyPortal/portal-components/processes/Functional Processes/DeleteDocumentItem.p.json index e133470f8fb..8a284e8bda7 100644 --- a/AxonIvyPortal/portal-components/processes/Functional Processes/DeleteDocumentItem.p.json +++ b/AxonIvyPortal/portal-components/processes/Functional Processes/DeleteDocumentItem.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "1818A90AC6618738", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal-components/processes/Functional Processes/DownloadDocumentItem.p.json b/AxonIvyPortal/portal-components/processes/Functional Processes/DownloadDocumentItem.p.json index 658a3925cb1..567a6d0955e 100644 --- a/AxonIvyPortal/portal-components/processes/Functional Processes/DownloadDocumentItem.p.json +++ b/AxonIvyPortal/portal-components/processes/Functional Processes/DownloadDocumentItem.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "180CC2A120F7FCC9", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal-components/processes/Functional Processes/GetDocumentItems.p.json b/AxonIvyPortal/portal-components/processes/Functional Processes/GetDocumentItems.p.json index 3008e24a8be..09a71c2332b 100644 --- a/AxonIvyPortal/portal-components/processes/Functional Processes/GetDocumentItems.p.json +++ b/AxonIvyPortal/portal-components/processes/Functional Processes/GetDocumentItems.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "180CBDED29C1D2F8", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal-components/processes/Functional Processes/OpenCaseDetailsHook.p.json b/AxonIvyPortal/portal-components/processes/Functional Processes/OpenCaseDetailsHook.p.json index 27ee5120182..e1fbd9d27b0 100644 --- a/AxonIvyPortal/portal-components/processes/Functional Processes/OpenCaseDetailsHook.p.json +++ b/AxonIvyPortal/portal-components/processes/Functional Processes/OpenCaseDetailsHook.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "1817143899CB5AEC", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal-components/processes/Functional Processes/PortalComponentErrorHandler.p.json b/AxonIvyPortal/portal-components/processes/Functional Processes/PortalComponentErrorHandler.p.json index 4977d3a0ec9..6e9839e8357 100644 --- a/AxonIvyPortal/portal-components/processes/Functional Processes/PortalComponentErrorHandler.p.json +++ b/AxonIvyPortal/portal-components/processes/Functional Processes/PortalComponentErrorHandler.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "18098C74EBB97195", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal-components/processes/Functional Processes/SetBusinessDetailsPage.p.json b/AxonIvyPortal/portal-components/processes/Functional Processes/SetBusinessDetailsPage.p.json index 3ba5e5da0aa..4d9712f4584 100644 --- a/AxonIvyPortal/portal-components/processes/Functional Processes/SetBusinessDetailsPage.p.json +++ b/AxonIvyPortal/portal-components/processes/Functional Processes/SetBusinessDetailsPage.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "1624CFE2532EF6BE", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal-components/processes/Functional Processes/SetCaseBusinessEntity.p.json b/AxonIvyPortal/portal-components/processes/Functional Processes/SetCaseBusinessEntity.p.json index dc33060405c..fc65599e35d 100644 --- a/AxonIvyPortal/portal-components/processes/Functional Processes/SetCaseBusinessEntity.p.json +++ b/AxonIvyPortal/portal-components/processes/Functional Processes/SetCaseBusinessEntity.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "161936E158EBC57F", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal-components/processes/Functional Processes/UploadDocumentItem.p.json b/AxonIvyPortal/portal-components/processes/Functional Processes/UploadDocumentItem.p.json index 9f549ed157a..97c03feee77 100644 --- a/AxonIvyPortal/portal-components/processes/Functional Processes/UploadDocumentItem.p.json +++ b/AxonIvyPortal/portal-components/processes/Functional Processes/UploadDocumentItem.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "180CC1E9248E252B", "kind" : "CALLABLE_SUB", "config" : { @@ -233,6 +233,8 @@ "config" : { "output" : { "code" : [ + "import com.axonivy.portal.components.jsf.ManagedBeans;", + "import com.axonivy.portal.components.bean.DocumentUploadBean;", "import com.axonivy.portal.components.masterdata.MasterData;", "import com.axonivy.portal.components.enums.UploadDocumentCheckStatus;", "import org.apache.commons.io.FileUtils;", @@ -248,10 +250,17 @@ " in.message = ivy.cms.co(\"/Dialogs/com/axonivy/portal/components/DocumentTable/EmptyFileMessage\");", " in.status = UploadDocumentCheckStatus.FAIL;", "} else {", + " DocumentUploadBean documentUploadBean = ManagedBeans.get(\"documentUploadBean\") as DocumentUploadBean;", " Long maxFileUploadSize = MasterData.getFileUploadSizeLimit();", + "", + " if(documentUploadBean != null) {", + " maxFileUploadSize = documentUploadBean.getFileUploadSizeLimit();", + " }", + " ", " if (in.uploadedFile.getSize() > maxFileUploadSize) {", " in.message = ivy.cms.co(\"/Dialogs/com/axonivy/portal/components/DocumentTable/ErrorFileUploadSize\", Arrays.asList(FileUtils.byteCountToDisplaySize(maxFileUploadSize)));", " }", + " ", " in.status = UploadDocumentCheckStatus.FAIL;", "}" ] diff --git a/AxonIvyPortal/portal-components/processes/Functional Processes/UploadDocumentItemChecker.p.json b/AxonIvyPortal/portal-components/processes/Functional Processes/UploadDocumentItemChecker.p.json index d52a452fb25..fd8f8185b21 100644 --- a/AxonIvyPortal/portal-components/processes/Functional Processes/UploadDocumentItemChecker.p.json +++ b/AxonIvyPortal/portal-components/processes/Functional Processes/UploadDocumentItemChecker.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "180CC29030DF7407", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal-components/processes/Ivy Data Processes/PortalComponentCaseService.p.json b/AxonIvyPortal/portal-components/processes/Ivy Data Processes/PortalComponentCaseService.p.json index 7a7d3a5c6ab..5978be98d9f 100644 --- a/AxonIvyPortal/portal-components/processes/Ivy Data Processes/PortalComponentCaseService.p.json +++ b/AxonIvyPortal/portal-components/processes/Ivy Data Processes/PortalComponentCaseService.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "18104AE3EB4807A1", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal-components/processes/Ivy Data Processes/PortalComponentSecurityService.p.json b/AxonIvyPortal/portal-components/processes/Ivy Data Processes/PortalComponentSecurityService.p.json index 2ac0228fcca..24b05872126 100644 --- a/AxonIvyPortal/portal-components/processes/Ivy Data Processes/PortalComponentSecurityService.p.json +++ b/AxonIvyPortal/portal-components/processes/Ivy Data Processes/PortalComponentSecurityService.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "18098B8A2F5FCF38", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/bean/DocumentUploadBean.java b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/bean/DocumentUploadBean.java index 43f1bc38bdc..38b254bdbc8 100644 --- a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/bean/DocumentUploadBean.java +++ b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/bean/DocumentUploadBean.java @@ -22,13 +22,15 @@ public class DocumentUploadBean implements Serializable { private static final long serialVersionUID = 1L; + private Long customFileSizeLimit; + public Long getFileUploadSizeLimit() { - return MasterData.getFileUploadSizeLimit(); + return (customFileSizeLimit != null && customFileSizeLimit > 0) ? customFileSizeLimit : MasterData.getFileUploadSizeLimit(); } - public String getFileUploadInvalidSizeMessage() { + public String getFileUploadInvalidSizeMessage(Long fileUploadSizeLimit) { return Ivy.cms().co("/Dialogs/com/axonivy/portal/components/DocumentTable/ErrorFileUploadSize", - Arrays.asList(FileUtils.byteCountToDisplaySize(getFileUploadSizeLimit()))); + Arrays.asList(FileUtils.byteCountToDisplaySize(fileUploadSizeLimit))); } public DocumentType[] getDocumentTypes() { @@ -46,4 +48,12 @@ public boolean getPortalVirusScannerSettingOrDefault(boolean defaultIfEmpty) { public String getPortalAllowedUploadFileTypesSettingOrDefault(String defaultIfEmpty) { return GlobalSettingService.getInstance().findGlobalSettingValueAsString(GlobalVariable.UPLOAD_DOCUMENT_WHITELIST_EXTENSION, defaultIfEmpty); } + + public Long getCustomFileSizeLimit() { + return customFileSizeLimit; + } + + public void setCustomFileSizeLimit(Long customFileSizeLimit) { + this.customFileSizeLimit = customFileSizeLimit; + } } diff --git a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/bean/HtmlSanitizerBean.java b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/bean/HtmlSanitizerBean.java index bce0a4c839e..dbd97f77e90 100644 --- a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/bean/HtmlSanitizerBean.java +++ b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/bean/HtmlSanitizerBean.java @@ -24,6 +24,8 @@ public String sanitize(String content) { /** * This method is used to clearly mark XSS is considered. + * @param content + * @return santized content */ public String sanitizeIgnoredWithAwareness(String content) { return content; diff --git a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/bean/PortalComponentDisplayNameFormatBean.java b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/bean/PortalComponentDisplayNameFormatBean.java index 21c6a449c98..5f42ea11499 100644 --- a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/bean/PortalComponentDisplayNameFormatBean.java +++ b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/bean/PortalComponentDisplayNameFormatBean.java @@ -5,9 +5,11 @@ import javax.faces.bean.ApplicationScoped; import javax.faces.bean.ManagedBean; +import com.axonivy.portal.components.dto.SecurityMemberDTO; import com.axonivy.portal.components.dto.UserDTO; import com.axonivy.portal.components.util.SecurityMemberDisplayNameUtils; +import ch.ivyteam.ivy.environment.Ivy; import ch.ivyteam.ivy.security.ISecurityMember; @ManagedBean @@ -19,6 +21,15 @@ public String generateBriefDisplayNameForSecurityMember(ISecurityMember member, return SecurityMemberDisplayNameUtils.generateBriefDisplayNameForSecurityMember(member, securityMemberName); } + public String generateBriefDisplayNameForSecurityMember( + SecurityMemberDTO memberDTO) { + ISecurityMember member = Ivy.security().members() + .findById(memberDTO.getSecurityMemberId()); + return SecurityMemberDisplayNameUtils + .generateBriefDisplayNameForSecurityMember(member, + member.getMemberName()); + } + public String getDisplayNameForUserDTO(UserDTO user) { return SecurityMemberDisplayNameUtils.generateDisplayNameForUserDTO(user); } diff --git a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/bean/ProcessViewerBean.java b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/bean/ProcessViewerBean.java index 3b31d0be6c9..4a59964f6d2 100644 --- a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/bean/ProcessViewerBean.java +++ b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/bean/ProcessViewerBean.java @@ -11,7 +11,7 @@ public class ProcessViewerBean implements Serializable { private static final long serialVersionUID = 3619473738758338192L; - public static String getProcessTypeDisplayName(String processType) { + public String getProcessTypeDisplayName(String processType) { ProcessType type = ProcessType.typeOf(processType); return type != null ? type.getLabel() : processType; } diff --git a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/dto/AiResultDTO.java b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/dto/AiResultDTO.java new file mode 100644 index 00000000000..8121b27ff9d --- /dev/null +++ b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/dto/AiResultDTO.java @@ -0,0 +1,33 @@ +package com.axonivy.portal.components.dto; + +import com.axonivy.portal.components.enums.AIState; + +public class AiResultDTO { + private String result; + private String resultForAI; + private AIState state; + + public String getResult() { + return result; + } + + public void setResult(String result) { + this.result = result; + } + + public String getResultForAI() { + return resultForAI; + } + + public void setResultForAI(String resultForAI) { + this.resultForAI = resultForAI; + } + + public AIState getState() { + return state; + } + + public void setState(AIState state) { + this.state = state; + } +} diff --git a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/enums/AIState.java b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/enums/AIState.java new file mode 100644 index 00000000000..e84505954a1 --- /dev/null +++ b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/enums/AIState.java @@ -0,0 +1,12 @@ +package com.axonivy.portal.components.enums; + +import com.fasterxml.jackson.annotation.JsonValue; + +public enum AIState { + OPEN, IN_PROGRESS, DONE, ERROR, TRIGGER; + + @JsonValue + public String value() { + return this.name().toLowerCase(); + } +} diff --git a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/enums/SessionAttribute.java b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/enums/SessionAttribute.java index bc66771f809..747951fb425 100644 --- a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/enums/SessionAttribute.java +++ b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/enums/SessionAttribute.java @@ -10,5 +10,5 @@ public enum SessionAttribute { HELP_URL_LINK, PORTAL_IN_TEAMS, DEFAULT_PAGE_IN_TEAMS, - SELECTED_DASHBOARD_ID; + SELECTED_SUB_DASHBOARD_ID; } \ No newline at end of file diff --git a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/ivydata/bo/JsonVersion.java b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/ivydata/bo/JsonVersion.java index c5b79675b9a..41f2b12c747 100644 --- a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/ivydata/bo/JsonVersion.java +++ b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/ivydata/bo/JsonVersion.java @@ -5,7 +5,7 @@ import org.apache.commons.lang3.StringUtils; public class JsonVersion implements Comparable { - public static final JsonVersion LATEST = new JsonVersion("10.0.0"); + public static final JsonVersion LATEST = new JsonVersion("12.0.0"); private String value; diff --git a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/ivydata/service/impl/SecurityService.java b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/ivydata/service/impl/SecurityService.java index 3d93369a347..7509bf5fbb8 100644 --- a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/ivydata/service/impl/SecurityService.java +++ b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/ivydata/service/impl/SecurityService.java @@ -51,7 +51,9 @@ private List queryUsers(String query, int startIndex, int count, List fromRoles) { } } + if (CollectionUtils.isEmpty(roles)) { + return null; + } + UserQuery hasRolesQuery = UserQuery.create(); IFilterQuery hasRolesFilter = hasRolesQuery.where(); for (IRole role : roles) { diff --git a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/persistence/converter/BusinessEntityConverter.java b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/persistence/converter/BusinessEntityConverter.java index c43656cc909..12dbaea5c94 100644 --- a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/persistence/converter/BusinessEntityConverter.java +++ b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/persistence/converter/BusinessEntityConverter.java @@ -10,6 +10,7 @@ import com.axonivy.portal.components.service.exception.PortalException; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; /** @@ -17,51 +18,70 @@ * and reverse */ public final class BusinessEntityConverter { - public static ObjectMapper objectMapper; + public static ObjectMapper objectMapper; - private BusinessEntityConverter() { - } + private BusinessEntityConverter() { + } - public static String entityToJsonValue(BusinessEntity entity) { - try { - return getObjectMapper().writeValueAsString(entity); - } catch (JsonProcessingException e) { - throw new PortalException(e); - } - } + public static String entityToJsonValue(BusinessEntity entity) { + try { + return getObjectMapper().writeValueAsString(entity); + } catch (JsonProcessingException e) { + throw new PortalException(e); + } + } - public static T jsonValueToEntity(String jsonValue, Class classType) { - try { - return getObjectMapper().readValue(jsonValue, classType); - } catch (IOException e) { - throw new PortalException(e); - } - } + public static T jsonValueToEntity(String jsonValue, Class classType) { + try { + return getObjectMapper().readValue(jsonValue, classType); + } catch (IOException e) { + throw new PortalException(e); + } + } - public static String entityToJsonValue(Object entity) { - try { - return getObjectMapper().writeValueAsString(entity); - } catch (JsonProcessingException e) { - throw new PortalException(e); - } - } + public static String entityToJsonValue(Object entity) { + try { + return getObjectMapper().writeValueAsString(entity); + } catch (JsonProcessingException e) { + throw new PortalException(e); + } + } - public static List jsonValueToEntities(String jsonValue, Class classType) { - if (StringUtils.isBlank(jsonValue)) { - return new ArrayList<>(); - } - try { - return getObjectMapper().readValue(jsonValue, - getObjectMapper().getTypeFactory().constructCollectionType(List.class, classType)); - } catch (IOException e) { - throw new PortalException(e); - } - } + public static JsonNode entityToJsonNode(Object entity) { + try { + return getObjectMapper().readTree(entityToJsonValue(entity)); + } catch (JsonProcessingException e) { + throw new PortalException(e); + } + } - public static ObjectMapper getObjectMapper() { - if (objectMapper == null) { - objectMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - } - return objectMapper; - } + public static List jsonValueToEntities(String jsonValue, + Class classType) { + if (StringUtils.isBlank(jsonValue)) { + return new ArrayList<>(); + } + try { + return getObjectMapper().readValue(jsonValue, getObjectMapper() + .getTypeFactory().constructCollectionType(List.class, classType)); + } catch (IOException e) { + throw new PortalException(e); + } + } + + public static ObjectMapper getObjectMapper() { + if (objectMapper == null) { + objectMapper = new ObjectMapper() + .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + } + return objectMapper; + } + + public static String prettyPrintEntityToJsonValue(Object entity) { + try { + return getObjectMapper().writerWithDefaultPrettyPrinter() + .writeValueAsString(entity); + } catch (JsonProcessingException e) { + throw new PortalException(e); + } + } } diff --git a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/publicapi/AiAssistantAPI.java b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/publicapi/AiAssistantAPI.java new file mode 100644 index 00000000000..fd7fa4a7eb6 --- /dev/null +++ b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/publicapi/AiAssistantAPI.java @@ -0,0 +1,70 @@ +package com.axonivy.portal.components.publicapi; + +import java.util.Map; + +import org.apache.commons.lang3.StringUtils; + +import com.axonivy.portal.components.dto.AiResultDTO; +import com.axonivy.portal.components.enums.AIState; +import com.axonivy.portal.components.service.impl.ProcessService; + +import ch.ivyteam.ivy.environment.Ivy; +import ch.ivyteam.ivy.workflow.start.IWebStartable; +import ch.ivyteam.util.ExceptionUtil; + +public class AiAssistantAPI { + private static final String IFRAME_RESULT_PATTERN = ""; + private static final String EXECUTE_RESULT_PATTERN = "%s"; + + public static void addIframeIvyProcessLinkToAiResult(String link, + Map params, AiResultDTO result) { + try { + IWebStartable process = initWebStartable(link); + result.setResult(String.format(IFRAME_RESULT_PATTERN, + process.getLink().queryParams(params).getRelative())); + } catch (Exception e) { + result = generateErrorAiResult(e, + Ivy.cms().co("/Labels/AI/Error/ErrorWhenProceedRequest")); + } + } + + public static String generateExecutableResult(String link) { + return String.format(EXECUTE_RESULT_PATTERN, link); + } + + private static IWebStartable initWebStartable(String processPath) { + if (StringUtils.isBlank(processPath)) { + return null; + } + + return ProcessService.getInstance().findAllProcesses().stream() + .filter(process -> process.getId().contentEquals(processPath)) + .findFirst().orElse(null); + } + + public static AiResultDTO generateErrorAiResult(Throwable error, + String errorDescription) { + AiResultDTO result = new AiResultDTO(); + result.setResult(errorDescription.concat(StringUtils.LF) + .concat(ExceptionUtil.getAllMessages(error))); + result.setState(AIState.ERROR); + + return result; + } + + public static AiResultDTO generateErrorAiResult(String error) { + AiResultDTO result = new AiResultDTO(); + result.setResult(error); + result.setResultForAI(error); + result.setState(AIState.ERROR); + + return result; + } + + public static AiResultDTO createSomethingWentWrongError() { + AiResultDTO result = new AiResultDTO(); + result.setResult(Ivy.cms().co("/Labels/AI/Error/SomethingWentWrong")); + result.setState(AIState.ERROR); + return result; + } +} diff --git a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/publicapi/ProcessStartAPI.java b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/publicapi/ProcessStartAPI.java index 3d7af55a2d5..b6dc4965f01 100644 --- a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/publicapi/ProcessStartAPI.java +++ b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/publicapi/ProcessStartAPI.java @@ -38,8 +38,7 @@ private ProcessStartAPI() { */ public static String findStartableLinkByUserFriendlyRequestPath(String friendlyRequestPath) { return Sudo.get(() -> { - List applicationsInSecurityContext = IApplicationRepository.instance() - .allOf(ISecurityContext.current()); + List applicationsInSecurityContext = IApplicationRepository.of(ISecurityContext.current()).all(); for (IApplication app : applicationsInSecurityContext) { IProcessStart processStart = findStartableProcessStartByUserFriendlyRequestPath(friendlyRequestPath, app); diff --git a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/service/impl/ProcessService.java b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/service/impl/ProcessService.java index e7bceec617b..c9e1ec67938 100644 --- a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/service/impl/ProcessService.java +++ b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/service/impl/ProcessService.java @@ -10,7 +10,6 @@ import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; - import ch.ivyteam.ivy.environment.Ivy; import ch.ivyteam.ivy.security.exec.Sudo; import ch.ivyteam.ivy.workflow.IWorkflowSession; @@ -37,6 +36,14 @@ public List findProcesses() { }); } + public List findAllProcesses() { + return Sudo.get(() -> { + return Ivy.session().getAllStartables() + .filter(process -> isNotPortalHomeAndMSTeamsProcess(process)) + .collect(Collectors.toList()); + }); + } + private List findStartablesWithoutPortalHomeAndMSTeamsProcess(IWorkflowSession session) { return session.getStartables().stream().filter(process -> isNotPortalHomeAndMSTeamsProcess(process)) .collect(Collectors.toList()); @@ -55,4 +62,4 @@ public List findCustomDashboardProcesses() { private Predicate filterByCustomDashboardProcess() { return start -> BooleanUtils.toBoolean(start.customFields().value(IS_DASHBOARD_PROCESS)); } -} +} \ No newline at end of file diff --git a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/util/ProcessStartUtils.java b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/util/ProcessStartUtils.java index cd48dc9d640..ca14dcb1309 100644 --- a/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/util/ProcessStartUtils.java +++ b/AxonIvyPortal/portal-components/src/com/axonivy/portal/components/util/ProcessStartUtils.java @@ -38,8 +38,7 @@ public static IProcessStart findProcessStartByUserFriendlyRequestPath(String req return processStart; } - List applicationsInSecurityContext = - IApplicationRepository.instance().allOf(ISecurityContext.current()); + List applicationsInSecurityContext = IApplicationRepository.of(ISecurityContext.current()).all(); List processModels = applicationsInSecurityContext.stream() .map(IApplication::getProcessModelsSortedByName).flatMap(List::stream).collect(Collectors.toList()); @@ -78,7 +77,7 @@ public static String findFriendlyRequestPathContainsKeyword(String keyword, Obje if (portalStartPmvId == null) { return findFriendlyRequestPathContainsKeywordInPMV(keyword, Ivy.wfTask().getProcessModelVersion()); } else { - List applicationsInSecurityContext = IApplicationRepository.instance().allOf(ISecurityContext.current()); + List applicationsInSecurityContext = IApplicationRepository.of(ISecurityContext.current()).all(); for (IApplication app : applicationsInSecurityContext) { IProcessModelVersion findProcessModelVersion = app.findProcessModelVersion(portalStartPmvId); if (findProcessModelVersion != null) { diff --git a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/DocumentTable/DocumentTable.xhtml b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/DocumentTable/DocumentTable.xhtml index e34319fed05..17c2fdb4024 100644 --- a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/DocumentTable/DocumentTable.xhtml +++ b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/DocumentTable/DocumentTable.xhtml @@ -14,6 +14,7 @@ + @@ -43,7 +44,7 @@ - +
@@ -96,7 +97,7 @@ listener="#{logic.upload}" rendered="#{cc.attrs.uploadRendered}" update="document-table document-messages #{cc.attrs.updatedComponentAfterUploaded}" - invalidSizeMessage="#{documentUploadBean.getFileUploadInvalidSizeMessage()}" + invalidSizeMessage="#{documentUploadBean.getFileUploadInvalidSizeMessage(documentUploadBean.fileUploadSizeLimit)}" label="#{not empty cc.attrs.uploadText ? cc.attrs.uploadText : ivy.cms.co('/Dialogs/com/axonivy/portal/components/DocumentTable/Upload')}" cancelLabel="#{ivy.cms.co('/Dialogs/com/axonivy/portal/components/Common/Cancel')}" onstart="#{logic.setFileLimit(cc.attrs.fileLimit)}" sizeLimit="#{documentUploadBean.fileUploadSizeLimit}" diff --git a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/DocumentTable/DocumentTableData.d.json b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/DocumentTable/DocumentTableData.d.json index 903d67debe4..2f38a35f3b0 100644 --- a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/DocumentTable/DocumentTableData.d.json +++ b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/DocumentTable/DocumentTableData.d.json @@ -1,24 +1,21 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "DocumentTableData", "namespace" : "com.axonivy.portal.components.DocumentTable", "isBusinessCaseData" : false, "fields" : [ { "name" : "documents", - "type" : "java.util.List", - "modifiers" : [ "PERSISTENT" ] + "type" : "java.util.List" }, { "name" : "event", - "type" : "org.primefaces.event.FileUploadEvent", - "modifiers" : [ "PERSISTENT" ] + "type" : "org.primefaces.event.FileUploadEvent" }, { "name" : "fileLimit", "type" : "Integer", "modifiers" : [ "PERSISTENT" ] }, { "name" : "ivyCase", - "type" : "ch.ivyteam.ivy.workflow.ICase", - "modifiers" : [ "PERSISTENT" ] + "type" : "ch.ivyteam.ivy.workflow.ICase" }, { "name" : "message", "type" : "String", @@ -29,28 +26,23 @@ "modifiers" : [ "PERSISTENT" ] }, { "name" : "selectedDocument", - "type" : "com.axonivy.portal.components.ivydata.bo.IvyDocument", - "modifiers" : [ "PERSISTENT" ] + "type" : "com.axonivy.portal.components.ivydata.bo.IvyDocument" }, { "name" : "streamedContent", - "type" : "org.primefaces.model.StreamedContent", - "modifiers" : [ "PERSISTENT" ] + "type" : "org.primefaces.model.StreamedContent" }, { "name" : "typeColumnRendered", "type" : "Boolean", "modifiers" : [ "PERSISTENT" ] }, { "name" : "typeSelection", - "type" : "com.axonivy.portal.components.enums.DocumentType", - "modifiers" : [ "PERSISTENT" ] + "type" : "com.axonivy.portal.components.enums.DocumentType" }, { "name" : "uploadDocumentCheckStatus", - "type" : "com.axonivy.portal.components.enums.UploadDocumentCheckStatus", - "modifiers" : [ "PERSISTENT" ] + "type" : "com.axonivy.portal.components.enums.UploadDocumentCheckStatus" }, { "name" : "uploadedDocument", - "type" : "ch.ivyteam.ivy.workflow.document.IDocument", - "modifiers" : [ "PERSISTENT" ] + "type" : "ch.ivyteam.ivy.workflow.document.IDocument" }, { "name" : "enableVirusScannerForUploadedDocument", "type" : "Boolean", @@ -67,5 +59,9 @@ "name" : "uploadedFile", "type" : "org.primefaces.model.file.UploadedFile", "modifiers" : [ "PERSISTENT" ] + }, { + "name" : "sizeLimit", + "type" : "Long", + "modifiers" : [ "PERSISTENT" ] } ] } \ No newline at end of file diff --git a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/DocumentTable/DocumentTableProcess.p.json b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/DocumentTable/DocumentTableProcess.p.json index f51ac17eb5a..f79f8f358d4 100644 --- a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/DocumentTable/DocumentTableProcess.p.json +++ b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/DocumentTable/DocumentTableProcess.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "16B1B70EE89C4939", "kind" : "HTML_DIALOG", "config" : { @@ -446,7 +446,7 @@ }, { "id" : "f42", "type" : "HtmlDialogMethodStart", - "name" : "renderComponent(String,Boolean,DocumentType,Boolean,Boolean,String)", + "name" : "renderComponent(String,Boolean,DocumentType,Boolean,Boolean,String,Long)", "config" : { "signature" : "renderComponent", "input" : { @@ -456,13 +456,15 @@ { "name" : "selectedType", "type" : "com.axonivy.portal.components.enums.DocumentType", "desc" : "" }, { "name" : "enableScriptCheckingForUploadedDocument", "type" : "Boolean", "desc" : "" }, { "name" : "enableVirusScannerForUploadedDocument", "type" : "Boolean", "desc" : "" }, - { "name" : "allowedUploadFileTypes", "type" : "String", "desc" : "" } + { "name" : "allowedUploadFileTypes", "type" : "String", "desc" : "" }, + { "name" : "sizeLimit", "type" : "Long", "desc" : "" } ], "map" : { "out.allowedUploadFileTypes" : "param.allowedUploadFileTypes", "out.enableScriptCheckingForUploadedDocument" : "param.enableScriptCheckingForUploadedDocument", "out.enableVirusScannerForUploadedDocument" : "param.enableVirusScannerForUploadedDocument", "out.messageComponentId" : "param.messageComponentId", + "out.sizeLimit" : "param.sizeLimit", "out.typeColumnRendered" : "param.typeColumnRendered", "out.typeSelection" : "param.selectedType" } @@ -471,10 +473,10 @@ }, "visual" : { "at" : { "x" : 96, "y" : 192 }, - "labelOffset" : { "x" : 121, "y" : 37 } + "labelOffset" : { "x" : 123, "y" : 43 } }, "connect" : [ - { "id" : "f44", "to" : "f43" } + { "id" : "f44", "to" : "f15" } ] }, { "id" : "f43", @@ -500,5 +502,29 @@ "connect" : [ { "id" : "f14", "to" : "f51" } ] + }, { + "id" : "f15", + "type" : "Script", + "name" : "Set size limit into bean", + "config" : { + "output" : { + "code" : [ + "import com.axonivy.portal.components.jsf.ManagedBeans;", + "import com.axonivy.portal.components.bean.DocumentUploadBean;", + "", + "DocumentUploadBean documentUploadBean = ManagedBeans.get(\"documentUploadBean\") as DocumentUploadBean;", + "", + "if(documentUploadBean != null) {", + " documentUploadBean.setCustomFileSizeLimit(in.sizeLimit);", + "}" + ] + } + }, + "visual" : { + "at" : { "x" : 224, "y" : 192 } + }, + "connect" : [ + { "id" : "f17", "to" : "f43", "color" : "default" } + ] } ] } \ No newline at end of file diff --git a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/IFrameTaskConfig/IFrameTaskConfig.xhtml b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/IFrameTaskConfig/IFrameTaskConfig.xhtml new file mode 100644 index 00000000000..2b1ba460ec2 --- /dev/null +++ b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/IFrameTaskConfig/IFrameTaskConfig.xhtml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/IFrameTaskConfig/IFrameTaskConfigData.d.json b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/IFrameTaskConfig/IFrameTaskConfigData.d.json new file mode 100644 index 00000000000..603f9806fef --- /dev/null +++ b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/IFrameTaskConfig/IFrameTaskConfigData.d.json @@ -0,0 +1,6 @@ +{ + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", + "simpleName" : "IFrameTaskConfigData", + "namespace" : "com.axonivy.portal.components.IFrameTaskConfig", + "isBusinessCaseData" : false +} \ No newline at end of file diff --git a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/IFrameTaskConfig/IFrameTaskConfigProcess.p.json b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/IFrameTaskConfig/IFrameTaskConfigProcess.p.json new file mode 100644 index 00000000000..cd3641265c8 --- /dev/null +++ b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/IFrameTaskConfig/IFrameTaskConfigProcess.p.json @@ -0,0 +1,50 @@ +{ + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", + "id" : "19274BA8B8973F00", + "kind" : "HTML_DIALOG", + "config" : { + "data" : "com.axonivy.portal.components.IFrameTaskConfig.IFrameTaskConfigData" + }, + "elements" : [ { + "id" : "f0", + "type" : "HtmlDialogStart", + "name" : "start()", + "config" : { + "signature" : "start", + "guid" : "19274BA8B8C633D4" + }, + "visual" : { + "at" : { "x" : 96, "y" : 64 } + }, + "connect" : [ + { "id" : "f2", "to" : "f1" } + ] + }, { + "id" : "f1", + "type" : "HtmlDialogEnd", + "visual" : { + "at" : { "x" : 224, "y" : 64 }, + "labelOffset" : { "x" : 10, "y" : 30 } + } + }, { + "id" : "f3", + "type" : "HtmlDialogEventStart", + "name" : "close", + "config" : { + "guid" : "19274BA8B8F47AD0" + }, + "visual" : { + "at" : { "x" : 96, "y" : 160 } + }, + "connect" : [ + { "id" : "f5", "to" : "f4" } + ] + }, { + "id" : "f4", + "type" : "HtmlDialogExit", + "visual" : { + "at" : { "x" : 224, "y" : 160 }, + "labelOffset" : { "x" : 10, "y" : 30 } + } + } ] +} \ No newline at end of file diff --git a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/ProcessChain/ProcessChainData.d.json b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/ProcessChain/ProcessChainData.d.json index 830b3d5f519..f6bc0e4575e 100644 --- a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/ProcessChain/ProcessChainData.d.json +++ b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/ProcessChain/ProcessChainData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "ProcessChainData", "namespace" : "com.axonivy.portal.components.ProcessChain", "isBusinessCaseData" : false diff --git a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/ProcessChain/ProcessChainProcess.p.json b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/ProcessChain/ProcessChainProcess.p.json index f41b22d2aaa..8017809a696 100644 --- a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/ProcessChain/ProcessChainProcess.p.json +++ b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/ProcessChain/ProcessChainProcess.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "18118F75C3E2A5CF", "kind" : "HTML_DIALOG", "config" : { diff --git a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/ProcessHistory/ProcessHistoryData.d.json b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/ProcessHistory/ProcessHistoryData.d.json index 245ba276212..2ffc678cb44 100644 --- a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/ProcessHistory/ProcessHistoryData.d.json +++ b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/ProcessHistory/ProcessHistoryData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "ProcessHistoryData", "namespace" : "com.axonivy.portal.components.ProcessHistory", "isBusinessCaseData" : false, @@ -9,8 +9,7 @@ "modifiers" : [ "PERSISTENT" ] }, { "name" : "caze", - "type" : "ch.ivyteam.ivy.workflow.ICase", - "modifiers" : [ "PERSISTENT" ] + "type" : "ch.ivyteam.ivy.workflow.ICase" }, { "name" : "isOpenInFrame", "type" : "Boolean", diff --git a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/ProcessHistory/ProcessHistoryProcess.p.json b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/ProcessHistory/ProcessHistoryProcess.p.json index ee0c460300e..3f662e4acca 100644 --- a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/ProcessHistory/ProcessHistoryProcess.p.json +++ b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/ProcessHistory/ProcessHistoryProcess.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "180F979F5AF44684", "kind" : "HTML_DIALOG", "config" : { diff --git a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/ProcessViewer/ProcessViewerData.d.json b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/ProcessViewer/ProcessViewerData.d.json index 0ded87b0e71..0dccd670df1 100644 --- a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/ProcessViewer/ProcessViewerData.d.json +++ b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/ProcessViewer/ProcessViewerData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "ProcessViewerData", "namespace" : "com.axonivy.portal.components.ProcessViewer", "isBusinessCaseData" : false, @@ -21,20 +21,17 @@ "modifiers" : [ "PERSISTENT" ] }, { "name" : "webStartable", - "type" : "ch.ivyteam.ivy.workflow.start.IWebStartable", - "modifiers" : [ "PERSISTENT" ] + "type" : "ch.ivyteam.ivy.workflow.start.IWebStartable" }, { "name" : "webLink", - "type" : "ch.ivyteam.ivy.model.value.WebLink", - "modifiers" : [ "PERSISTENT" ] + "type" : "ch.ivyteam.ivy.model.value.WebLink" }, { "name" : "activatorName", "type" : "String", "modifiers" : [ "PERSISTENT" ] }, { "name" : "activator", - "type" : "ch.ivyteam.ivy.security.ISecurityMember", - "modifiers" : [ "PERSISTENT" ] + "type" : "ch.ivyteam.ivy.security.ISecurityMember" }, { "name" : "category", "type" : "String", diff --git a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/ProcessViewer/ProcessViewerProcess.p.json b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/ProcessViewer/ProcessViewerProcess.p.json index 4204b1a03d5..1bc84edb5d7 100644 --- a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/ProcessViewer/ProcessViewerProcess.p.json +++ b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/ProcessViewer/ProcessViewerProcess.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "181FC5E5ED6EAE2A", "kind" : "HTML_DIALOG", "config" : { diff --git a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/RoleSelection/RoleSelectionData.d.json b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/RoleSelection/RoleSelectionData.d.json index 44a6fc655d6..157f3f1c3da 100644 --- a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/RoleSelection/RoleSelectionData.d.json +++ b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/RoleSelection/RoleSelectionData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "RoleSelectionData", "namespace" : "com.axonivy.portal.components.RoleSelection", "isBusinessCaseData" : false diff --git a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/RoleSelection/RoleSelectionProcess.p.json b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/RoleSelection/RoleSelectionProcess.p.json index 22aa2d574dd..36eba44362a 100644 --- a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/RoleSelection/RoleSelectionProcess.p.json +++ b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/RoleSelection/RoleSelectionProcess.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "180B70D44ADA37B5", "kind" : "HTML_DIALOG", "config" : { diff --git a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/UserSelection/UserSelection.xhtml b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/UserSelection/UserSelection.xhtml index 312054815eb..cbeddf397d8 100644 --- a/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/UserSelection/UserSelection.xhtml +++ b/AxonIvyPortal/portal-components/src_hd/com/axonivy/portal/components/UserSelection/UserSelection.xhtml @@ -56,14 +56,19 @@ + styleClass="#{cc.attrs.labelPanelStyleClass} ui-g-6 pl-0"> + + + + styleClass="pl-0 user-selection-panel #{cc.attrs.autoCompletePanelStyleClass} #{cc.attrs.floatingLabel and ivyPrimefacesThemeResolver.sessionTheme.contains('serenity') ? 'md-inputfield' : ''} #{cc.attrs.floatingLabel and ivyPrimefacesThemeResolver.sessionTheme.contains('freya') ? 'ui-float-label' : ''}"> - - - but it will be sanitized.", - "HTML description could contain malicious script but it will be sanitized.", taskWidgetPage); - testChangeTaskDescription("", "No description", taskWidgetPage); + "HTML description could contain malicious script but it will be sanitized.", taskWidget); + testChangeTaskDescription("", "No description", taskWidget); testChangeTaskDescription("And you can change description if it is empty", - "And you can change description if it is empty", taskWidgetPage); + "And you can change description if it is empty", taskWidget); } private void testChangeTaskDescription(String newDescription, String shownDescriptionInDetails, - TaskWidgetPage taskWidgetPage) { + TopMenuTaskWidgetPage taskWidgetPage) { taskWidgetPage.changeDescriptionOfTask(newDescription); assertEquals(taskWidgetPage.getTaskDescription(), shownDescriptionInDetails); } @@ -49,17 +51,19 @@ private void testChangeTaskDescription(String newDescription, String shownDescri @Test public void testUserWithoutPermissionCannotChangeTaskName() { int firstTask = 0; - taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.openTaskDetails(firstTask); - assertFalse(taskWidgetPage.isTaskNameChangeComponentPresented(firstTask)); + NavigationHelper.navigateToTaskList(); + TopMenuTaskWidgetPage taskWidget = new TopMenuTaskWidgetPage(); + taskWidget.openTaskDetailsPageByAction(firstTask); + assertFalse(taskWidget.isTaskNameChangeComponentPresented(firstTask)); } public void changeLanguage(int index) { - UserProfilePage userProfilePage = taskWidgetPage.openMyProfilePage(); + NewDashboardPage taskList = NavigationHelper.navigateToTaskList(); + UserProfilePage userProfilePage = taskList.openMyProfilePage(); userProfilePage.selectLanguage(index); userProfilePage.save(); - taskWidgetPage = NavigationHelper.navigateToTaskList(); + NavigationHelper.navigateToTaskList(); } @AfterEach diff --git a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/task/TaskDetailsTest.java b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/task/TaskDetailsTest.java index 951810d7893..7e04c01af72 100644 --- a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/task/TaskDetailsTest.java +++ b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/task/TaskDetailsTest.java @@ -8,13 +8,15 @@ import com.axonivy.ivy.webtest.IvyWebTest; import com.axonivy.portal.selenium.common.BaseTest; -import com.axonivy.portal.selenium.common.TaskState; +import com.axonivy.portal.selenium.common.FilterOperator; +import com.axonivy.portal.selenium.common.FilterValueType; +import com.axonivy.portal.selenium.common.NavigationHelper; import com.axonivy.portal.selenium.common.TestAccount; import com.axonivy.portal.selenium.common.Variable; import com.axonivy.portal.selenium.page.CaseDetailsPage; import com.axonivy.portal.selenium.page.MainMenuPage; import com.axonivy.portal.selenium.page.TaskDetailsPage; -import com.axonivy.portal.selenium.page.TaskWidgetPage; +import com.axonivy.portal.selenium.page.TopMenuTaskWidgetPage; import com.codeborne.selenide.Condition; import ch.ivy.addon.portalkit.enums.PortalPermission; @@ -49,8 +51,8 @@ public void testVisibilityOfNotesWhenAddNoteOnTaskDetailsWithoutTechnicalCase() redirectToNewDashBoard(); MainMenuPage mainMenuPage = new MainMenuPage(); mainMenuPage.openTaskList(); - TaskWidgetPage taskWidgetPage = new TaskWidgetPage(); - taskWidgetPage.openTask(ORDER_PIZZA); + TopMenuTaskWidgetPage taskWidget = new TopMenuTaskWidgetPage(); + taskWidget.openDashboardTaskDetails(ORDER_PIZZA); TaskDetailsPage taskDetailsPage = new TaskDetailsPage(); taskDetailsPage.addNote(NOTE_TASK_DETAIL_BUSINESS_CASE); taskDetailsPage.getNotesWithContent(NOTE_TASK_DETAIL_BUSINESS_CASE).shouldHave(size(1)); @@ -67,8 +69,8 @@ public void testVisibilityOfNotesWhenAddNoteOnTaskDetailsWithTechnicalCase() { redirectToNewDashBoard(); MainMenuPage mainMenuPage = new MainMenuPage(); mainMenuPage.openTaskList(); - TaskWidgetPage taskWidgetPage = new TaskWidgetPage(); - taskWidgetPage.openTask(TAKE_ORDER); + TopMenuTaskWidgetPage taskWidget = new TopMenuTaskWidgetPage(); + taskWidget.openDashboardTaskDetails(TAKE_ORDER); TaskDetailsPage taskDetailsPage = new TaskDetailsPage(); taskDetailsPage.addNote(NOTE_TASK_DETAIL_TECHNICAL_CASE); taskDetailsPage.getNotesWithContent(NOTE_TASK_DETAIL_TECHNICAL_CASE).shouldHave(size(1)); @@ -88,8 +90,8 @@ public void testShareTaskDetails() { redirectToNewDashBoard(); MainMenuPage mainMenuPage = new MainMenuPage(); mainMenuPage.openTaskList(); - TaskWidgetPage taskWidgetPage = new TaskWidgetPage(); - taskWidgetPage.openTask(TAKE_ORDER); + TopMenuTaskWidgetPage taskWidget = new TopMenuTaskWidgetPage(); + taskWidget.openDashboardTaskDetails(TAKE_ORDER); TaskDetailsPage taskDetailsPage = new TaskDetailsPage(); taskDetailsPage.getShareButton().shouldBe(Condition.appear, DEFAULT_TIMEOUT).click(); taskDetailsPage.getShareDialog().shouldBe(Condition.appear, DEFAULT_TIMEOUT); @@ -97,7 +99,8 @@ public void testShareTaskDetails() { redirectToRelativeLink(denyShareLinkTaskDetailsPermission); redirectToNewDashBoard(); mainMenuPage.openTaskList(); - taskWidgetPage.openTask(TAKE_ORDER); + taskWidget = new TopMenuTaskWidgetPage(); + taskWidget.openDashboardTaskDetails(TAKE_ORDER); taskDetailsPage.getShareButton().shouldBe(Condition.disappear); } @@ -107,36 +110,45 @@ public void testShowTaskStatusBannerOnTaskDetails() { login(TestAccount.ADMIN_USER); grantSpecificPortalPermission(PortalPermission.SYSTEM_TASK_READ_ALL); redirectToNewDashBoard(); - MainMenuPage mainMenuPage = new MainMenuPage(); - mainMenuPage.openTaskList(); - TaskWidgetPage taskWidgetPage = new TaskWidgetPage(); + NavigationHelper.navigateToTaskList(); + TopMenuTaskWidgetPage taskWidget = new TopMenuTaskWidgetPage(); - taskWidgetPage.openTask("Maternity Leave Request"); + taskWidget.openDashboardTaskDetails("Maternity Leave Request"); TaskDetailsPage taskDetailsPage = new TaskDetailsPage(); taskDetailsPage.clickStartTask(); redirectToNewDashBoard(); - mainMenuPage.openTaskList(); - taskWidgetPage.openTask("Maternity Leave Request"); + + NavigationHelper.navigateToTaskList(); + taskWidget = new TopMenuTaskWidgetPage(); + taskWidget.openDashboardTaskDetails("Maternity Leave Request"); taskDetailsPage.getStatusBanner().shouldBe(Condition.appear, DEFAULT_TIMEOUT); - mainMenuPage.openTaskList(); - taskWidgetPage.filterTasksBy("Sick Leave Request"); - taskWidgetPage.waitTillNameOfFirstTaskToBe("Sick Leave Request"); - taskWidgetPage.isTaskDestroyEnabled(0); - taskWidgetPage.destroyTask(0); - taskWidgetPage.confimDestruction(); - taskWidgetPage.checkTaskState(0, TaskState.DESTROYED.getValue()); - taskWidgetPage.openTask("Sick Leave Request"); + NavigationHelper.navigateToTaskList(); + taskWidget = new TopMenuTaskWidgetPage(); + taskWidget.openFilterWidget(); + taskWidget.addFilter("Name", FilterOperator.IS); + taskWidget.inputValueOnLatestFilter(FilterValueType.TEXT, "Sick Leave Request"); + taskWidget.applyFilter(); + taskWidget.destroyTask(0); + taskWidget.openDashboardTaskDetails("Sick Leave Request"); taskDetailsPage.getStatusBanner().shouldBe(Condition.appear, DEFAULT_TIMEOUT); redirectToRelativeLink(createCaseWithTechnicalCaseUrl); - mainMenuPage.openTaskList(); - taskWidgetPage.filterTasksBy(TAKE_ORDER); - taskWidgetPage.waitTillNameOfFirstTaskToBe(TAKE_ORDER); - taskWidgetPage.startTaskWithoutUI(0); + NavigationHelper.navigateToTaskList(); + taskWidget = new TopMenuTaskWidgetPage(); + taskWidget.openFilterWidget(); + taskWidget.removeFilter(0); + taskWidget.addFilter("Name", FilterOperator.IS); + taskWidget.inputValueOnLatestFilter(FilterValueType.TEXT, TAKE_ORDER); + taskWidget.applyFilter(); + + taskWidget.startTask(0); redirectToNewDashBoard(); - mainMenuPage.openTaskList(); - taskWidgetPage.openTask(TAKE_ORDER); + NavigationHelper.navigateToTaskList(); + taskWidget.openFilterWidget(); + taskWidget.removeFilter(0); + taskWidget.applyFilter(); + taskWidget.openDashboardTaskDetails(TAKE_ORDER); taskDetailsPage.getStatusBanner().shouldBe(Condition.appear, DEFAULT_TIMEOUT); } } diff --git a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/task/TaskFilterTest.java b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/task/TaskFilterTest.java deleted file mode 100644 index da9ca2f0ae5..00000000000 --- a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/task/TaskFilterTest.java +++ /dev/null @@ -1,57 +0,0 @@ -package com.axonivy.portal.selenium.test.task; - -import java.text.SimpleDateFormat; -import java.util.Date; - -import org.junit.jupiter.api.Assertions; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -import com.axonivy.ivy.webtest.IvyWebTest; -import com.axonivy.portal.selenium.common.BaseTest; -import com.axonivy.portal.selenium.common.DateTimePattern; -import com.axonivy.portal.selenium.common.TestAccount; -import com.axonivy.portal.selenium.page.MainMenuPage; -import com.axonivy.portal.selenium.page.TaskWidgetPage; -import com.codeborne.selenide.CollectionCondition; - -@IvyWebTest -public class TaskFilterTest extends BaseTest { - - private static final String EMPTY = ""; - - @Override - @BeforeEach - public void setup() { - super.setup(); - } - - @Test - public void testFilterTasksByCreatedDate() { - TaskWidgetPage taskWidgetPage = createTestData(); - taskWidgetPage.openAdvancedFilter("Created (from/to)", "created"); - String fromInputText = new SimpleDateFormat(DateTimePattern.DATE_PATTERN).format(new Date()); - taskWidgetPage.filterTasksByCreatedDate(fromInputText, EMPTY); - taskWidgetPage.countTasks().shouldHave(CollectionCondition.sizeGreaterThanOrEqual(1)); - } - - @Test - public void testFilterTasksByApplication() { - TaskWidgetPage taskWidgetPage = createTestData(); - int before = taskWidgetPage.countTasks().size(); - taskWidgetPage.openAdvancedFilter("Application", "application"); - taskWidgetPage.filterFirstApp(); - int after = taskWidgetPage.countTasks().size(); - Assertions.assertEquals(before, after); - } - - private TaskWidgetPage createTestData() { - redirectToRelativeLink(createTestingTasksUrl); - login(TestAccount.ADMIN_USER); - MainMenuPage mainMenuPage = new MainMenuPage(); - mainMenuPage.waitForGrowlMessageDisappear(); - TaskWidgetPage taskWidgetPage = mainMenuPage.openTaskList(); - return taskWidgetPage; - } - -} diff --git a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/task/TaskPriorityChangeTest.java b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/task/TaskPriorityChangeTest.java index 6c22d485308..bef2e8f693b 100644 --- a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/task/TaskPriorityChangeTest.java +++ b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/task/TaskPriorityChangeTest.java @@ -9,7 +9,7 @@ import com.axonivy.portal.selenium.common.TestAccount; import com.axonivy.portal.selenium.common.Variable; import com.axonivy.portal.selenium.page.TaskDetailsPage; -import com.axonivy.portal.selenium.page.TaskWidgetPage; +import com.axonivy.portal.selenium.page.TopMenuTaskWidgetPage; @IvyWebTest public class TaskPriorityChangeTest extends BaseTest { @@ -28,8 +28,9 @@ public void testChangeTaskPriority() { int firstTask = 0; int priorityIntValue = 2; String priorityStringValue = "NORMAL"; - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - TaskDetailsPage taskDetailsPage = taskWidgetPage.openTaskDetails(firstTask); + NavigationHelper.navigateToTaskList(); + TopMenuTaskWidgetPage taskWidget = new TopMenuTaskWidgetPage(); + TaskDetailsPage taskDetailsPage = taskWidget.openTaskDetailsPageByAction(firstTask); taskDetailsPage.changePriorityOfTask(priorityIntValue); assertTrue(priorityStringValue.equals(taskDetailsPage.getPriorityOfTask().getText())); } @@ -37,9 +38,10 @@ public void testChangeTaskPriority() { @Test public void testUserWithoutPermissionCannotChangeTaskPriority() { int firstTask = 0; - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.openTaskDetails(firstTask); - assertFalse(taskWidgetPage.isTaskPriorityChangeComponentPresented(firstTask)); + NavigationHelper.navigateToTaskList(); + TopMenuTaskWidgetPage taskWidget = new TopMenuTaskWidgetPage(); + taskWidget.openTaskDetailsPageByAction(firstTask); + assertFalse(taskWidget.isTaskPriorityChangeComponentPresented(firstTask)); } } diff --git a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/task/TaskTemplateIFrameTest.java b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/task/TaskTemplateIFrameTest.java index d830db54676..91a6e673e7b 100644 --- a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/task/TaskTemplateIFrameTest.java +++ b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/task/TaskTemplateIFrameTest.java @@ -6,13 +6,15 @@ import com.axonivy.ivy.webtest.IvyWebTest; import com.axonivy.portal.selenium.common.BaseTest; +import com.axonivy.portal.selenium.common.FilterOperator; +import com.axonivy.portal.selenium.common.FilterValueType; import com.axonivy.portal.selenium.common.NavigationHelper; import com.axonivy.portal.selenium.common.Variable; import com.axonivy.portal.selenium.common.WaitHelper; import com.axonivy.portal.selenium.page.NewDashboardPage; import com.axonivy.portal.selenium.page.TaskIFrameTemplatePage; import com.axonivy.portal.selenium.page.TaskTemplatePage; -import com.axonivy.portal.selenium.page.TaskWidgetPage; +import com.axonivy.portal.selenium.page.TopMenuTaskWidgetPage; @IvyWebTest public class TaskTemplateIFrameTest extends BaseTest { @@ -31,9 +33,13 @@ public void setup() { @Test public void testCustomParamsForIFrameTaskTemplate() { redirectToRelativeLink(CUSTOM_PARAMS_TEMPLATE_TASK_URL); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.filterTasksInExpandedModeBy("IFrame task with custom params"); - TaskIFrameTemplatePage taskTemplatePage = taskWidgetPage.startTaskWithouWaitForTaskActionPresent(0); + NavigationHelper.navigateToTaskList(); + TopMenuTaskWidgetPage taskWidget = new TopMenuTaskWidgetPage(); + taskWidget.openFilterWidget(); + taskWidget.addFilter("Name", FilterOperator.IS); + taskWidget.inputValueOnLatestFilter(FilterValueType.TEXT, "IFrame task with custom params"); + taskWidget.applyFilter(); + TaskIFrameTemplatePage taskTemplatePage = taskWidget.startTaskIFrameByIndex(0); assertFalse(taskTemplatePage.isTaskNameDisplayed()); assertFalse(taskTemplatePage.isTaskActionDisplayed()); assertFalse(taskTemplatePage.isCaseInfoButtonDisplayed()); @@ -54,9 +60,13 @@ public void testNotDisplayWarningInIFrameTaskTemplate() { redirectToRelativeLink(IFRAME_TASK_URL); waitForTemplateRender(); TaskTemplatePage taskTemplatePage1 = new TaskTemplatePage(); - TaskWidgetPage taskWidgetPage = taskTemplatePage1.finishCreateInvestmentTask(); - taskWidgetPage.filterTasksInExpandedModeBy("Approve Investment", 1); - TaskIFrameTemplatePage taskTemplatePage2 = taskWidgetPage.startTaskIFrame(0); + taskTemplatePage1.finishCreateInvestmentTask(); + TopMenuTaskWidgetPage taskWidget = new TopMenuTaskWidgetPage(); + taskWidget.openFilterWidget(); + taskWidget.addFilter("Name", FilterOperator.CONTAINS); + taskWidget.inputValueOnLatestFilter(FilterValueType.TEXT, "Approve Investment"); + taskWidget.applyFilter(); + TaskIFrameTemplatePage taskTemplatePage2 = taskWidget.startTaskIFrameByIndex(0); taskTemplatePage2.clickOnLogo(); new NewDashboardPage(); } @@ -67,9 +77,13 @@ public void testRedirectToApplicationHome() { redirectToRelativeLink(IFRAME_TASK_URL); waitForTemplateRender(); TaskTemplatePage taskTemplatePage1 = new TaskTemplatePage(); - TaskWidgetPage taskWidgetPage = taskTemplatePage1.finishCreateInvestmentTask(); - taskWidgetPage.filterTasksInExpandedModeBy("Approve Investment", 1); - TaskIFrameTemplatePage taskTemplatePage2 = taskWidgetPage.startTaskIFrame(0); + taskTemplatePage1.finishCreateInvestmentTask(); + TopMenuTaskWidgetPage taskWidget = new TopMenuTaskWidgetPage(); + taskWidget.openFilterWidget(); + taskWidget.addFilter("Name", FilterOperator.CONTAINS); + taskWidget.inputValueOnLatestFilter(FilterValueType.TEXT, "Approve Investment"); + taskWidget.applyFilter(); + TaskIFrameTemplatePage taskTemplatePage2 = taskWidget.startTaskIFrameByIndex(0); taskTemplatePage2.backToHomeInIFrameApprovalTask(); new NewDashboardPage(); } @@ -79,13 +93,16 @@ public void testStickyTaskList() { redirectToRelativeLink(IFRAME_TASK_URL); waitForTemplateRender(); TaskTemplatePage taskTemplatePage1 = new TaskTemplatePage(); - TaskWidgetPage taskWidgetPage1 = taskTemplatePage1.finishCreateInvestmentTask(); - taskWidgetPage1 = taskWidgetPage1.openTaskList(); - taskWidgetPage1.filterTasksInExpandedModeBy("Approve Investment", 1); - TaskIFrameTemplatePage taskTemplatePage2 = taskWidgetPage1.startTaskIFrame(0); - TaskWidgetPage taskWidgetPage2 = taskTemplatePage2.finishIFrameReviewTask(); - WaitHelper - .assertTrueWithWait(() -> taskWidgetPage2.isElementDisplayed(By.cssSelector("[id$='task-config-command']"))); + taskTemplatePage1.finishCreateInvestmentTask(); + TopMenuTaskWidgetPage taskWidget = new TopMenuTaskWidgetPage(); + taskWidget.openFilterWidget(); + taskWidget.addFilter("Name", FilterOperator.CONTAINS); + taskWidget.inputValueOnLatestFilter(FilterValueType.TEXT, "Approve Investment"); + taskWidget.applyFilter(); + TaskIFrameTemplatePage taskTemplatePage2 = taskWidget.startTaskIFrameByIndex(0); + NewDashboardPage taskWidgetPage2 = taskTemplatePage2.finishIFrameReviewTask(); + WaitHelper.assertTrueWithWait(() -> taskWidgetPage2 + .isElementDisplayed(By.cssSelector("[id$='task-default_task_list_dashboard_task_1:info-sidebar-link-0']"))); } public void waitForTemplateRender() { @@ -97,10 +114,13 @@ public void testTextOutIFrameChangeWithSkipTaskList() { redirectToRelativeLink(IFRAME_TASK_URL); waitForTemplateRender(); TaskTemplatePage taskTemplatePage1 = new TaskTemplatePage(); - TaskWidgetPage taskWidgetPage1 = taskTemplatePage1.finishCreateInvestmentTask(); - taskWidgetPage1 = taskWidgetPage1.openTaskList(); - taskWidgetPage1.filterTasksInExpandedModeBy("Approve Investment", 1); - TaskIFrameTemplatePage taskTemplatePage2 = taskWidgetPage1.startTaskIFrame(0); + taskTemplatePage1.finishCreateInvestmentTask(); + TopMenuTaskWidgetPage taskWidget = new TopMenuTaskWidgetPage(); + taskWidget.openFilterWidget(); + taskWidget.addFilter("Name", FilterOperator.CONTAINS); + taskWidget.inputValueOnLatestFilter(FilterValueType.TEXT, "Approve Investment"); + taskWidget.applyFilter(); + TaskIFrameTemplatePage taskTemplatePage2 = taskWidget.startTaskIFrameByIndex(0); taskTemplatePage2.waitForIFrameContentVisible(); assertEquals("Review Request (Skip Tasklist in IFrame)", taskTemplatePage2.getTaskNameOutsideIFrameWithSkipTaskList()); @@ -110,9 +130,13 @@ public void testTextOutIFrameChangeWithSkipTaskList() { public void testShowCategoryInCaseByDefaultIframe() { redirectToRelativeLink("InternalSupport/15B1EA24CCF377E8/saleAndInform.ivp"); NewDashboardPage newDashboardPage = new NewDashboardPage(); - TaskWidgetPage taskWidget = newDashboardPage.openTaskList(); - taskWidget.filterTasksInExpandedModeBy("sale department", 1); - TaskIFrameTemplatePage startTask = taskWidget.startTaskIFrame(0); + newDashboardPage.openTaskList(); + TopMenuTaskWidgetPage taskWidget = new TopMenuTaskWidgetPage(); + taskWidget.openFilterWidget(); + taskWidget.addFilter("Name", FilterOperator.CONTAINS); + taskWidget.inputValueOnLatestFilter(FilterValueType.TEXT, "sale department"); + taskWidget.applyFilter(); + TaskIFrameTemplatePage startTask = taskWidget.startTaskIFrameByIndex(0); startTask.openCaseInfo(); resizeBrowserTo2kResolution(); assertTrue(startTask.isCategoryColumnDisplayed()); diff --git a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/task/TaskTemplateTest.java b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/task/TaskTemplateTest.java index ec1602f93a2..d9c752abaf6 100644 --- a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/task/TaskTemplateTest.java +++ b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/task/TaskTemplateTest.java @@ -5,6 +5,8 @@ import com.axonivy.ivy.webtest.IvyWebTest; import com.axonivy.portal.selenium.common.BaseTest; +import com.axonivy.portal.selenium.common.FilterOperator; +import com.axonivy.portal.selenium.common.FilterValueType; import com.axonivy.portal.selenium.common.NavigationHelper; import com.axonivy.portal.selenium.common.TestAccount; import com.axonivy.portal.selenium.common.Variable; @@ -14,7 +16,7 @@ import com.axonivy.portal.selenium.page.TaskDetailsPage; import com.axonivy.portal.selenium.page.TaskIFrameTemplatePage; import com.axonivy.portal.selenium.page.TaskTemplatePage; -import com.axonivy.portal.selenium.page.TaskWidgetPage; +import com.axonivy.portal.selenium.page.TopMenuTaskWidgetPage; import com.axonivy.portal.selenium.page.WorkingTaskDialogPage; @IvyWebTest @@ -72,8 +74,9 @@ public void testLeaveWorkingTaskByClickingOnLogo() { taskTemplatePage.clickOnLogo(); WorkingTaskDialogPage dialogPage = new WorkingTaskDialogPage(); dialogPage.leaveTask(); - TaskWidgetPage taskWidget = NavigationHelper.navigateToTaskList(); - assertTrue(taskWidget.isTaskStateOpen(0)); + NavigationHelper.navigateToTaskList(); + TopMenuTaskWidgetPage taskWidget = new TopMenuTaskWidgetPage(); + assertTrue("open".equalsIgnoreCase(taskWidget.stateOfFirstTask().text())); } @Test @@ -87,20 +90,26 @@ public void testReserveWorkingTaskByClickingOnLogo() { taskTemplatePage.clickOnLogo(); WorkingTaskDialogPage dialogPage = new WorkingTaskDialogPage(); dialogPage.reserveTask(); - TaskWidgetPage taskWidget = NavigationHelper.navigateToTaskList(); - assertTrue(taskWidget.isTaskStateReserved(0)); + NavigationHelper.navigateToTaskList(); + TopMenuTaskWidgetPage taskWidget = new TopMenuTaskWidgetPage(); + assertTrue("open".equalsIgnoreCase(taskWidget.stateOfFirstTask().text())); } @Test public void testResetTaskWhenStartSideStep() { redirectToRelativeLink(createTestingCaseMapUrl); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - int latestTask = taskWidgetPage.countTasks().size() - 1; - TaskTemplatePage taskTemplatePage = taskWidgetPage.startTask(latestTask); + NavigationHelper.navigateToTaskList(); + TopMenuTaskWidgetPage taskWidget = new TopMenuTaskWidgetPage(); + taskWidget.openFilterWidget(); + taskWidget.addFilter("Name", FilterOperator.IS); + taskWidget.inputValueOnLatestFilter(FilterValueType.TEXT, "Case Map Leave Request"); + taskWidget.applyFilter(); + TaskTemplatePage taskTemplatePage = taskWidget.startTaskByIndex(0); taskTemplatePage.clickTaskActionMenu(); taskTemplatePage.startSideStep(); - TaskWidgetPage taskWidget = NavigationHelper.navigateToTaskList(); - assertTrue(taskWidget.isTaskStateOpen(0)); + NavigationHelper.navigateToTaskList(); + taskWidget = new TopMenuTaskWidgetPage(); + assertTrue("open".equalsIgnoreCase(taskWidget.stateOfFirstTask().text())); } private void createTestData() { @@ -109,26 +118,20 @@ private void createTestData() { } private TaskIFrameTemplatePage startATask() { - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - TaskIFrameTemplatePage taskTemplatePage = taskWidgetPage.startTaskIFrame(0); + NavigationHelper.navigateToTaskList(); + TopMenuTaskWidgetPage taskWidget = new TopMenuTaskWidgetPage(); + TaskIFrameTemplatePage taskTemplatePage = taskWidget.startTaskIFrameByIndex(0); return taskTemplatePage; } private TaskIFrameTemplatePage startATaskAndOpenCaseInfo() { - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - TaskIFrameTemplatePage taskTemplatePage = taskWidgetPage.startTaskIFrame(0); + NavigationHelper.navigateToTaskList(); + TopMenuTaskWidgetPage taskWidget = new TopMenuTaskWidgetPage(); + TaskIFrameTemplatePage taskTemplatePage = taskWidget.startTaskIFrameByIndex(0); taskTemplatePage.openCaseInfo(); return taskTemplatePage; } - @Test - public void testShowCategoryColummnByDefault() { - createTestData(); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - TaskWidgetPage taskList = newDashboardPage.openTaskList(); - assertTrue(taskList.isCategoryColumnDisplayed()); - } - @Test public void testOpeningFinishedTaskInHistoryArea() { createTestData(); diff --git a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/task/TaskWidgetTest.java b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/task/TaskWidgetTest.java index 5a7c267e133..2b7f771ddb9 100644 --- a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/task/TaskWidgetTest.java +++ b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/task/TaskWidgetTest.java @@ -1,43 +1,22 @@ package com.axonivy.portal.selenium.test.task; -import java.util.List; - -import org.apache.commons.lang3.StringUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import com.axonivy.ivy.webtest.IvyWebTest; import com.axonivy.portal.selenium.common.BaseTest; import com.axonivy.portal.selenium.common.NavigationHelper; -import com.axonivy.portal.selenium.common.TaskState; import com.axonivy.portal.selenium.common.TestAccount; -import com.axonivy.portal.selenium.common.TestRole; import com.axonivy.portal.selenium.common.Variable; import com.axonivy.portal.selenium.page.CaseDetailsPage; import com.axonivy.portal.selenium.page.NewDashboardPage; import com.axonivy.portal.selenium.page.TaskDetailsPage; -import com.axonivy.portal.selenium.page.TaskWidgetPage; -import com.axonivy.portal.selenium.page.UserProfilePage; -import com.codeborne.selenide.CollectionCondition; +import com.axonivy.portal.selenium.page.TopMenuTaskWidgetPage; import com.codeborne.selenide.Condition; -import ch.ivy.addon.portalkit.enums.PortalPermission; - @IvyWebTest public class TaskWidgetTest extends BaseTest { - private static final String DISABLE_TASK_COUNT_SETTING = Variable.DISABLE_TASK_COUNT.getKey(); - private static final String GRANT_DELEGATE_OWN_TASK_PERMISSION_PROCESS_URL = - "portalKitTestHelper/14DE09882B540AD5/grantOnlyDelegateOwnTasksPermission.ivp"; - private static final String DENY_DELEGATE_OWN_TASK_PERMISSION_PROCESS_URL = - "portalKitTestHelper/14DE09882B540AD5/undoOnlyDelegateOwnTasksPermission.ivp"; - private static final String DENY_DESTROY_TASK_URL = - "portalKitTestHelper/14DE09882B540AD5/denyDestroyTaskPermission.ivp"; - private static final String GRANT_DESTROY_TASK_URL = - "portalKitTestHelper/14DE09882B540AD5/grantDestroyTaskPermission.ivp"; - - private static final String MATERNITY_LEAVE_REQUEST = "Maternity Leave Request"; - private TaskDetailsPage taskDetailsPage; @Override @@ -50,97 +29,27 @@ public void setup() { @Test public void testOpenRelatedCaseOfTask() { - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.openTaskDetails(0); - - CaseDetailsPage casePage = taskWidgetPage.openRelatedCaseOfTask(); + NavigationHelper.navigateToTaskList(); + TopMenuTaskWidgetPage taskWidget = new TopMenuTaskWidgetPage(); + taskWidget.openTaskDetailsPageByAction(0); + CaseDetailsPage casePage = taskWidget.openRelatedCaseOfTask(); String caseName = casePage.getCaseName(); casePage.checkCaseName(caseName); } - @Test - public void testReserveTask() { - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.checkNameOfTaskAt(0, MATERNITY_LEAVE_REQUEST); - taskWidgetPage.sideStepMenuOnActionButton(0); - taskWidgetPage.reserveTask(0); - taskWidgetPage.isReserveLinkDisabled(0); - taskWidgetPage.checkTaskState(0, TaskState.OPEN.getValue()); - - taskWidgetPage.clickOnTaskStatesAndApply(List.of("Reserved")); - taskWidgetPage.checkNameOfTaskAt(0, MATERNITY_LEAVE_REQUEST); - - taskWidgetPage.sideStepMenuOnActionButton(0); - taskWidgetPage.resetTask(0); - assertTrue(taskWidgetPage.isResetLinkDisabled(0)); - - taskWidgetPage.checkTaskState(0, TaskState.OPEN.getValue()); - - taskWidgetPage.clickOnTaskStatesAndApply(List.of("Reserved")); - taskWidgetPage.countTasks().shouldHave(CollectionCondition.size(0)); - - taskWidgetPage.clickOnTaskStatesAndApply(List.of("Suspended")); - taskWidgetPage.checkNameOfTaskAt(0, MATERNITY_LEAVE_REQUEST); - } - - @Test - public void testStartButtonStatus() { - login(TestAccount.ADMIN_USER); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - - taskWidgetPage.filterTasksBy("Annual Leave Request"); - taskWidgetPage.waitTillNameOfFirstTaskToBe("Annual Leave Request"); - taskWidgetPage.isTaskDisabled(0); - - taskWidgetPage.filterTasksBy("Sick Leave Request"); - taskWidgetPage.waitTillNameOfFirstTaskToBe("Sick Leave Request"); - } - - @Test - public void testDisplayDelegateButton() { - login(TestAccount.ADMIN_USER); - redirectToRelativeLink(GRANT_DELEGATE_OWN_TASK_PERMISSION_PROCESS_URL); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - - taskWidgetPage.filterTasksBy("Sick Leave Request"); - taskWidgetPage.waitTillNameOfFirstTaskToBe("Sick Leave Request"); - taskWidgetPage.isTaskDelegationEnabled(0); - - taskWidgetPage.filterTasksBy("Annual Leave Request"); - taskWidgetPage.waitTillNameOfFirstTaskToBe("Annual Leave Request"); - - redirectToRelativeLink(DENY_DELEGATE_OWN_TASK_PERMISSION_PROCESS_URL); - } - - @Test - public void testDestroyTask() { - login(TestAccount.ADMIN_USER); - grantSpecificPortalPermission(PortalPermission.SYSTEM_TASK_READ_ALL); - redirectToRelativeLink(GRANT_DESTROY_TASK_URL); - - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.filterTasksBy("Annual Leave Request"); - taskWidgetPage.waitTillNameOfFirstTaskToBe("Annual Leave Request"); - - taskWidgetPage.isTaskDestroyEnabled(0); - taskWidgetPage.destroyTask(0); - taskWidgetPage.confimDestruction(); - taskWidgetPage.checkTaskState(0, TaskState.DESTROYED.getValue()); - - redirectToRelativeLink(DENY_DESTROY_TASK_URL); - } - @Test public void testBreadCrumbInTaskDetail() { - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskDetailsPage = taskWidgetPage.openTaskDetails(0); + NavigationHelper.navigateToTaskList(); + TopMenuTaskWidgetPage taskWidget = new TopMenuTaskWidgetPage(); + + taskDetailsPage = taskWidget.openTaskDetailsPageByAction(0); assertEquals("Task: Maternity Leave Request", taskDetailsPage.getTextOfCurrentBreadcrumb()); taskDetailsPage.clickTaskListBreadCrumb(); - taskWidgetPage = new TaskWidgetPage(); - assertEquals(true, taskWidgetPage.isDisplayed()); + taskWidget = new TopMenuTaskWidgetPage(); + assertEquals(true, taskWidget.isDisplayed()); - taskDetailsPage = taskWidgetPage.openTaskDetails(0); + taskDetailsPage = taskWidget.openTaskDetailsPageByAction(0); taskDetailsPage.goToHomeFromBreadcrumb(); NewDashboardPage newDashboardPage = new NewDashboardPage(); assertEquals(true, newDashboardPage.isDisplayed()); @@ -149,106 +58,19 @@ public void testBreadCrumbInTaskDetail() { @Test public void testDisplayTaskAndCaseCategory() { login(TestAccount.ADMIN_USER); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.openTaskDetails(0); - taskWidgetPage.getTaskCategory().shouldHave(Condition.text("Other Leave/Maternity")); - taskWidgetPage.getCaseCategory().shouldHave(Condition.text("Leave Request")); + NavigationHelper.navigateToTaskList(); + TopMenuTaskWidgetPage taskWidget = new TopMenuTaskWidgetPage(); + taskWidget.openTaskDetailsPageByAction(0); + taskWidget.getTaskCategory().shouldHave(Condition.text("Other Leave/Maternity")); + taskWidget.getCaseCategory().shouldHave(Condition.text("Leave Request")); } @Test public void testShowTaskCount() { - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.waitUntilTaskCountDifferentThanZero(); - assertEquals(3, taskWidgetPage.getTaskCount().intValue(), "In Task list, Task Count != 3"); - } - - @Test - public void testDisableTaskCount() { - updatePortalSetting(DISABLE_TASK_COUNT_SETTING, "true"); - login(TestAccount.ADMIN_USER); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - assertEquals(null, taskWidgetPage.getTaskCount(), "In Task list, Task Count is disabled"); - } - - @Test - public void testBreadCrumb() { - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - assertEquals("Tasks (3)", taskWidgetPage.getTextOfCurrentBreadcrumb()); - taskWidgetPage.goToHomeFromBreadcrumb(); - NewDashboardPage newDashboardPage = new NewDashboardPage(); - assertEquals(true, newDashboardPage.isDisplayed()); - } - - @Test - public void testDelegateTask() { - login(TestAccount.ADMIN_USER); - redirectToRelativeLink(NewDashboardPage.PORTAL_HOME_PAGE_URL); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - assertEquals(TestRole.EVERYBODY_ROLE, taskWidgetPage.getResponsibleOfTaskAt(0)); - taskWidgetPage.openTaskDelegateDialog(0); - taskWidgetPage.isDelegateTypeSelectAvailable(); - taskWidgetPage.selectDelegateResponsible(TestAccount.HR_ROLE_USER.getFullName(), false); - assertEquals(TestAccount.HR_ROLE_USER.getFullName(), taskWidgetPage.getResponsibleOfTaskAt(0)); - - taskWidgetPage.openTaskDelegateDialog(0); - taskWidgetPage.selectDelegateResponsible(TestRole.HR_ROLE, true); - assertEquals(TestRole.HR_ROLE, taskWidgetPage.getResponsibleOfTaskAt(0)); + NavigationHelper.navigateToTaskList(); + TopMenuTaskWidgetPage taskWidget = new TopMenuTaskWidgetPage(); + taskWidget.waitUntilTaskCountDifferentThanZero(); + assertEquals(4, taskWidget.countAllTasks().size(), "In Task list, Task Count != 4"); } - @Test - public void testChangeTaskSortingOptions() { - NewDashboardPage newDashboardPage = new NewDashboardPage(); - UserProfilePage userProfilePage = newDashboardPage.openMyProfilePage(); - - // Change sorting options - userProfilePage.selectTaskSortField("Priority"); - userProfilePage.selectTaskSortDirection("Sort ascending"); - newDashboardPage = userProfilePage.save(); - - // Check result - TaskWidgetPage taskWidgetPage = newDashboardPage.openTaskList(); - assertEquals("high", taskWidgetPage.getPriorityOfTask(0)); - assertEquals("low", taskWidgetPage.getPriorityOfTask(taskWidgetPage.countTasks().size() - 1)); - - // Change sorting options - userProfilePage = taskWidgetPage.openMyProfilePage(); - userProfilePage.selectTaskSortField("Name"); - userProfilePage.selectTaskSortDirection("Sort descending"); - newDashboardPage = userProfilePage.save(); - - // Check result - taskWidgetPage = newDashboardPage.openTaskList(); - assertEquals("Sick Leave Request", taskWidgetPage.getNameOfTaskAt(0)); - assertEquals("Annual Leave Request", taskWidgetPage.getNameOfTaskAt(taskWidgetPage.countTasks().size() - 1)); - } - - @Test - public void testExportToExcel() { - login(TestAccount.ADMIN_USER); - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.clickExportToExcelLink(); - assertTrue(taskWidgetPage.isDownloadCompleted()); - } - - @Test - public void testStickySortTaskList() { - TaskWidgetPage taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskWidgetPage.sortTaskListByColumn("Name / Description", 0, "task-name", "Annual Leave Request"); - String taskName = taskWidgetPage.getTaskListCustomCellValue(0, "task-name"); - assertTrue(StringUtils.equalsIgnoreCase("Annual Leave Request", taskName)); - taskWidgetPage.sortTaskListByColumn("Name / Description", 0, "task-name", "Sick Leave Request"); - taskWidgetPage.clickOnLogo(); - new NewDashboardPage(); - taskWidgetPage = NavigationHelper.navigateToTaskList(); - taskName = taskWidgetPage.getTaskListCustomCellValue(0, "task-name"); - assertTrue(StringUtils.equalsIgnoreCase("Sick Leave Request", taskName)); - - UserProfilePage userProfilePage = taskWidgetPage.openMyProfilePage(); - userProfilePage.selectTaskSortField("Priority"); - userProfilePage.selectTaskSortDirection("Sort ascending"); - NewDashboardPage newDashboardPage = userProfilePage.save(); - - taskWidgetPage = newDashboardPage.openTaskList(); - assertEquals("high", taskWidgetPage.getPriorityOfTask(0)); - } } diff --git a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/userexample/test/CaseMapTest.java b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/userexample/test/CaseMapTest.java index 711808c7a06..027820ba4c4 100644 --- a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/userexample/test/CaseMapTest.java +++ b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/userexample/test/CaseMapTest.java @@ -5,10 +5,12 @@ import com.axonivy.ivy.webtest.IvyWebTest; import com.axonivy.portal.selenium.common.BaseTest; +import com.axonivy.portal.selenium.common.FilterOperator; +import com.axonivy.portal.selenium.common.FilterValueType; import com.axonivy.portal.selenium.common.NavigationHelper; import com.axonivy.portal.selenium.common.TestAccount; import com.axonivy.portal.selenium.page.CaseMapPage; -import com.axonivy.portal.selenium.page.TaskWidgetPage; +import com.axonivy.portal.selenium.page.TopMenuTaskWidgetPage; import com.codeborne.selenide.CollectionCondition; import com.codeborne.selenide.Condition; @@ -23,7 +25,6 @@ public class CaseMapTest extends BaseTest { private static final String APPROVAL_LEVEL_2 = "Approve Level 2"; private CaseMapPage caseMapPage; - private TaskWidgetPage taskWidgetPage; @Override @BeforeEach @@ -62,9 +63,15 @@ public void testCaseMapApprovalWorkflow() { startTaskByTaskName(CREATE_CONTRACT); assertInputData(); caseMapPage.clickSubmitContractButton(); - taskWidgetPage = new TaskWidgetPage(); - taskWidgetPage.waitForPageLoad(); - taskWidgetPage.countTasks().shouldHave(CollectionCondition.size(0)); + NavigationHelper.navigateToTaskList(); + TopMenuTaskWidgetPage taskWidget = new TopMenuTaskWidgetPage(); + + taskWidget.waitForPageLoad(); + taskWidget.openFilterWidget(); + taskWidget.addFilter("state", null); + taskWidget.inputValueOnLatestFilter(FilterValueType.STATE_TYPE, "Done"); + taskWidget.applyFilter(); + taskWidget.countAllTasks().shouldHave(CollectionCondition.size(6)); } @Test @@ -88,15 +95,20 @@ public void testCaseMapRejectedWorkflow() { caseMapPage.getVerifierComment().shouldHave(Condition.value("Ok")); caseMapPage.getInternalCreditComment().shouldHave(Condition.value("Fail")); caseMapPage.clickRejectButton(); - taskWidgetPage = new TaskWidgetPage(); - taskWidgetPage.filterTasksInExpandedModeBy(APPROVAL_LEVEL_2, 0); - taskWidgetPage.countTasks().shouldHave(CollectionCondition.size(0)); + NavigationHelper.navigateToTaskList(); + TopMenuTaskWidgetPage taskWidget = new TopMenuTaskWidgetPage(); + taskWidget.openFilterWidget(); + taskWidget.addFilter("Name", FilterOperator.IS); + taskWidget.inputValueOnLatestFilter(FilterValueType.TEXT, APPROVAL_LEVEL_1); + taskWidget.addFilter("state", null); + taskWidget.inputValueOnLatestFilter(FilterValueType.STATE_TYPE, "Done"); + taskWidget.applyFilter(); + taskWidget.countAllTasks().shouldHave(CollectionCondition.size(1)); } private void startTaskByTaskName(String taskname) { - TaskWidgetPage taskWidgetPage = new TaskWidgetPage(); - taskWidgetPage.filterTasksInExpandedModeBy(taskname); - taskWidgetPage.clickOnStartTaskLink(0); + TopMenuTaskWidgetPage taskWidget = new TopMenuTaskWidgetPage(); + taskWidget.startTaskByNameInIFrame(taskname); } private void assertInputData() { diff --git a/AxonIvyPortal/portal/.settings/ch.ivyteam.ivy.designer.prefs b/AxonIvyPortal/portal/.settings/ch.ivyteam.ivy.designer.prefs index 52962b8e303..55779a5ce56 100644 --- a/AxonIvyPortal/portal/.settings/ch.ivyteam.ivy.designer.prefs +++ b/AxonIvyPortal/portal/.settings/ch.ivyteam.ivy.designer.prefs @@ -1,4 +1,3 @@ -ch.ivyteam.ivy.designer.preferences.DataClassPreferencePage\:DEFAULT_DATA_CLASS=ch.ivy.add.portalkit.Data ch.ivyteam.ivy.designer.preferences.DataClassPreferencePage\:DEFAULT_NAMESPACE=portalkit ch.ivyteam.ivy.designer.preferences.DataClassPreferencePage\:useProjectSettings=true ch.ivyteam.ivy.designer.preferences.ProcessEnginePreferencePage\:ACTIVATE_PROCESS_DATA_HISTORY=true @@ -17,5 +16,5 @@ ch.ivyteam.ivy.designer.preferences.editor.ProcessEditorPreferencePage\:SHOW_GRI ch.ivyteam.ivy.designer.preferences.editor.ProcessEditorPreferencePage\:useProjectSettings=true ch.ivyteam.ivy.project.preferences\:PORTAL_VERSION=10 ch.ivyteam.ivy.project.preferences\:PRIMEFACES_VERSION=13 -ch.ivyteam.ivy.project.preferences\:PROJECT_VERSION=114006 +ch.ivyteam.ivy.project.preferences\:PROJECT_VERSION=120001 eclipse.preferences.version=1 diff --git a/AxonIvyPortal/portal/cms/cms.yaml b/AxonIvyPortal/portal/cms/cms.yaml index edb4596d15f..5a2295b2567 100644 --- a/AxonIvyPortal/portal/cms/cms.yaml +++ b/AxonIvyPortal/portal/cms/cms.yaml @@ -21,6 +21,7 @@ ch.ivy.addon.portalkit.ui.jsf: editAbsence: Edit absence from: From noDeputy: No substitute + noPermissionToSeeThisArea: You do not have the required permission to see this area. period: Period personalTaskDuringAbsenceDeputies: Substitutes for personally assigned tasks during the absence personalTaskPermanentDeputies: Permanent substitutes for personally assigned tasks @@ -109,14 +110,10 @@ ch.ivy.addon.portalkit.ui.jsf: TUESDAY: TUE WEDNESDAY: WED MyProfile: - CaseList: Case list DateFormat: Date Format General: General Homepage: Homepage ProcessList: Process list - SortFieldSelections: - defaultSortFieldLabel: Default sort field - TaskList: Task list defaultOption: Default ({0}) defaultViewMode: Default view mode PortalManagement: @@ -135,7 +132,7 @@ ch.ivy.addon.portalkit.ui.jsf: announcementsDisabled: Announcements are disabled. announcementsEnabled: Announcements are enabled. defaultLanguageRequiredMessage: Announcement for application default language is required. - disable: Disable + disabled: Disabled enable: Enable information: You can announce a general information (e.g. Downtime, Changes, etc.) in this area. This message can be seen by all portal users. tabTitle: Announcements @@ -450,7 +447,7 @@ ch.ivy.addon.portalkit.ui.jsf: notAvailable: N/A note: NOTE numberOfSelectedFilter: selected filters - ok: Ok + ok: OK 'on': 'on' pleaseAddDocument: Please add a document with the link above. pleaseAddNote: Please add a note with the link above. @@ -460,11 +457,12 @@ ch.ivy.addon.portalkit.ui.jsf: processes: Processes public: Public remove: Remove + removeSelection: Remove selection reorder: Reorder requiredFieldMessage: This field is required reserve: Reserve reset: Reset - resetSettingHeaderText: Reset setting? + resetSettingHeaderText: Reset setting resetTaskHeaderText: Reset this task? resetToDefaultMessage: This operation cannot be undone. Are you sure you want to reset to default settings? resetToStandardFilterHeaderText: 'Reset to standard filter? ' @@ -472,6 +470,7 @@ ch.ivy.addon.portalkit.ui.jsf: restoreToDefaultChartHeaderText: Restore to default charts? role: Role save: Save + saveAll: Save all saveSuccessfully: Data saved successfully. search: Search second: second @@ -511,7 +510,7 @@ ch.ivy.addon.portalkit.ui.jsf: viewExpired: Your current view expired. You will be redirected to the home page. viewMode: View mode visible: Visible - warning: Warning + warning: Warning! welcomeToPortal: Welcome, please login wrongDateFormat: Please enter valid date. year: year @@ -870,7 +869,7 @@ ch.ivy.addon.portalkit.ui.jsf: toUser: User userSelectionWatermark: Please select a user... taskDetails: - addDocumentHelpText: To upload files, drag & drop or select files + addDocumentHelpText: 'To upload files, drag & drop or ' addNoteHelpText: Write your text here. afterEscalation: After escalation businessCase: Business Case @@ -1014,11 +1013,12 @@ ch.ivy.addon.portalkit.ui.jsf: showFullTaskList: Show full task list sort: Sort taskWarning: - createdTaskLeave: 'You are about to leave this page. Please choose one of the following options:
  •     Leave: Discard your changes and move to the selected page.
  •     Cancel: Continue working this task.
' - createdTaskLogout: 'You are about to leave this page. Please choose one of the following options:
  •  Logout: Discard your changes and logout.
  •  Cancel: Continue working this task.
' - resetParkTaskBeforeLeave: 'You are about to leave a task in progress. Please choose one of the following options:
  • Leave: Discard your changes and move to the selected page.
  • Reserve: Discard your changes and keep the task in your task list.
  • Cancel: Continue working this task.
' - resetParkTaskBeforeLogout: 'You are about to leave a task in progress. Please choose one of the following options:
  •     Logout: Discard your changes and logout.
  •     Reserve: Discard your changes and keep the task in your personal task list. Then logout.
  •     - Cancel: Continue working this task.
' + createdTaskLeave: '
You are about to leave this page.
Please choose one of the following options:
  • Leave: Discard your changes and move to the selected page.
  • Cancel: Continue working this task.
' + createdTaskLogout: '
You are about to leave this page.
Please choose one of the following options:
  •  Logout: Discard your changes and logout.
  •  Cancel: Continue working this task.
' + resetParkTaskBeforeLeave: '
You are about to leave a task in progress.
Please choose one of the following options:
  • Leave: Discard your changes and move to the selected page.
  • Reserve: Discard your changes and keep the task in your task list.
  • Cancel: Continue working this + task.
' + resetParkTaskBeforeLogout: '
You are about to leave a task in progress.
Please choose one of the following options:
  •     Logout: Discard your changes and logout.
  •     Reserve: Discard your changes and keep the task in your personal task list. Then logout.
  •   +   Cancel: Continue working this task.
' taskNotFound: The task does not exist or you have insufficient rights to see this task. userProfile: myProfileTitle: My profile @@ -1060,7 +1060,7 @@ Dialogs: noResultsText: There are no results. dashboard: PortalDashboardConfiguration: - NewDashboard: New Dashboard + NewDashboard: Add new dashboard component: CustomDashboardWidget: CouldNotFindLinkedProcess: Could not find the linked process! diff --git a/AxonIvyPortal/portal/cms/cms_de.yaml b/AxonIvyPortal/portal/cms/cms_de.yaml index 104b1bf7133..923656479dd 100644 --- a/AxonIvyPortal/portal/cms/cms_de.yaml +++ b/AxonIvyPortal/portal/cms/cms_de.yaml @@ -23,6 +23,7 @@ ch.ivy.addon.portalkit.ui.jsf: editAbsence: Abwesenheiten bearbeiten from: Von noDeputy: Kein Stellvertreter + noPermissionToSeeThisArea: Sie haben nicht die erforderliche Erlaubnis, dieses Gebiet zu sehen. period: Zeitraum personalTaskDuringAbsenceDeputies: Vertretungen für persönlich zugewiesene Aufgaben während der Abwesenheit personalTaskPermanentDeputies: Ständige Stellvertreter für persönlich zugewiesene Aufgaben @@ -48,6 +49,8 @@ ch.ivy.addon.portalkit.ui.jsf: nextAbsence: Bevorstehende Abwesenheit selectedDeputyFor: Ausgewählter Benutzer ist Stellvertreter für selectedUser: Ausgewählter Benutzer + AccessibilityShortcuts: + processName: Barrierefreiheit Kürzel Widgets AllTasks: caseDescription: Beschreibung des Vorgangs taskDescription: Aufgabenbeschreibung @@ -134,16 +137,12 @@ ch.ivy.addon.portalkit.ui.jsf: HEADING_3: Rubrik 3 NORMAL_TEXT: Normaler Text MyProfile: - CaseList: Liste der Vorgänge DateFormat: Datum Format FormattingLanguage: Sprache der Formatierung General: Allgemeine Homepage: Homepage Language: Sprache ProcessList: Prozess-Liste - SortFieldSelections: - defaultSortFieldLabel: Standard-Sortierfeld - TaskList: Aufgabenliste byDefault: ' standardmäßig' defaultOption: Standard ({0}) defaultViewMode: Standardanzeige @@ -168,8 +167,8 @@ ch.ivy.addon.portalkit.ui.jsf: announcementsDisabled: Ankündigungen sind deaktiviert announcementsEnabled: Ankündigungen sind aktiviert defaultLanguageRequiredMessage: Ein Ankündigungstext in der standard Applikationssprache ist notwendig - disable: Deaktivieren - enable: Aktivieren + disabled: Deaktiviert + enable: Ansage einschalten information: Sie können eine allgemeine Ankündigung in diesem Bereich machen (z.B. Wartungsankündigung). Diese Nachricht kann von allen Benutzern gesehen werden. saveChanges: Änderungen speichern tabTitle: Ankündigungen @@ -180,6 +179,7 @@ ch.ivy.addon.portalkit.ui.jsf: applicationHint: Die Reihenfolge kann mit Drag & Drop geändert werden. applicationLinkRequiredMsg: Geben Sie den Portal Link an. applicationList: + addNewApplication: Neue Anwendung hinzufügen applicationSelectionHeader: Anwendung auswählen menuIcon: Menü Symbol applications: Anwendungen @@ -344,7 +344,7 @@ ch.ivy.addon.portalkit.ui.jsf: FINISHED_TIME: Erledigt ID: Vorgangs Id NAME: Name / Beschreibung - OWNER: Verantwortlich + OWNER: Prozessverantwortlichen STATE: Status deletionNoteContent: Der Vorgang wurde durch {0} gelöscht. destroyCaseMessage: Diese Operation kann nicht rückgängig gemacht werden. Sind Sie sicher, dass dieser komplette Vorgang gelöscht werden soll? @@ -412,6 +412,7 @@ ch.ivy.addon.portalkit.ui.jsf: addDocument: Dokument hinzufügen addNote: Notiz hinzufügen allCategories: Alle Kategorien + allTypes: Alle Typen allowPng: Nur das png Format wird unterstützt apply: Anwenden at: am @@ -459,8 +460,10 @@ ch.ivy.addon.portalkit.ui.jsf: destroyTaskHeaderText: Diese Aufgabe löschen? detail: Details display: Anzeigen + displayAsTopMenu: Als oberstes Menü anzeigen displayName: Name anzeigen - dragAndDrop: 'Ziehen und Ablegen eines Bildes oder ' + dragAndDropFile: 'Ziehen und Ablegen einer Datei oder ' + dragAndDropImage: 'Ziehen und Ablegen eines Bildes oder ' edit: Bearbeiten errorAjaxMessage: Es gibt einen allgemeinen Fehler! errorFileUploadSize: Die Dateigrösse muss kleiner als {0} sein. @@ -517,7 +520,7 @@ ch.ivy.addon.portalkit.ui.jsf: note: NOTIZ numberFromBiggerThanTo: Nach" muss größer sein als "Von". numberOfSelectedFilter: Ausgewählte Filter - ok: Ok + ok: OK 'on': am pleaseAddDocument: Verwenden Sie bitte den Link oben, um Dokumente hochzuladen pleaseAddNote: Verwenden Sie bitte den Link oben, um Notizen hochzuladen @@ -527,10 +530,12 @@ ch.ivy.addon.portalkit.ui.jsf: processes: Prozesse public: Öffentlich remove: Entfernen + removeSelection: Selektion entfernen reorder: Neu anordnen requiredFieldMessage: Dies ist ein Pflichtfeld reserve: Reservieren reset: Zurücksetzen + resetFilters: Filter zurücksetzen resetSettingHeaderText: Einstellung zurücksetzen? resetTaskHeaderText: Diese Aufgabe zurücksetzen? resetToDefaultMessage: Dieser Vorgang kann nicht rückgängig gemacht werden. Sind Sie sicher, dass Sie auf die Standard-Einstellungen zurücksetzen möchten? @@ -539,11 +544,13 @@ ch.ivy.addon.portalkit.ui.jsf: restoreToDefaultChartHeaderText: Auf Standarddiagramme zurücksetzen? role: Rolle save: Speichern + saveAll: Speichern Sie alle saveSuccessfully: Daten erfolgreich gespeichert. search: Suche second: Sekunde seconds: Sekunden seeDetail: Details anzeigen + select: Auswählen selectAll: Alle selektieren selectUsers: Benutzer auswählen selectedDay: '{0} ausgewählte Tag(e)' @@ -570,10 +577,12 @@ ch.ivy.addon.portalkit.ui.jsf: theProcess: Der Prozess timeInformation: Zeitangaben timestamp: Zeitstempel + topMenuItem: Oberster Menüpunkt type: Typ typeAdmin: Alle Administratoren typeAllUsers: Alle Benutzer typeOnlyMe: Nur für mich + uploadHere: Hier hochladen uploadOneHere: Auswählen user: '{0} Benutzer' users: Benutzer @@ -581,7 +590,7 @@ ch.ivy.addon.portalkit.ui.jsf: viewExpired: Ihre aktuelle Bearbeitungsmaske ist abgelaufen und kann nicht weiter bearbeitet werden. Sie werden auf die Startseite umgeleitet. viewMode: Ansichtsmodus visible: Sichtbar - warning: Warnung + warning: Warnung! welcomeToPortal: Willkommen, bitte melden Sie sich an wrongDateFormat: Bitte geben Sie ein gültiges Datum ein. year: Jahr @@ -789,6 +798,7 @@ ch.ivy.addon.portalkit.ui.jsf: dashboardIcon: Dashboard-Symbol dashboardPermission: Dashboard Berechtigung dashboardTitle: Dashboard Titel + deleteDashboardMessage: Sind Sie sicher, dass Sie die "{0}" dashboard? editDashboard: Dashboard editieren manageDashboard: Dashboard verwalten removeDashboardHeader: Dashboard "{0}" entfernen @@ -854,6 +864,7 @@ ch.ivy.addon.portalkit.ui.jsf: taskListIntroduction: Dieses Widget zeigt relevante Aufgabeninformationen gemäß der definierten Einstellungen an taskStart: Aufgabe starten taskWidgetConfiguration: Aufgaben-Widget-Konfiguration + topMenuItemInfo: Wenn die Checkbox „Oberster Menüpunkt“ aktiviert ist, erscheint das Dashboard als oberstes Element in der Navigationsleiste, sortiert nach Listenposition. Wenn sie deaktiviert ist, wird es als Unterpunkt unter „Dashboards“ angezeigt, ebenfalls nach Listenposition sortiert. widgetInfo: Widget-Informationen widgetInfoIcon: Widget-Informations-Symbol widgetTitle: Widget-Titel @@ -1091,7 +1102,7 @@ ch.ivy.addon.portalkit.ui.jsf: toUser: Benutzer userSelectionWatermark: Bitte wählen Sie einen Benutzer aus... taskDetails: - addDocumentHelpText: Zum Hochladen Dateien per Drag & Drop hier ablegen oder Dateien auswählen + addDocumentHelpText: 'Zum Hochladen Dateien per Drag & Drop hier ablegen oder ' addNoteHelpText: Schreiben Sie hier Ihren Text afterEscalation: Nach Eskalation businessCase: Vorgang @@ -1109,6 +1120,7 @@ ch.ivy.addon.portalkit.ui.jsf: processingTime: Bearbeitungszeit setDelayTimestamp: '{0} ({1}) hat die Verzügerungszeit des Tasks #{2} auf {3} gesetzt.' setExpiryActivatorAndTimeNotes: '{0} und weisen Sie {1} als Aktivator für die Aufgabeneskalation zu' + supportFileTypes: 'Unterstützte Dateitypen für Uploads: {0}' taskCategory: Aufgabenkategorie taskExpiryDisable: Es kann keine Ablaufzeit gesetzt werden, da diese Aufgabe keine Eskalationslogik enthält. technicalCase: Technischer Vorgang @@ -1237,12 +1249,12 @@ ch.ivy.addon.portalkit.ui.jsf: showFullTaskList: Komplette Aufgabenliste anzeigen sort: Sortieren taskWarning: - createdTaskLeave: 'Sie verlassen die aktuelle Seite. Bitte wählen Sie eine der folgenden Optionen:
  •     Verlassen: Ihre Änderungen verwerfen und zur ausgewählten Seite gehen.
  •     Abbrechen: Die Bearbeitung dieser Aufgabe fortsetzen.
' - createdTaskLogout: 'Sie verlassen die aktuelle Seite. Bitte wählen Sie eine der folgenden Optionen:
  • Abmelden: Ihre Änderungen verwerfen und abmelden.
  • Abbrechen: Die Bearbeitung dieser Aufgabe fortsetzen.
' - resetParkTaskBeforeLeave: 'Sie verlassen die aktuelle Aufgabe. Bitte wählen Sie eine der folgenden Optionen:
  • Verlassen: Ihre Änderungen verwerfen und zur ausgewählten Seite gehen.
  • Reservieren: Ihre Änderungen verwerfen und die Aufgabe in Ihre Aufgabenliste verschieben
  • Abbrechen: Die - Bearbeitung dieser Aufgabe fortsetzen.
' - resetParkTaskBeforeLogout: 'Sie verlassen die aktuelle Aufgabe. Bitte wählen Sie eine der folgenden Optionen:
  •     Abmelden: Ihre Änderungen verwerfen und abmelden.
  •     Reservieren: Ihre Änderungen verwerfen und die Aufgabe in Ihre persönliche Aufgabenliste verschieben. - Dann abmelden.
  •     Abbrechen: Die Bearbeitung dieser Aufgabe fortsetzen.
' + createdTaskLeave: '
Sie verlassen die aktuelle Seite.
Bitte wählen Sie eine der folgenden Optionen:
  • Verlassen: Ihre Änderungen verwerfen und zur ausgewählten Seite gehen.
  • Abbrechen: Die Bearbeitung dieser Aufgabe fortsetzen.
' + createdTaskLogout: '
Sie verlassen die aktuelle Seite.
Bitte wählen Sie eine der folgenden Optionen:
  • Abmelden: Ihre Änderungen verwerfen und abmelden.
  • Abbrechen: Die Bearbeitung dieser Aufgabe fortsetzen.
' + resetParkTaskBeforeLeave: '
Sie verlassen die aktuelle Aufgabe.
Bitte wählen Sie eine der folgenden Optionen:
  • Verlassen: Ihre Änderungen verwerfen und zur ausgewählten Seite gehen.
  • Reservieren: Ihre Änderungen verwerfen und die Aufgabe in Ihre Aufgabenliste verschieben
  • + Abbrechen: Die Bearbeitung dieser Aufgabe fortsetzen.
' + resetParkTaskBeforeLogout: '
Sie verlassen die aktuelle Aufgabe.
Bitte wählen Sie eine der folgenden Optionen:
  •     Abmelden: Ihre Änderungen verwerfen und abmelden.
  •     Reservieren: Ihre Änderungen verwerfen und die Aufgabe in Ihre persönliche Aufgabenliste + verschieben. Dann abmelden.
  •     Abbrechen: Die Bearbeitung dieser Aufgabe fortsetzen.
' taskNotFound: Die Aufgabe existiert nicht oder Sie haben ungenügende Rechte, um diese Aufgabe zu sehen. userProfile: myProfileTitle: Mein Profil @@ -1285,7 +1297,7 @@ Dialogs: noResultsText: Es liegen keine Ergebnisse vor. dashboard: PortalDashboardConfiguration: - NewDashboard: Neues Dashboard + NewDashboard: Neues Dashboard hinzufügen component: CustomDashboardWidget: CouldNotFindLinkedProcess: Der verlinkte Prozess konnte nicht gefunden werden! @@ -1305,7 +1317,7 @@ Dialogs: CaseDetailTitle: Vorgangsdetails DataDescription: Daten und Beschreibung destroyCase: Vorgang löschen - CaseOwner: Prozessverantwortlicher + CaseOwner: Prozessverantwortlichen Finished: Erledigt GlobalSearchText: Die Vorgänge enthalten das Schlüsselwort "{0}" in Vorgangs Id{1}. ShowBusinessDetails: Geschäftsinformationen anzeigen @@ -1327,11 +1339,31 @@ Dialogs: axonivy: portal: component: + ChatDashboard: + AddTool: Werkzeug hinzufügen + Tools: Werkzeuge + WelcomeHeaderText: Willkommen auf dem Axon Ivy Portal! + WelcomeText: Wir freuen uns, Sie an Bord zu haben. Das Axon Ivy Portal ist Ihr Tor zu einer nahtlosen und effizienten Erfahrung. Egal, ob Sie ein neuer Benutzer sind, der die Funktionen erkundet, oder ein wiederkehrender Besucher, wir sind hier, um Sie bei jedem Schritt zu unterstützen. ShareLinkDialog: CopyLink: Link kopieren + Link: Link LinkCopied: Link kopiert + ToolList: + Attributes: Attribute + Collection: Sammlung + NoAvailableTools: Es gibt keine verfügbaren Tools dashboard: component: + AccessibilityShortcuts: + content: "
\n
\n Alt + 1Fokus auf die Dashboards\n
\n
\n Alt + 4Fokus auf die Fälle\n
\n\ + \
\n Alt + AFokus auf den ersten Prozess\n
\n
\n TabSequentielles Durchlaufen von Elementen\n
\n \n Alt + 2Fokus auf die Prozesse\n
\n
\n Alt + 5Fokus auf die Suche\n
\n
\n Alt + WFokus auf die erste Aufgabe\n
\n
\n EscErweiterte Widgets schließen/Kontext Menüs schließen\n
\n
\n Alt + 3Fokus auf die Aufgaben\n
\n
\n Alt + 6Fokus auf die User Einstellungen\n
\n
\n Alt + QFokus auf den ersten Fall\n
\n
\n EnterAuswahl bestätigen \n
\n
" + title: 'Barrierefreiheitskürzel. Alt + 1: Se focaliser sur l’onglet du Dashboard. Alt + 2: Se focaliser sur l’onglet des processus. Alt + 3: Se focaliser sur l’onglet des tâches. Alt + 4: Se focaliser sur l’onglet des cas. Alt + 5: Se focaliser sur la recherche. Alt + 6: Se focaliser sur + les paramètres utilisateur. Alt + A: Se focaliser sur le premier processus. Alt + W: Se focaliser sur la première tâche. Alt + Q: Se focaliser sur le premier cas. Tab: Navigation séquentielle entre les éléments. Esc: Fermer les widgets agrandis/Fermer les menus contextuels. Enter: Confirmer + la sélection' CaseWidgetConfiguration: AddFilter: Filter hinzufügen ClientStatisticWidget: @@ -1389,11 +1421,43 @@ Dialogs: invalidSizeMessage: Datei zu groß! maximumFileUploadElement: Es gibt bereits ein Datei-Upload-Element Labels: + AI: + Error: + CannotFindUser: '' + CannotStartTask: '' + InvalidTaskPriority: '' + InvalidTaskState: '' + NoMatchingCase: '' + NoMatchingProcesses: '' + NoMatchingTask: '' + FindCaseAIResult: '' + FindProcessAIResult: '' + FindTaskAIResult: '' + FindUserAIResult: '' + FoundCaseHeader: '' + FoundProcessesHeader: '' + FoundTaskHeader: '' + FoundUsersHeader: '' + ProcessInfoHeader: '' + ProcessInfoHeaderWithParameters: '' + ProcessParameterInfo: '' + ProcessParameterInfoWithValue: '' + TaskDetailsResult: '' AppendTask-Explain: Die Aufgabe wird in der Sequenz nach meiner Aufgabe hinzugefügt. AppendTheTask: Aufgabe anhängen CreateNewDashboard: Neues Dashboard erstellen EditDescription: Beschreibung bearbeiten Enums: + ChatbotCandidateQuestion: + EXPLORE: + header: Explore + question: Was sind die wichtigsten Merkmale des Axon Ivy Portals? + INTERACT: + header: Interact + question: Listen Sie mir alle Aufgaben auf, die in der laufenden Woche erledigt werden müssen + TUTORIAL: + header: Tutorial + question: Wo kann ich die Dokumentation oder Tutorials für das Axon Ivy Portal finden? DashboardStandardCaseColumn: ACTIONS: Aktionen APPLICATION: Anmeldung @@ -1404,7 +1468,7 @@ Labels: FINISHED: Beendetes Datum ID: Id NAME: Name - OWNER: Eigentümer des Falles + OWNER: Prozessverantwortlichen STATE: Staat DashboardStandardTaskColumn: ACTIONS: Aktionen diff --git a/AxonIvyPortal/portal/cms/cms_en.yaml b/AxonIvyPortal/portal/cms/cms_en.yaml index abe85f3c95f..047dfbf620b 100644 --- a/AxonIvyPortal/portal/cms/cms_en.yaml +++ b/AxonIvyPortal/portal/cms/cms_en.yaml @@ -23,6 +23,7 @@ ch.ivy.addon.portalkit.ui.jsf: editAbsence: Edit absence from: From noDeputy: No substitute + noPermissionToSeeThisArea: You do not have the required permission to see this area. period: Period personalTaskDuringAbsenceDeputies: Substitutes for personally assigned tasks during the absence personalTaskPermanentDeputies: Permanent substitutes for personally assigned tasks @@ -48,6 +49,8 @@ ch.ivy.addon.portalkit.ui.jsf: nextAbsence: Upcoming absence selectedDeputyFor: Selected user is substitute for selectedUser: Selected user + AccessibilityShortcuts: + processName: Accessibility shortcuts process AllTasks: caseDescription: Case description taskDescription: Task description @@ -134,16 +137,12 @@ ch.ivy.addon.portalkit.ui.jsf: HEADING_3: Heading 3 NORMAL_TEXT: Normal Text MyProfile: - CaseList: Case list DateFormat: Date Format FormattingLanguage: Formatting language General: General Homepage: Homepage Language: Language ProcessList: Process list - SortFieldSelections: - defaultSortFieldLabel: Default sort field - TaskList: Task list byDefault: ' by default' defaultOption: Default ({0}) defaultViewMode: Default view mode @@ -168,8 +167,8 @@ ch.ivy.addon.portalkit.ui.jsf: announcementsDisabled: Announcements are disabled. announcementsEnabled: Announcements are enabled. defaultLanguageRequiredMessage: Announcement for application default language is required. - disable: Disable - enable: Enable + disabled: Disabled + enable: Enable announcement information: You can announce a general information (e.g. Downtime, Changes, etc.) in this area. This message can be seen by all portal users. saveChanges: Save changes tabTitle: Announcements @@ -180,6 +179,7 @@ ch.ivy.addon.portalkit.ui.jsf: applicationHint: Use drag & drop to reorder. applicationLinkRequiredMsg: Please enter portal link. applicationList: + addNewApplication: Add new application applicationSelectionHeader: Select application menuIcon: Menu icon applications: Applications @@ -343,7 +343,7 @@ ch.ivy.addon.portalkit.ui.jsf: FINISHED_TIME: Finished ID: Case Id NAME: Name / Description - OWNER: Owner + OWNER: Case Owners STATE: State deletionNoteContent: The case was destroyed by {0} destroyCaseMessage: This operation cannot be undone. Are you sure you want to destroy this case and all of its tasks? @@ -411,6 +411,7 @@ ch.ivy.addon.portalkit.ui.jsf: addDocument: Add document addNote: Add note allCategories: All Categories + allTypes: All types allowPng: Only png types allowed apply: Apply at: at @@ -458,8 +459,10 @@ ch.ivy.addon.portalkit.ui.jsf: destroyTaskHeaderText: Destroy this task? detail: Details display: Display + displayAsTopMenu: Display as top menu displayName: Display name - dragAndDrop: 'Drag and drop an image or ' + dragAndDropFile: 'Drag and drop a file or ' + dragAndDropImage: 'Drag and drop an image or ' edit: Edit errorAjaxMessage: There is a general exception. errorFileUploadSize: The file size must be lower than {0} @@ -516,7 +519,7 @@ ch.ivy.addon.portalkit.ui.jsf: note: NOTE numberFromBiggerThanTo: '''To'' must be bigger than ''From''.' numberOfSelectedFilter: selected filters - ok: Ok + ok: OK 'on': 'on' pleaseAddDocument: Please add a document with the link above. pleaseAddNote: Please add a note with the link above. @@ -526,10 +529,12 @@ ch.ivy.addon.portalkit.ui.jsf: processes: Processes public: Public remove: Remove + removeSelection: Remove selection reorder: Reorder requiredFieldMessage: This field is required reserve: Reserve reset: Reset + resetFilters: Reset filters resetSettingHeaderText: Reset setting? resetTaskHeaderText: Reset this task? resetToDefaultMessage: This operation cannot be undone. Are you sure you want to reset to default settings? @@ -538,11 +543,13 @@ ch.ivy.addon.portalkit.ui.jsf: restoreToDefaultChartHeaderText: Restore to default charts? role: Role save: Save + saveAll: Save all saveSuccessfully: Data saved successfully. search: Search second: second seconds: seconds seeDetail: See details + select: Select selectAll: Select All selectUsers: Select user(s) selectedDay: '{0} selected day(s)' @@ -569,10 +576,12 @@ ch.ivy.addon.portalkit.ui.jsf: theProcess: The process timeInformation: Time Information timestamp: Timestamp + topMenuItem: Top Menu Item type: Type typeAdmin: All administrators typeAllUsers: All users typeOnlyMe: Only me + uploadHere: Upload here uploadOneHere: Upload one here user: '{0} user' users: Users @@ -580,7 +589,7 @@ ch.ivy.addon.portalkit.ui.jsf: viewExpired: Your current view expired. You will be redirected to the home page. viewMode: View mode visible: Visible - warning: Warning + warning: Warning! welcomeToPortal: Welcome, please login wrongDateFormat: Please enter valid date. year: year @@ -791,6 +800,7 @@ ch.ivy.addon.portalkit.ui.jsf: dashboardIcon: Dashboard icon dashboardPermission: Dashboard permission dashboardTitle: Dashboard title + deleteDashboardMessage: Are you sure you want to delete the "{0}" dashboard? editDashboard: Edit dashboard manageDashboard: Manage dashboard removeDashboardHeader: Remove the "{0}" dashboard @@ -856,6 +866,7 @@ ch.ivy.addon.portalkit.ui.jsf: taskListIntroduction: This widget displays relevant task information according to defined settings. taskStart: Task start taskWidgetConfiguration: Task Widget Configuration + topMenuItemInfo: If the "Top Menu Item" checkbox is checked, the dashboard appears as a top-level item in the navigation bar, sorted by list position. If unchecked, it appears as a sub-item under “Dashboard”, also sorted by list position. widgetInfo: Widget information widgetInfoIcon: Widget Information Icon widgetTitle: Widget Title @@ -1093,7 +1104,7 @@ ch.ivy.addon.portalkit.ui.jsf: toUser: User userSelectionWatermark: Please select a user... taskDetails: - addDocumentHelpText: To upload files, drag & drop or select files + addDocumentHelpText: 'To upload files, drag & drop or ' addNoteHelpText: Write your text here. afterEscalation: After escalation businessCase: Business Case @@ -1111,6 +1122,7 @@ ch.ivy.addon.portalkit.ui.jsf: processingTime: Processing Time setDelayTimestamp: '{0} ({1}) has set delay time to task #{2} to {3}' setExpiryActivatorAndTimeNotes: '{0} and assign {1} as the task escalation activator' + supportFileTypes: ' Upload file type supported: {0}' taskCategory: Task Category taskExpiryDisable: This task does not contain any escalation handling logic, therefore no expiry time can be set. technicalCase: Technical Case @@ -1239,11 +1251,12 @@ ch.ivy.addon.portalkit.ui.jsf: showFullTaskList: Show full task list sort: Sort taskWarning: - createdTaskLeave: 'You are about to leave this page. Please choose one of the following options:
  •     Leave: Discard your changes and move to the selected page.
  •     Cancel: Continue working this task.
' - createdTaskLogout: 'You are about to leave this page. Please choose one of the following options:
  •  Logout: Discard your changes and logout.
  •  Cancel: Continue working this task.
' - resetParkTaskBeforeLeave: 'You are about to leave a task in progress. Please choose one of the following options:
  • Leave: Discard your changes and move to the selected page.
  • Reserve: Discard your changes and keep the task in your task list.
  • Cancel: Continue working this task.
' - resetParkTaskBeforeLogout: 'You are about to leave a task in progress. Please choose one of the following options:
  •     Logout: Discard your changes and logout.
  •     Reserve: Discard your changes and keep the task in your personal task list. Then logout.
  •     - Cancel: Continue working this task.
' + createdTaskLeave: '
You are about to leave this page.
Please choose one of the following options:
  • Leave: Discard your changes and move to the selected page.
  • Cancel: Continue working this task.
' + createdTaskLogout: '
You are about to leave this page.
Please choose one of the following options:
  •  Logout: Discard your changes and logout.
  •  Cancel: Continue working this task.
' + resetParkTaskBeforeLeave: '
You are about to leave a task In progress.
Please choose one of the following options:
  • Leave: Discard your changes and move to the selected page.
  • Reserve: Discard your changes and keep the task in your task list.
  • Cancel: Continue working this + task.
' + resetParkTaskBeforeLogout: '
You are about to leave a task in progress.
Please choose one of the following options:
  •     Logout: Discard your changes and logout.
  •     Reserve: Discard your changes and keep the task in your personal task list. Then logout.
  •   +   Cancel: Continue working this task.
' taskNotFound: The task does not exist or you have insufficient rights to see this task. userProfile: myProfileTitle: My profile @@ -1286,7 +1299,7 @@ Dialogs: noResultsText: There are no results. dashboard: PortalDashboardConfiguration: - NewDashboard: New Dashboard + NewDashboard: Add new dashboard component: CustomDashboardWidget: CouldNotFindLinkedProcess: Could not find the linked process! @@ -1306,7 +1319,7 @@ Dialogs: CaseDetailTitle: Case Details DataDescription: Data and Description destroyCase: Destroy case - CaseOwner: Case Owner + CaseOwner: Case Owners Finished: Finished GlobalSearchText: Cases contain the keyword "{0}" in Case Id{1}. ShowBusinessDetails: Business details @@ -1328,11 +1341,63 @@ Dialogs: axonivy: portal: component: + ChatDashboard: + AddTool: Add tool + Tools: Tools + WelcomeHeaderText: Welcome to the Axon Ivy Portal! + WelcomeText: We are delighted to have you on board. The Axon Ivy Portal is your gateway to a seamless and efficient experience. Whether you are a new user exploring the features or a returning visitor, we're here to assist you every step of the way. ShareLinkDialog: CopyLink: Copy link + Link: Link LinkCopied: Link copied + ToolList: + Attributes: Attributes + Collection: Collection + NoAvailableTools: There are no available tools dashboard: component: + AccessibilityShortcuts: + content: |- +
+
+ Alt + 1Focus on to the Dashboard Tab +
+
+ Alt + 4Focus on to the Case Tab +
+
+ Alt + AFocus on to the first Process +
+
+ TabSequential tabbing through elements +
+
+ Alt + 2Focus on to the Process Tab +
+
+ Alt + 5Focus on to the Search +
+
+ Alt + WFocus on to the first Task +
+
+ EscClose expanded Widgets +
+
+ Alt + 3Focus on to the Tasks Tab +
+
+ Alt + 6Focus on to the User Settings +
+
+ Alt + QFocus on to the first Case +
+
+ EnterConfirm selection +
+
+ title: 'Accessibility Shortcuts. Alt + 1: Focus on to the Dashboard tab. Alt + 2: Focus on to the Process tab. Alt + 3: Focus on to the Tasks tab. Alt + 4: Focus on to the Case tab. Alt + 5: Focus on to the search. Alt + 6: Focus on to the User settings. Alt + A: Focus on to the first Process. + Alt + W: Focus on to the first task. Alt + Q: Focus on to the first case. Tab: Sequential tabbing through elements. Esc: Close expanded widgets. Enter: Confirm selection.' CaseWidgetConfiguration: AddFilter: Add filter ClientStatisticWidget: @@ -1393,11 +1458,53 @@ Dialogs: MaxLabelLenght: '35' maxOptionsLength: '20' Labels: + AI: + Error: + CannotFindUser: Sorry, cannot find any user matched your request. Please try again. + CannotStartTask: Cannot start task has ID {0} + InvalidTaskPriority: 'Invalid task priority. Valid task priorities are: low, normal, high, or exception.' + InvalidTaskState: 'Invalid task state. Valid task states are: open, done, in progress, or error.' + NoMatchingCase: Cannot find any task matched your request + NoMatchingProcesses: No matching processes. + NoMatchingTask: Cannot find any task matched your request + FindCaseAIResult: 'ID: {0}, Name: {1}, Description: {2}, State: {3}' + FindProcessAIResult: ' - ID: {0}, Name: {1}, Description: {2}' + FindTaskAIResult: 'ID: {0}, Name: {1}, Description: {2}, State: {3}, Priority {4}' + FindUserAIResult: 'Username: {0}, Name: {1}, Email: {2}, State: {3}' + FoundCaseHeader: 'Found cases:' + FoundProcessesHeader: 'Found processes:' + FoundTaskHeader: 'Found tasks:' + FoundUsersHeader: 'Found users:' + ProcessInfoHeader: |- + **Process name:** {0} + **Process description:** {1} + ProcessInfoHeaderWithParameters: |- + - **Process name:** {0} + - **Process description:** {1} + - **Number of parameters:** {2} + ProcessParameterInfo: "\t+ {0} ({1})" + ProcessParameterInfoWithValue: |- + - Name: {0} + Description: {1} + Value: + TaskDetailsResult: |- + Details of task **{0} (#{1})**: + {2} AppendTask-Explain: The task is added to the sequence after my task. AppendTheTask: Append the task CreateNewDashboard: Create new dashboard EditDescription: Edit description Enums: + ChatbotCandidateQuestion: + EXPLORE: + header: Explore + question: What are the key features of the Axon Ivy Portal? + INTERACT: + header: Interact + question: List me all the tasks that need completion within the current week + TUTORIAL: + header: Tutorial + question: Where can I find the documentation or tutorials for the Axon Ivy Portal? DashboardStandardCaseColumn: ACTIONS: Actions APPLICATION: Application @@ -1408,7 +1515,7 @@ Labels: FINISHED: Finished Date ID: Id NAME: Name - OWNER: Case Owner + OWNER: Case Owners STATE: State DashboardStandardTaskColumn: ACTIONS: Actions diff --git a/AxonIvyPortal/portal/cms/cms_es.yaml b/AxonIvyPortal/portal/cms/cms_es.yaml index 8e336e0e173..45be74efd61 100644 --- a/AxonIvyPortal/portal/cms/cms_es.yaml +++ b/AxonIvyPortal/portal/cms/cms_es.yaml @@ -23,6 +23,7 @@ ch.ivy.addon.portalkit.ui.jsf: editAbsence: Editar ausencia from: Del noDeputy: Sin sustituto + noPermissionToSeeThisArea: Usted no tiene el permiso necesario para ver esta zona. period: Periodo personalTaskDuringAbsenceDeputies: Sustituye las tareas asignadas personalmente durante la ausencia personalTaskPermanentDeputies: Sustitución permanente de las tareas asignadas personalmente @@ -48,6 +49,8 @@ ch.ivy.addon.portalkit.ui.jsf: nextAbsence: Siguiente ausencia selectedDeputyFor: El usuario seleccionado es el sustituto de selectedUser: Usuario seleccionado + AccessibilityShortcuts: + processName: Atajos de accesibilidad de widgets AllTasks: caseDescription: Descripción de caso taskDescription: Descripción de tarea @@ -134,16 +137,12 @@ ch.ivy.addon.portalkit.ui.jsf: HEADING_3: Rúbrica 3 NORMAL_TEXT: Texto normal MyProfile: - CaseList: Lista de casos DateFormat: Formato de la fecha FormattingLanguage: Lenguaje de formato General: Generales Homepage: Página web Language: Idioma ProcessList: Lista de procesos - SortFieldSelections: - defaultSortFieldLabel: Orden predeterminado - TaskList: Lista de tareas byDefault: ' por defecto' defaultOption: Predeterminado ({0}) defaultViewMode: Modo predeterminado @@ -168,8 +167,8 @@ ch.ivy.addon.portalkit.ui.jsf: announcementsDisabled: Los avisos están deactivados announcementsEnabled: Los avisos están activados defaultLanguageRequiredMessage: 'Texto requerido en el idioma estándard de la aplicación ' - disable: Desactivar - enable: Activar + disabled: Deshabilitado + enable: Activar anuncio information: En esta área puede anunciar una información general (ej. mantenimiento, cambios en la aplicación, etc.). Este mensaje será visible para todos los usuarios. saveChanges: Guardar cambios tabTitle: Avisos @@ -180,6 +179,7 @@ ch.ivy.addon.portalkit.ui.jsf: applicationHint: Use arrastrar y soltar para reordenar. applicationLinkRequiredMsg: Por favor, introduzca el enlace al portal applicationList: + addNewApplication: Añadir nueva aplicación applicationSelectionHeader: Seleccionar aplicación menuIcon: Icono de menú applications: Aplicaciones @@ -345,7 +345,7 @@ ch.ivy.addon.portalkit.ui.jsf: FINISHED_TIME: Terminado ID: ID del caso NAME: Nombre / Descripción - OWNER: Propietario + OWNER: Responsables del proceso STATE: 'Estatus ' deletionNoteContent: El caso fue destruido por {0} destroyCaseMessage: Esta operación no se puede deshacer. ¿Está seguro de que quiere destruir este caso y todas sus tareas? @@ -413,6 +413,7 @@ ch.ivy.addon.portalkit.ui.jsf: addDocument: Agregar documento addNote: Agregar nota allCategories: Todas las categorias + allTypes: Todos los tipos allowPng: Solo se permiten los tipos png apply: Aplicar at: en @@ -460,8 +461,10 @@ ch.ivy.addon.portalkit.ui.jsf: destroyTaskHeaderText: ¿Destruir esta tarea? detail: Detalles display: Mostrar + displayAsTopMenu: Mostrar como menú principal displayName: Nombre de pantalla - dragAndDrop: 'Arrastre y suelte una imagen o ' + dragAndDropFile: 'Arrastre y suelte un archivo o ' + dragAndDropImage: 'Arrastre y suelte una imagen o ' edit: Editar errorAjaxMessage: Error general errorFileUploadSize: El tamaño deberá ser inferior a {0} @@ -518,7 +521,7 @@ ch.ivy.addon.portalkit.ui.jsf: note: Nota numberFromBiggerThanTo: Para" debe ser mayor que "De". numberOfSelectedFilter: Filtros seleccionados - ok: Ok + ok: OK 'on': en pleaseAddDocument: Por favor agregue documentos usando el enlace superior pleaseAddNote: Por favor agregue notas usando el enlace superior @@ -528,10 +531,12 @@ ch.ivy.addon.portalkit.ui.jsf: processes: Procesos public: Público remove: Retirar + removeSelection: Eliminar selección reorder: Reordenar requiredFieldMessage: este campo es obligatorio reserve: Reservar reset: Reiniciar + resetFilters: Restablecer filtros resetSettingHeaderText: ¿Resetear la configuración? resetTaskHeaderText: ¿Reiniciar esta tarea? resetToDefaultMessage: Esta operación no se puede deshacer. ¿Estás seguro de que quieres restablecer la configuración por defecto? @@ -540,11 +545,13 @@ ch.ivy.addon.portalkit.ui.jsf: restoreToDefaultChartHeaderText: ¿Restablecer a los gráficos por defecto? role: Rol save: Guardar + saveAll: Guardar todos saveSuccessfully: Datos guardados exitosamente. search: Buscar second: segundo seconds: segundos seeDetail: Mostrar detalles + select: Seleccionar selectAll: Seleccionar todo selectUsers: Seleccione usuario(s) selectedDay: '{0} Día(s) selecionados' @@ -571,10 +578,12 @@ ch.ivy.addon.portalkit.ui.jsf: theProcess: El proceso timeInformation: Informaciones de tiempo timestamp: Marca de tiempo + topMenuItem: Elemento del menú superior type: Tipo typeAdmin: Todos los administradores typeAllUsers: Todos los usuarios typeOnlyMe: Solo yo + uploadHere: Cargue aquí uploadOneHere: Seleccionar user: '{0} usuario' users: Usuarios @@ -582,7 +591,7 @@ ch.ivy.addon.portalkit.ui.jsf: viewExpired: Su vista actual expiró. Serás redirigido a la página de inicio. viewMode: Modo de visualización visible: Visible - warning: Advertencia + warning: Advertencia! welcomeToPortal: Bienvenido, por favor inicie su sesión wrongDateFormat: Por favor ingrese una fecha válida. year: Año @@ -788,6 +797,7 @@ ch.ivy.addon.portalkit.ui.jsf: dashboardIcon: Icono del panel de control dashboardPermission: Permiso de tablero dashboardTitle: Título del tablero + deleteDashboardMessage: ¿Está seguro de que desea eliminar el "{0}" cuadro de mandos? editDashboard: Editar tablero manageDashboard: Administrar tablero removeDashboardHeader: Borrar el tablero "{0}" @@ -853,6 +863,7 @@ ch.ivy.addon.portalkit.ui.jsf: taskListIntroduction: Este widget muestra la información relevante de la tarea según la configuración definida. taskStart: Iniciar tarea taskWidgetConfiguration: Configuración del widget de tareas + topMenuItemInfo: Si la casilla "Elemento del menú superior" está marcada, el tablero aparece como un elemento de nivel superior en la barra de navegación, ordenado según su posición en la lista. Si no está marcada, aparece como un subelemento en "Dashboard", también ordenado por posición en la lista. widgetInfo: Información del widget widgetInfoIcon: Icono de información del widget widgetTitle: Título del widget @@ -1090,7 +1101,7 @@ ch.ivy.addon.portalkit.ui.jsf: toUser: Usuario userSelectionWatermark: Por favor seleccione un usuario... taskDetails: - addDocumentHelpText: Para cargar archivos, arrastrar y soltar o seleccionar archivos + addDocumentHelpText: 'Para cargar archivos, arrastrar y soltar o ' addNoteHelpText: Escriba su texto aquí. afterEscalation: Después de la escalada businessCase: Caso comercial @@ -1108,6 +1119,7 @@ ch.ivy.addon.portalkit.ui.jsf: processingTime: Tiempo de procesado setDelayTimestamp: '{0} ({1}) Ha modificado el tiempo de demora para la tarea #{2} a {3}' setExpiryActivatorAndTimeNotes: '{0} y asignar {1} como el usuario de la tarea escalada' + supportFileTypes: 'Tipos de archivos admitidos para cargar: {0}' taskCategory: Categoría de tarea taskExpiryDisable: Esta tarea no tiene manejo lógico de escalado, por lo tanto no se puede establecer el tiempo de expiración. technicalCase: Caso técnico @@ -1236,11 +1248,11 @@ ch.ivy.addon.portalkit.ui.jsf: showFullTaskList: Mostrar lista de tareas completa sort: Ordenar taskWarning: - createdTaskLeave: 'Va a salir de esta página. Por favor selecione una de las siguientes opciones:
  •     Salir: No guardará sus cambios y navegará a la página seleccionada
  •     Cancelar: Continue trabajando en esta tarea.
' - createdTaskLogout: 'Va a salir de esta página. Por favor selecione una de las siguientes opciones:
  •     Cerrar sesión: No guardará sus cambios y se cerrará la sesión.
  •  Cancelar: Continue trabajando en esta tarea.
' - resetParkTaskBeforeLeave: 'Va a salir de esta página. Por favor selecione una de las siguientes opciones:
  • Salir: No guardará sus cambios y navegará a la página seleccionada
  • Reservar: No guardará sus cambios y esta tarea quedara reservada para usted.
  • Cancelar: Continue trabajando en esta - tarea.
' - resetParkTaskBeforeLogout: 'Va a salir de esta página. Por favor selecione una de las siguientes opciones:
  • Salir: no guardará sus cambios y volverá a la página anterior.
  • Reservar: No guardará sus cambios, volverá a la página anterior pero la tarea quedara reservada para usted.
  • Cancelar: + createdTaskLeave: '
    Va a salir de esta página. Por favor selecione una de las siguientes opciones:
    •     Salir: No guardará sus cambios y navegará a la página seleccionada
    •     Cancelar: Continue trabajando en esta tarea.
    ' + createdTaskLogout: '
    Va a salir de esta página.
    Por favor selecione una de las siguientes opciones:
    •     Cerrar sesión: No guardará sus cambios y se cerrará la sesión.
    •  Cancelar: Continue trabajando en esta tarea.
    ' + resetParkTaskBeforeLeave: '
    Va a salir de esta página.
    Por favor selecione una de las siguientes opciones:
    • Salir: No guardará sus cambios y navegará a la página seleccionada
    • Reservar: No guardará sus cambios y esta tarea quedara reservada para usted.
    • Cancelar: Continue trabajando + en esta tarea.
    ' + resetParkTaskBeforeLogout: '
    Va a salir de esta página.
    Por favor selecione una de las siguientes opciones:
    • Salir: no guardará sus cambios y volverá a la página anterior.
    • Reservar: No guardará sus cambios, volverá a la página anterior pero la tarea quedara reservada para usted.
    • Cancelar: Continue trabajando en esta tarea.
    ' taskNotFound: La tarea no existe o no los tiene derechos suficientes para ver esta tarea. userProfile: @@ -1284,7 +1296,7 @@ Dialogs: noResultsText: No hay resultados. dashboard: PortalDashboardConfiguration: - NewDashboard: Nuevo panel de control + NewDashboard: Añadir un nuevo cuadro de mandos component: CustomDashboardWidget: CouldNotFindLinkedProcess: ¡No se pudo encontrar el proceso vinculado! @@ -1304,7 +1316,7 @@ Dialogs: CaseDetailTitle: Detalles del caso DataDescription: Datos y Descripción destroyCase: Borrar caso - CaseOwner: Responsable del proceso + CaseOwner: Responsables del proceso Finished: Terminado GlobalSearchText: Los casos contienen la palabra clave "{0}" en ID del caso{1}. ShowBusinessDetails: Detalles del negocio @@ -1328,9 +1340,19 @@ Dialogs: component: ShareLinkDialog: CopyLink: Copiar enlace + Link: Enlace LinkCopied: ¡Enlace copiado dashboard: component: + AccessibilityShortcuts: + content: "
    \n
    \n Alt + 1Enfocar en la pestaña del Panel de Control\n
    \n
    \n Alt + 4Enfocar en la\ + \ pestaña de Casos\n
    \n
    \n Alt + AEnfocar en el primer proceso\n
    \n
    \n TabTabbing secuencial a través de\ + \ elementos\n
    \n
    \n Alt + 2Enfocar en la pestaña de Procesos\n
    \n
    \n Alt + 5Enfocar en la búsqueda\n
    \n\ + \
    \n Alt + WEnfocar en la primera tarea\n
    \n
    \n EscCerrar widgets expandidos/Cerrar menús contextuales\n
    \n\ + \
    \n Alt + 3Enfocar en la pestaña de Tareas\n
    \n
    \n Alt + 6Enfocar en la pestaña del Panel de Control\n
    \n\ + \
    \n Alt + QEnfocar en el primer caso\n
    \n
    \n EnterConfirmar selección\n
    \n \n
    " + title: 'Atajos de accesibilidad. Alt + 1: Enfocar en la pestaña del Panel de Control. Alt + 2: Enfocar en la pestaña de Procesos. Alt + 3: Enfocar en la pestaña de Tareas. Alt + 4: Enfocar en la pestaña de Casos. Alt + 5: Enfocar en la búsqueda. Alt + 6: Enfocar en la pestaña del Panel de + Control. Alt + A: Enfocar en el primer proceso. Alt + W: Enfocar en la primera tarea. Alt + Q: Enfocar en el primer caso. Tab: Tabbing secuencial a través de elementos. Esc: Cerrar widgets expandidos/Cerrar menús contextuales. Enter: Confirmar selección' CaseWidgetConfiguration: AddFilter: Añadir filtro ClientStatisticWidget: @@ -1388,6 +1410,28 @@ Dialogs: invalidSizeMessage: ¡El archivo es muy grande! maximumFileUploadElement: Ya existe un elemento de subir documentos Labels: + AI: + Error: + CannotFindUser: '' + CannotStartTask: '' + InvalidTaskPriority: '' + InvalidTaskState: '' + NoMatchingCase: '' + NoMatchingProcesses: '' + NoMatchingTask: '' + FindCaseAIResult: '' + FindProcessAIResult: '' + FindTaskAIResult: '' + FindUserAIResult: '' + FoundCaseHeader: '' + FoundProcessesHeader: '' + FoundTaskHeader: '' + FoundUsersHeader: '' + ProcessInfoHeader: '' + ProcessInfoHeaderWithParameters: '' + ProcessParameterInfo: '' + ProcessParameterInfoWithValue: '' + TaskDetailsResult: '' AppendTask-Explain: La tarea es añadida a la secuencia después de mi tarea. AppendTheTask: Anexar la tarea CreateNewDashboard: Crear un nuevo cuadro de mandos @@ -1403,7 +1447,7 @@ Labels: FINISHED: Fecha de finalización ID: Id NAME: Nombre - OWNER: Propietario del caso + OWNER: Responsables del proceso STATE: Estado DashboardStandardTaskColumn: ACTIONS: Acciones diff --git a/AxonIvyPortal/portal/cms/cms_fr.yaml b/AxonIvyPortal/portal/cms/cms_fr.yaml index 1298149d76d..df13469df8e 100644 --- a/AxonIvyPortal/portal/cms/cms_fr.yaml +++ b/AxonIvyPortal/portal/cms/cms_fr.yaml @@ -23,6 +23,7 @@ ch.ivy.addon.portalkit.ui.jsf: editAbsence: Editer les absences from: Du noDeputy: Aucun substitut + noPermissionToSeeThisArea: Vous n'avez pas l'autorisation requise pour visiter cette zone. period: Période personalTaskDuringAbsenceDeputies: Remplacer les tâches assignées personnellement pendant l'absence personalTaskPermanentDeputies: Remplacement permanent des tâches confiées personnellement @@ -48,6 +49,8 @@ ch.ivy.addon.portalkit.ui.jsf: nextAbsence: Absence à venir selectedDeputyFor: L'utilisateur sélectionné est un substitut de selectedUser: Utilisateur sélectionné + AccessibilityShortcuts: + processName: Raccourcis d'accessibilité Widgets AllTasks: caseDescription: Description du dossier taskDescription: Description de la tâche @@ -134,16 +137,12 @@ ch.ivy.addon.portalkit.ui.jsf: HEADING_3: Rubrique 3 NORMAL_TEXT: Texte normal MyProfile: - CaseList: Liste de cas DateFormat: Format de la date FormattingLanguage: Langue de mise en forme General: Généraux Homepage: Page d'accueil Language: Langue ProcessList: Liste des processus - SortFieldSelections: - defaultSortFieldLabel: Champ de tri par défaut - TaskList: Liste des tâches byDefault: ' par défaut' defaultOption: Par défaut ({0}) defaultViewMode: Mode de vue par défaut @@ -168,8 +167,8 @@ ch.ivy.addon.portalkit.ui.jsf: announcementsDisabled: Les annonces sont désactivées. announcementsEnabled: Les annonces sont activées. defaultLanguageRequiredMessage: L'annonce de la langue par défaut de l'application est requise. - disable: Désactiver - enable: Activer + disabled: Désactivé + enable: Activer l'annonce information: Vous pouvez annoncer une information générale (par exemple, temps d'arrêt, modifications, etc.) dans cette zone. Ce message peut être vu par tous les utilisateurs du portail. saveChanges: Enregistrer les modifications tabTitle: Annonces @@ -180,6 +179,7 @@ ch.ivy.addon.portalkit.ui.jsf: applicationHint: L'ordre peut être modifié par glisser/déposer applicationLinkRequiredMsg: Veuillez rentrer le lien vers le Portail applicationList: + addNewApplication: Ajouter une nouvelle application applicationSelectionHeader: Sélectionner une application menuIcon: Icône de menu applications: Applications @@ -342,7 +342,7 @@ ch.ivy.addon.portalkit.ui.jsf: FINISHED_TIME: Terminé ID: Id du dossier NAME: Nom / Description - OWNER: Propriétaire + OWNER: Responsables de processus STATE: Etat deletionNoteContent: Ce dossier a été supprimé par {0} destroyCaseMessage: Cette opération ne peut pas être annulée. Êtes-vous sûr de vouloir supprimer ce dossier et toutes les tâches associées ? @@ -410,6 +410,7 @@ ch.ivy.addon.portalkit.ui.jsf: addDocument: Ajouter un document addNote: Ajouter une note allCategories: Toutes les catégories + allTypes: Tous les types allowPng: Seulement les types .png autorisés apply: Utiliser at: le @@ -457,8 +458,10 @@ ch.ivy.addon.portalkit.ui.jsf: destroyTaskHeaderText: Détruire cette tâche ? detail: Détails display: Présenter + displayAsTopMenu: Afficher en tant que menu principal displayName: Affichez le nom - dragAndDrop: 'Glisser-déposer une image ou ' + dragAndDropFile: 'Glisser-déposer un fichier ou ' + dragAndDropImage: 'Glisser-déposer une image ou ' edit: Editer errorAjaxMessage: Il y a une exception générale. errorFileUploadSize: La taille du fichier doit être inférieure à {0}. @@ -515,7 +518,7 @@ ch.ivy.addon.portalkit.ui.jsf: note: NOTE numberFromBiggerThanTo: L'adresse de destination doit être plus grande que l'adresse de départ. numberOfSelectedFilter: filtres sélectionnés - ok: Ok + ok: OK 'on': le pleaseAddDocument: Veuillez ajouter un document avec le lien ci-dessus. pleaseAddNote: Veuillez ajouter une note avec le lien ci-dessus. @@ -525,10 +528,12 @@ ch.ivy.addon.portalkit.ui.jsf: processes: Processus public: Publique remove: Retirer + removeSelection: Retirer la sélection reorder: Réorganiser requiredFieldMessage: Ce champ est obligatoire reserve: Enregistrer reset: Réinitialiser + resetFilters: Réinitialiser les filtres resetSettingHeaderText: Rétablir le réglage ? resetTaskHeaderText: Réinitialiser cette tâche ? resetToDefaultMessage: Cette opération ne peut pas être annulée. Êtes-vous sûr de vouloir rétablir les paramètres par défaut ? @@ -537,11 +542,13 @@ ch.ivy.addon.portalkit.ui.jsf: restoreToDefaultChartHeaderText: Rétablir les graphiques par défaut ? role: Rôle save: Enregistrer + saveAll: Enregistrer tout saveSuccessfully: Les données ont été correctement enregistrées search: Recherche second: seconde seconds: secondes seeDetail: Afficher les détails + select: Sélectionner selectAll: Sélectionner tout selectUsers: Sélectionnez un ou plusieurs utilisateurs selectedDay: '{0} jour(s) sélectionné(s)' @@ -568,10 +575,12 @@ ch.ivy.addon.portalkit.ui.jsf: theProcess: Le processus timeInformation: Informations sur le temps timestamp: Horodatage + topMenuItem: Élément du menu supérieur type: Type typeAdmin: Tous les administrateurs typeAllUsers: Tous les utilisateurs typeOnlyMe: Seulement pour moi + uploadHere: Téléchargez ici uploadOneHere: Téléchargez-en un ici user: '{0} utilisateur' users: Utilisateurs @@ -579,7 +588,7 @@ ch.ivy.addon.portalkit.ui.jsf: viewExpired: Votre vue actuelle a expiré. Vous allez être redirigé vers la page d'accueil. viewMode: Mode d'affichage visible: Visible - warning: Attention + warning: Attention! welcomeToPortal: Bienvenue, veuillez vous connecter wrongDateFormat: Veuillez entrer une date valide year: an @@ -785,6 +794,7 @@ ch.ivy.addon.portalkit.ui.jsf: dashboardIcon: Icône du tableau de bord dashboardPermission: Autorisation du tableau de bord dashboardTitle: Titre du tableau de bord + deleteDashboardMessage: Êtes-vous sûr de vouloir supprimer le "{0}" tableau de bord? editDashboard: Modifier le tableau de bord manageDashboard: Gérer le tableau de bord removeDashboardHeader: Supprimez le tableau de bord "{0}". @@ -850,6 +860,8 @@ ch.ivy.addon.portalkit.ui.jsf: taskListIntroduction: Ce widget affiche des informations pertinentes sur les tâches selon les paramètres définis. taskStart: Commencer la tâche taskWidgetConfiguration: Configuration du widget de tâches + topMenuItemInfo: Si la case "Is Top Menu Item" est cochée, le tableau de bord apparaît comme un élément de niveau supérieur dans la barre de navigation, trié selon sa position dans la liste. Si elle n'est pas cochée, il apparaît comme un sous-élément sous "Tableaux de bord", également trié par position + dans la liste. widgetInfo: Informations sur le widget widgetInfoIcon: Icône d'information du widget widgetTitle: Titre du widget @@ -1087,7 +1099,7 @@ ch.ivy.addon.portalkit.ui.jsf: toUser: Utilisateur userSelectionWatermark: Veuillez sélectionner un utilisateur… taskDetails: - addDocumentHelpText: Pour ajouter des fichiers, glissez-les ou sélectionnez-les + addDocumentHelpText: 'Pour ajouter des fichiers, glissez-les ou ' addNoteHelpText: Ecrivez votre texte ici afterEscalation: Après escalade businessCase: Dossier @@ -1105,6 +1117,7 @@ ch.ivy.addon.portalkit.ui.jsf: processingTime: Durée de traitement setDelayTimestamp: '{0} ({1}) a fixé le délai d''attente de la tâche #{2} à {3}' setExpiryActivatorAndTimeNotes: '{0} et assigner {1} comme activateur d''escalade de tâches' + supportFileTypes: 'Types de fichiers pris en charge pour le téléchargement : {0}' taskCategory: Catégorie de tâche taskExpiryDisable: Cette tâche ne contient pas de logique d'escalade. Aucune période d'expiration ne peut donc être définie. technicalCase: Dossier technique @@ -1233,12 +1246,12 @@ ch.ivy.addon.portalkit.ui.jsf: showFullTaskList: Voir la liste complète des tâches sort: Trier taskWarning: - createdTaskLeave: 'Vous êtes sur le point de quitter cette page. Choisissez l''une des options suivantes :
    • Quitter : abandonnez vos modifications et allez à la page choisie.
    • Annuler : continuez à travailler sur cette tâche.
    ' - createdTaskLogout: 'Vous êtes sur le point de quitter cette page. Choisissez l''une des options suivantes :
    •   Déconnecter : abandonnez vos modifications et déconnectez-vous.
    •   Annuler : continuez à travailler sur cette tâche.
    ' - resetParkTaskBeforeLeave: 'Vous êtes sur le point de laisser une tâche en cours. Choisissez l''une des options suivantes :
    • Quitter : abandonnez vos modifications et allez à la page choisie.
    • Enregistrer : abandonnez vos modifications et conservez la tâche dans votre liste de - tâches personnelles. Ensuite déconnectez-vous.
    • Annuler : continuez à travailler sur cette tâche.
    ' - resetParkTaskBeforeLogout: 'Vous êtes sur le point de laisser une tâche en cours. Choisissez l''une des options suivantes :
    •     Déconnecter : abandonnez vos modifications et déconnectez-vous.
    •     Enregistrer : annulez vos modifications et conservez la tâche - dans votre liste de tâches personnelles. Ensuite, déconnectez-vous.
    •     Annuler : continuez à travailler sur cette tâche.
    ' + createdTaskLeave: '
    Vous êtes sur le point de quitter cette page.
    Choisissez l''une des options suivantes :
    • Quitter : abandonnez vos modifications et allez à la page choisie.
    • Annuler : continuez à travailler sur cette tâche.
    ' + createdTaskLogout: '
    Vous êtes sur le point de quitter cette page.
    Choisissez l''une des options suivantes :
    •   Déconnecter : abandonnez vos modifications et déconnectez-vous.
    •   Annuler : continuez à travailler sur cette tâche.
    ' + resetParkTaskBeforeLeave: '
    Vous êtes sur le point de laisser une tâche en cours.
    Choisissez l''une des options suivantes :
    • Quitter : abandonnez vos modifications et allez à la page choisie.
    • Enregistrer : abandonnez vos modifications et conservez la tâche dans + votre liste de tâches personnelles. Ensuite déconnectez-vous.
    • Annuler : continuez à travailler sur cette tâche.
    ' + resetParkTaskBeforeLogout: '
    Vous êtes sur le point de laisser une tâche en cours.
    Choisissez l''une des options suivantes :
    •     Déconnecter : abandonnez vos modifications et déconnectez-vous.
    •     Enregistrer : annulez vos modifications et + conservez la tâche dans votre liste de tâches personnelles. Ensuite, déconnectez-vous.
    •     Annuler : continuez à travailler sur cette tâche.
    ' taskNotFound: cette tâche n'existe pas ou vous n'avez pas l'autorisation de la voir. userProfile: myProfileTitle: Mon profil @@ -1281,7 +1294,7 @@ Dialogs: noResultsText: Il n'y a pas de résultats. dashboard: PortalDashboardConfiguration: - NewDashboard: Nouveau tableau de bord + NewDashboard: Ajouter un nouveau tableau de bord component: CustomDashboardWidget: CouldNotFindLinkedProcess: Impossible de trouver le processus lié ! @@ -1301,7 +1314,7 @@ Dialogs: CaseDetailTitle: Détail du cas DataDescription: Données et description destroyCase: détruire le cas - CaseOwner: Responsable de processus + CaseOwner: Responsables de processus Finished: Terminé GlobalSearchText: Les cas contiennent le mot-clé "{0}" dans Id du dossier{1}. ShowBusinessDetails: Détails de l'entreprise @@ -1323,11 +1336,63 @@ Dialogs: axonivy: portal: component: + ChatDashboard: + AddTool: Ajouter un outil + Tools: Outils + WelcomeHeaderText: Bienvenue sur le portail Axon Ivy ! + WelcomeText: Nous sommes ravis de vous compter parmi nous. Le portail Axon Ivy est votre porte d'entrée pour une expérience transparente et efficace. Que vous soyez un nouvel utilisateur qui explore les fonctionnalités ou un visiteur habituel, nous sommes là pour vous aider à chaque étape. ShareLinkDialog: CopyLink: Copier le lien + Link: Lien LinkCopied: Lien copié + ToolList: + Attributes: Attributs + Collection: Collection + NoAvailableTools: Il n'y a pas d'outils disponibles dashboard: component: + AccessibilityShortcuts: + content: |- +
    +
    + Alt + 1Se focaliser sur l’onglet du Dashboard +
    +
    + Alt + 4Se focaliser sur l’onglet des cas +
    +
    + Alt + ASe focaliser sur le premier processus +
    +
    + TabNavigation séquentielle entre les éléments +
    +
    + Alt + 2Se focaliser sur l’onglet des processus +
    +
    + Alt + 5Se focaliser sur la recherche +
    +
    + Alt + WSe focaliser sur la première tâche +
    +
    + EscFermer les widgets agrandis/Fermer les menus contextuels +
    +
    + Alt + 3Se focaliser sur l’onglet des tâches +
    +
    + Alt + 6Se focaliser sur les paramètres utilisateur +
    +
    + Alt + QSe focaliser sur le premier cas +
    +
    + EnterConfirmer la sélection +
    +
    + title: 'Raccourcis d’accessibilité. Alt + 1: Fokus auf die Dashboards. Alt + 2: Fokus auf die Prozesse. Alt + 3: Fokus auf die Aufgaben. Alt + 4: Fokus auf die Fälle. Alt + 5: Fokus auf die Suche. Alt + 6: Fokus auf die User Einstellungen. Alt + A: Fokus auf den ersten Prozess. Alt + W: + Fokus auf die erste Aufgabe. Alt + Q: Fokus auf den ersten Fall. Tab: Sequentielles Durchlaufen von Elementen. Esc: Erweiterte Widgets schließen/Kontext Menüs schließen. Enter: Auswahl bestätigen' CaseWidgetConfiguration: AddFilter: Ajouter un filtre ClientStatisticWidget: @@ -1385,11 +1450,43 @@ Dialogs: invalidSizeMessage: Le fichier est trop volumineux ! maximumFileUploadElement: Il existe déjà un élément de téléchargement de fichiers Labels: + AI: + Error: + CannotFindUser: '' + CannotStartTask: '' + InvalidTaskPriority: '' + InvalidTaskState: '' + NoMatchingCase: '' + NoMatchingProcesses: '' + NoMatchingTask: '' + FindCaseAIResult: '' + FindProcessAIResult: '' + FindTaskAIResult: '' + FindUserAIResult: '' + FoundCaseHeader: '' + FoundProcessesHeader: '' + FoundTaskHeader: '' + FoundUsersHeader: '' + ProcessInfoHeader: '' + ProcessInfoHeaderWithParameters: '' + ProcessParameterInfo: '' + ProcessParameterInfoWithValue: '' + TaskDetailsResult: '' AppendTask-Explain: La tâche est ajoutée à la séquence après ma tâche. AppendTheTask: Ajouter la tâche CreateNewDashboard: Créer un nouveau tableau de bord EditDescription: Editer la description Enums: + ChatbotCandidateQuestion: + EXPLORE: + header: Explore + question: Quelles sont les principales caractéristiques du portail Axon Ivy ? + INTERACT: + header: Interact + question: Listez toutes les tâches qui doivent être accomplies dans la semaine en cours + TUTORIAL: + header: Tutorial + question: Où puis-je trouver la documentation ou les tutoriels pour le portail Axon Ivy ? DashboardStandardCaseColumn: ACTIONS: Actions APPLICATION: Application @@ -1400,7 +1497,7 @@ Labels: FINISHED: Date d'achèvement ID: Id NAME: Nom - OWNER: Propriétaire du dossier + OWNER: Responsables de processus STATE: État DashboardStandardTaskColumn: ACTIONS: Actions diff --git a/AxonIvyPortal/portal/cms/images/AIAssistant/DefaultLogo.png b/AxonIvyPortal/portal/cms/images/AIAssistant/DefaultLogo.png new file mode 100644 index 00000000000..9d1b71808cb Binary files /dev/null and b/AxonIvyPortal/portal/cms/images/AIAssistant/DefaultLogo.png differ diff --git a/AxonIvyPortal/portal/config/rest-clients.yaml b/AxonIvyPortal/portal/config/rest-clients.yaml index b7c49652e43..1d565dba5ca 100644 --- a/AxonIvyPortal/portal/config/rest-clients.yaml +++ b/AxonIvyPortal/portal/config/rest-clients.yaml @@ -14,3 +14,11 @@ RestClients: SpecUrl: https://raw.githubusercontent.com/DeepLcom/openapi/main/openapi.yaml Namespace: com.deepl.api.v2.client ResolveFully: true + PortalAI (LangChain Server): + UUID: 43e90b1f-7c7d-4a12-be4a-f4ee87d23e0a + Url: http://localhost:8018/ + Features: + - ch.ivyteam.ivy.rest.client.mapper.JsonFeature + OpenAPI: + SpecUrl: http://localhost:8018/openapi.json + Namespace: localhost.client diff --git a/AxonIvyPortal/portal/config/variables.yaml b/AxonIvyPortal/portal/config/variables.yaml index 8822454e377..c7242e6ff95 100644 --- a/AxonIvyPortal/portal/config/variables.yaml +++ b/AxonIvyPortal/portal/config/variables.yaml @@ -72,8 +72,8 @@ Variables: # Set URL to download Axon Ivy mobile app on Google Play. GooglePlayURL: 'https://play.google.com/store/apps/details?id=com.axonivy&pli=1' - # You can configure the look and feel for dashboard according to your needs via this json file. - # This setting will be taken over for all other dashboard. + # You can configure the look and feel of the dashboard according to your needs via this JSON file. + # These settings will apply to all other dashboards. # [file: json] Dashboard: # You can customize the name and icon of the main menu entry for Portal dashboards via this JSON file. @@ -99,25 +99,7 @@ Variables: ShowInformation: true Tasks: - # The standard sets of filters that will be used as the public filters in the task list. - # [file: json] - TaskFilters: - - # Task list refresh interval in seconds. - RefreshInterval: 10000 - - # Set to true to disable counting task in task list. - DisableCount: false - - # The standard sort field of task list - # [enum: PRIORITY, NAME, ACTIVATOR, ID, CREATION_TIME, EXPIRY_TIME, COMPLETED_ON, STATE, CATEGORY] - SortField: ID - - # The standard sort field of task list - # [enum: ASC, DESC] - SortDirection: DESC - - # For switch behaviours (run the task or access task details) when clicking on a task in task list page, task widget of dashboard and task list in case details page. + # For switch behaviours (run the task or access task details) when clicking on a task in task widget of dashboard and task list in case details page. # [enum: ACCESS_TASK_DETAILS, RUN_TASK] BehaviourWhenClickingOnLineInTaskList: RUN_TASK @@ -132,27 +114,12 @@ Variables: ShowDurationTime: true Cases: - # The standard sets of filters that will be used as the public filters in the case list. - # [file: json] - CaseFilters: - # Set to true to enable filtering case owner when cases are queried. - # This setting affects all case queries, e.g. for case list, global search, statistic. + # This setting affects all case queries, e.g. for case widget, global search, statistic. EnableOwner: false - # Set to true to disable counting case in case list. - DisableCount: false - - # The standard sort field of case list - # [enum: NAME, CREATOR, OWNER, ID, CREATION_TIME, FINISHED_TIME, STATE, ELAPSED_TIME, CATEGORY] - SortField: ID - - # The standard sort direction of case list - # [enum: ASC, DESC] - SortDirection: DESC - - # Set to true to hide case creator in case list, case widget and case details. - # This setting affects all case queries, e.g. for case list, global search, statistic. + # Set to true to hide case creator in case widget and case details. + # This setting affects all case queries, e.g. for case widget, global search, statistic. HideCaseCreator: false # You can configure the look and feel for case details according to your needs via this json file. @@ -221,7 +188,7 @@ Variables: # This setting affects in Tasks, Cases and Statistic results. HideYear: false - # Set to true to enable date filtering with time. This setting affects on task list, case list, statistic. + # Set to true to enable date filtering with time. This setting affects on task widget, case widget, statistic. DateFilterWithTime: false # Set this property to true to enable process viewer option in Task/Case actions @@ -290,8 +257,9 @@ Variables: # Otherwise, just hidden cases which were generated by Portal will be deleted. PortalDeleteAllFinishedHiddenCases: false - # By default, portal will query only tasks and cases which don't have hide information (store in either additional property or custom field) - # Set it to false will ingore this feature + # By default, the portal will query only tasks and cases that do not have hidden information + # (stored in either an additional property or a custom field). + # Setting this to false will ignore this feature. PortalHiddenTaskCaseExcluded: true # By default, Portal will redirect to Login Page if login is required and user is unknown. diff --git a/AxonIvyPortal/portal/config/variables/Portal/ClientStatistic.json b/AxonIvyPortal/portal/config/variables/Portal/ClientStatistic.json index b396995683d..024a0a2d2b3 100644 --- a/AxonIvyPortal/portal/config/variables/Portal/ClientStatistic.json +++ b/AxonIvyPortal/portal/config/variables/Portal/ClientStatistic.json @@ -161,7 +161,7 @@ } ], "descriptions": [ - { + { "locale": "de", "value": "Dieses Balkendiagramm zeigt alle Aufgaben an, die der Benutzer bearbeiten kann, gruppiert nach Priorität." }, @@ -696,19 +696,19 @@ "names": [ { "locale": "de", - "value": "Fällig Heute" + "value": "Heute fällige Aufgaben" }, { "locale": "en", - "value": "Due Today" + "value": "Tasks Due Today" }, { "locale": "fr", - "value": "Dû Aujourd'hui" + "value": "Tâches à effectuer aujourd'hui" }, { "locale": "es", - "value": "Vence Hoy" + "value": "Tareas para hoy" } ], "descriptions": [ diff --git a/AxonIvyPortal/portal/config/variables/Portal/Dashboard.json b/AxonIvyPortal/portal/config/variables/Portal/Dashboard.json index 1565091a5d6..fe24c2736a4 100644 --- a/AxonIvyPortal/portal/config/variables/Portal/Dashboard.json +++ b/AxonIvyPortal/portal/config/variables/Portal/Dashboard.json @@ -1,7 +1,7 @@ [ { "id": "1", - "version": "11.4.0", + "version": "12.0.0", "templateId": "default-portal-dashboard-template", "titles": [ { @@ -51,7 +51,6 @@ "y": 2 }, "enableQuickSearch": true, - "rowsPerPage": 5, "columns": [ { "field": "start" @@ -61,21 +60,17 @@ }, { "field": "id", - "visible": false, - "quickSearch": false + "visible": false }, { - "field": "name", - "quickSearch": true + "field": "name" }, { "field": "description", - "visible": false, - "quickSearch": false + "visible": false }, { - "field": "activator", - "quickSearch": false + "field": "activator" }, { "field": "state", @@ -90,8 +85,7 @@ }, { "field": "category", - "visible": false, - "quickSearch": false + "visible": false }, { "field": "actions" @@ -140,27 +134,23 @@ "x": 3, "y": 8 }, - "rowsPerPage": 5, + "enableQuickSearch": true, "columns": [ { - "field": "id", - "quickSearch": false + "field": "id" }, { - "field": "name", - "quickSearch": true + "field": "name" }, { "field": "description", - "visible": false, - "quickSearch": false + "visible": false }, { "field": "state" }, { - "field": "creator", - "quickSearch": false + "field": "creator" }, { "field": "startTimestamp" @@ -171,8 +161,7 @@ }, { "field": "category", - "visible": false, - "quickSearch": false + "visible": false }, { "field": "actions" @@ -328,5 +317,220 @@ "permissions": [ "Everybody" ] + }, + { + "id": "default-task-list-dashboard", + "version": "12.0.0", + "templateId": "create-from-scratch", + "titles": [ + { + "locale": "en", + "value": "Tasks" + }, + { + "locale": "fr", + "value": "Tâches" + }, + { + "locale": "de", + "value": "Aufgaben" + }, + { + "locale": "es", + "value": "Tareas" + } + ], + "icon": "si-task-list-edit", + "description": "Default Task List Dashboard", + "widgets": [ + { + "type": "task", + "id": "default_task_list_dashboard_task_1", + "names": [ + { + "locale": "en", + "value": "Your Tasks" + }, + { + "locale": "de", + "value": "Ihre Aufgaben" + }, + { + "locale": "fr", + "value": "Vos tâches" + }, + { + "locale": "es", + "value": "Sus tareas" + } + ], + "layout": { + "w": 12, + "h": 8, + "x": 0, + "y": 0 + }, + "enableQuickSearch": true, + "columns": [ + { + "field": "start", + "width": "75" + }, + { + "field": "priority", + "width": "70" + }, + { + "field": "id", + "quickSearch": true, + "width": "90" + }, + { + "field": "name", + "quickSearch": true, + "width": "280" + }, + { + "field": "description", + "quickSearch": true, + "width": "280" + }, + { + "field": "activator", + "width": "120" + }, + { + "field": "state", + "width": "80" + }, + { + "field": "startTimestamp", + "width": "95" + }, + { + "field": "expiryTimestamp", + "width": "95" + }, + { + "field": "category", + "width": "105" + }, + { + "field": "actions", + "width": "95" + } + ], + "canWorkOn": false, + "sortField": "id", + "sortDescending": true + } + ], + "permissions": [ + "Everybody" + ], + "isTopMenu": true + }, + { + "id": "default-case-list-dashboard", + "version": "12.0.0", + "templateId": "create-from-scratch", + "titles": [ + { + "locale": "en", + "value": "Cases" + }, + { + "locale": "fr", + "value": "Dossiers" + }, + { + "locale": "de", + "value": "Vorgänge" + }, + { + "locale": "es", + "value": "Casos" + } + ], + "icon": "si-layout-bullets", + "description": "Default Case List Dashboard", + "widgets": [ + { + "type": "case", + "id": "default_case_list_dashboard_case_1", + "names": [ + { + "locale": "en", + "value": "Your Cases" + }, + { + "locale": "de", + "value": "Ihre Vorgänge" + }, + { + "locale": "fr", + "value": "Vos affaires" + }, + { + "locale": "es", + "value": "Sus casos" + } + ], + "layout": { + "w": 12, + "h": 8, + "x": 0, + "y": 0 + }, + "sortDescending": true, + "sortField": "id", + "enableQuickSearch": true, + "columns": [ + { + "field": "id", + "quickSearch": true, + "width": "80" + }, + { + "field": "name", + "quickSearch": true, + "width": "300" + }, + { + "field": "description", + "quickSearch": true, + "width": "300" + }, + { + "field": "creator", + "width": "120" + }, + { + "field": "startTimestamp", + "width": "95" + }, + { + "field": "endTimestamp", + "width": "95" + }, + { + "field": "state", + "width": "80" + }, + { + "field": "category", + "width": "105" + }, + { + "field": "actions", + "width": "95" + } + ] + } + ], + "permissions": [ + "Everybody" + ], + "isTopMenu": true } -] \ No newline at end of file +] diff --git a/AxonIvyPortal/portal/config/variables/Portal/DashboardTemplates.json b/AxonIvyPortal/portal/config/variables/Portal/DashboardTemplates.json index bfd0e1d4b14..32c68d3934e 100644 --- a/AxonIvyPortal/portal/config/variables/Portal/DashboardTemplates.json +++ b/AxonIvyPortal/portal/config/variables/Portal/DashboardTemplates.json @@ -1,6 +1,6 @@ [ { - "version": "11.4.0", + "version": "12.0.0", "id": "default-portal-dashboard-template", "titles": [ { @@ -71,7 +71,6 @@ "y": 2 }, "enableQuickSearch": true, - "rowsPerPage": 5, "canWorkOn": true, "columns": [ { @@ -82,37 +81,30 @@ }, { "field": "id", - "visible": false, - "quickSearch": false + "visible": false }, { - "field": "name", - "quickSearch": true + "field": "name" }, { "field": "description", - "visible": false, - "quickSearch": false + "visible": false }, { - "field": "activator", - "quickSearch": false + "field": "activator" }, { - "field": "state", - "visible": false + "field": "state" }, { - "field": "startTimestamp", - "visible": false + "field": "startTimestamp" }, { "field": "expiryTimestamp" }, { "field": "category", - "visible": false, - "quickSearch": false + "visible": false }, { "field": "actions" @@ -160,27 +152,23 @@ "x": 3, "y": 8 }, - "rowsPerPage": 5, + "enableQuickSearch": true, "columns": [ { - "field": "id", - "quickSearch": false + "field": "id" }, { - "field": "name", - "quickSearch": true + "field": "name" }, { "field": "description", - "visible": false, - "quickSearch": false + "visible": false }, { "field": "state" }, { - "field": "creator", - "quickSearch": false + "field": "creator" }, { "field": "startTimestamp" @@ -191,8 +179,7 @@ }, { "field": "category", - "visible": false, - "quickSearch": false + "visible": false }, { "field": "actions" @@ -351,7 +338,7 @@ } }, { - "version": "11.4.0", + "version": "12.0.0", "id": "two-task-widget-dashboard-template", "titles": [ { @@ -410,7 +397,7 @@ "x": 0, "y": 0 }, - "rowsPerPage": 5, + "enableQuickSearch": true, "sortDescending": true, "columns": [ { @@ -427,8 +414,7 @@ }, { "field": "description", - "visible": false, - "quickSearch": false + "visible": false }, { "field": "activator", @@ -473,7 +459,7 @@ "x": 0, "y": 5 }, - "rowsPerPage": 5, + "enableQuickSearch": true, "sortDescending": true, "columns": [ { @@ -490,8 +476,7 @@ }, { "field": "description", - "visible": false, - "quickSearch": false + "visible": false }, { "field": "activator", @@ -536,7 +521,263 @@ "h": 10, "x": 9, "y": 0 - } + }, + "enableQuickSearch": true + } + ], + "permissions": [ + "Everybody" + ] + } + }, + { + "version": "12.0.0", + "id": "accessibility-dashboard-template", + "titles": [ + { + "locale": "en", + "value": "Accessibility dashboard" + }, + { + "locale": "fr", + "value": "Tableau de bord d'accessibilité " + }, + { + "locale": "de", + "value": "Dashboard für Barrierefreiheit" + }, + { + "locale": "es", + "value": "Panel de accesibilidad" + } + ], + "descriptions": [ + { + "locale": "en", + "value": "Optimized reduced Dashboard for Accessibility Use" + }, + { + "locale": "fr", + "value": "Tableau de bord réduit optimisé pour une utilisation en accessibilité" + }, + { + "locale": "de", + "value": "Optimiertes, reduziertes Dashboard für die barrierefreie Nutzung" + }, + { + "locale": "es", + "value": "Panel de control reducido optimizado para uso de accesibilidad" + } + ], + "icon": "si-layout-dashboard", + "dashboard": { + "id": "", + "templateId": "accessibility-dashboard-template", + "title": "Accessibility dashboard", + "widgets": [ + { + "type": "task", + "id": "task_1", + "names": [ + { + "locale": "en", + "value": "Your Tasks" + }, + { + "locale": "de", + "value": "Ihre Aufgaben" + }, + { + "locale": "fr", + "value": "Vos tâches" + }, + { + "locale": "es", + "value": "Sus tareas" + } + ], + "layout": { + "w": 9, + "h": 4, + "x": 3, + "y": 3 + }, + "enableQuickSearch": true, + "showFullscreenMode": false, + "columns": [ + { + "field": "start" + }, + { + "field": "actions" + }, + { + "field": "name" + }, + { + "field": "priority" + }, + { + "field": "activator" + }, + { + "field": "state" + }, + { + "field": "startTimestamp" + }, + { + "field": "expiryTimestamp" + }, + { + "field": "id", + "visible": false + }, + { + "field": "description", + "visible": false + }, + { + "field": "category", + "visible": false + } + ], + "sortField": "id", + "sortDescending": true, + "canWorkOn": true + }, + { + "type": "compact-process", + "id": "process_1", + "names": [ + { + "locale": "en", + "value": "Your Processes" + }, + { + "locale": "de", + "value": "Ihre Prozesse" + }, + { + "locale": "fr", + "value": "Vos processus" + }, + { + "locale": "es", + "value": "Sus procesos" + } + ], + "layout": { + "w": 3, + "h": 9, + "x": 0, + "y": 3 + }, + "showFullscreenMode": false, + "enableQuickSearch": true + }, + { + "type": "custom", + "id": "custom_1", + "names": [ + { + "locale": "en", + "value": "Accessibility Shortcuts" + }, + { + "locale": "fr", + "value": "Raccourcis d’accessibilité" + }, + { + "locale": "de", + "value": "Barrierefreiheitskürzel" + }, + { + "locale": "es", + "value": "Atajos de accesibilidad" + } + ], + "layout": { + "w": 12, + "h": 3, + "x": 0, + "y": 0 + }, + "data": { + "processPath": "Functional Processes/AccessibilityShortcutCustomWidget/accessibilityShortcut.ivp" + }, + "showFullscreenMode": false + }, + { + "type": "case", + "id": "case_1", + "names": [ + { + "locale": "en", + "value": "Your Cases" + }, + { + "locale": "de", + "value": "Ihre Vorgänge" + }, + { + "locale": "fr", + "value": "Vos affaires" + }, + { + "locale": "es", + "value": "Sus casos" + } + ], + "layout": { + "w": 9, + "h": 5, + "x": 3, + "y": 7 + }, + "enableQuickSearch": true, + "showFullscreenMode": false, + "columns": [ + { + "field": "name" + }, + { + "field": "id", + "visible": false + }, + { + "field": "description", + "visible": false + }, + { + "field": "state" + }, + { + "field": "creator" + }, + { + "field": "startTimestamp" + }, + { + "field": "endTimestamp" + }, + { + "field": "owner" + }, + { + "field": "category", + "visible": false + }, + { + "field": "application", + "visible": false + }, + { + "field": "actions" + } + ], + "sortField": "id", + "sortDescending": true } ], "permissions": [ diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/AnalyzeStatisticData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/AnalyzeStatisticData.d.json index f39776e14dc..0675e2b56c5 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/AnalyzeStatisticData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/AnalyzeStatisticData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "AnalyzeStatisticData", "namespace" : "ch.ivy.add.portalkit", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/BuildCaseQueryData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/BuildCaseQueryData.d.json index 6a5c05584f7..f20a52ccc9a 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/BuildCaseQueryData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/BuildCaseQueryData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "BuildCaseQueryData", "namespace" : "ch.ivy.add.portalkit", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/BuildTaskQueryData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/BuildTaskQueryData.d.json index 98af30ab007..45f3d454506 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/BuildTaskQueryData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/BuildTaskQueryData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "BuildTaskQueryData", "namespace" : "ch.ivy.add.portalkit", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/CaculateTaskDelegateData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/CaculateTaskDelegateData.d.json index 4756e497343..95a90a13f58 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/CaculateTaskDelegateData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/CaculateTaskDelegateData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "CaculateTaskDelegateData", "namespace" : "ch.ivy.add.portalkit", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/ChangePasswordData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/ChangePasswordData.d.json index 9e10e60adc0..a4bbb9c3959 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/ChangePasswordData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/ChangePasswordData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "ChangePasswordData", "namespace" : "ch.ivy.add.portalkit", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/Data.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/Data.d.json index 073206f3470..607fb0eee0c 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/Data.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/Data.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "Data", "namespace" : "ch.ivy.add.portalkit", "isBusinessCaseData" : false diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/DeleteDocumentData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/DeleteDocumentData.d.json index 3b78562c553..fcaba233b33 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/DeleteDocumentData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/DeleteDocumentData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "DeleteDocumentData", "namespace" : "ch.ivy.add.portalkit", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/DownloadDocumentData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/DownloadDocumentData.d.json index 2f73fee7a30..dd8b7ffa91d 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/DownloadDocumentData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/DownloadDocumentData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "DownloadDocumentData", "namespace" : "ch.ivy.add.portalkit", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/GetDocumentListData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/GetDocumentListData.d.json index e2624846fad..f3614c2738d 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/GetDocumentListData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/GetDocumentListData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "GetDocumentListData", "namespace" : "ch.ivy.add.portalkit", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/HideSystemCaseData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/HideSystemCaseData.d.json index 62441d649fc..8308b491aa4 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/HideSystemCaseData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/HideSystemCaseData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "HideSystemCaseData", "namespace" : "ch.ivy.add.portalkit", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/LoginData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/LoginData.d.json index 9acf51d16fe..ec6582b5b32 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/LoginData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/LoginData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "LoginData", "namespace" : "ch.ivy.add.portalkit", "isBusinessCaseData" : false diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/LogoutData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/LogoutData.d.json index 842016f7889..c7bb6e5a2d7 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/LogoutData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/LogoutData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "LogoutData", "namespace" : "ch.ivy.add.portalkit", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/NavigatorData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/NavigatorData.d.json index 179e7e283eb..544710c6950 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/NavigatorData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/NavigatorData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "NavigatorData", "namespace" : "ch.ivy.add.portalkit", "isBusinessCaseData" : false diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/UploadDocumentCheckerData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/UploadDocumentCheckerData.d.json index 879d1041188..a08b245c77f 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/UploadDocumentCheckerData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/UploadDocumentCheckerData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "UploadDocumentCheckerData", "namespace" : "ch.ivy.add.portalkit", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/UploadDocumentData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/UploadDocumentData.d.json index 903a1f2474f..0ea72b6d398 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/UploadDocumentData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/add/portalkit/UploadDocumentData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "UploadDocumentData", "namespace" : "ch.ivy.add.portalkit", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/DailyTaskSummaryMailContentData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/DailyTaskSummaryMailContentData.d.json index d186b52707b..0c97cbe85ed 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/DailyTaskSummaryMailContentData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/DailyTaskSummaryMailContentData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "DailyTaskSummaryMailContentData", "namespace" : "ch.ivy.addon.portal.generic", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/Data.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/Data.d.json index a177d32ec21..fb477f17007 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/Data.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/Data.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "Data", "namespace" : "ch.ivy.addon.portal.generic", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/InitializeCaseDataModel.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/InitializeCaseDataModel.d.json index ea82f451ee0..2fba7ad8656 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/InitializeCaseDataModel.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/InitializeCaseDataModel.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "InitializeCaseDataModel", "namespace" : "ch.ivy.addon.portal.generic", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/InitializeTaskDataModelData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/InitializeTaskDataModelData.d.json index 289d39cdfbe..c654b74fc09 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/InitializeTaskDataModelData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/InitializeTaskDataModelData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "InitializeTaskDataModelData", "namespace" : "ch.ivy.addon.portal.generic", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/NavigatorData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/NavigatorData.d.json index 5872f9921a0..a51d2d7df98 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/NavigatorData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/NavigatorData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "NavigatorData", "namespace" : "ch.ivy.addon.portal.generic", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/NewTaskMailContentData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/NewTaskMailContentData.d.json index 6a144b50892..7ab85b98cef 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/NewTaskMailContentData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/NewTaskMailContentData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "NewTaskMailContentData", "namespace" : "ch.ivy.addon.portal.generic", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/OpenPortalCaseDetailsData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/OpenPortalCaseDetailsData.d.json index e70d778abab..31fb45e8e39 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/OpenPortalCaseDetailsData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/OpenPortalCaseDetailsData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "OpenPortalCaseDetailsData", "namespace" : "ch.ivy.addon.portal.generic", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/OpenPortalCasesData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/OpenPortalCasesData.d.json index 6509ea3bf56..b7864778913 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/OpenPortalCasesData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/OpenPortalCasesData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "OpenPortalCasesData", "namespace" : "ch.ivy.addon.portal.generic", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/OpenPortalSearchData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/OpenPortalSearchData.d.json index 2ace843baba..a862dc5ce77 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/OpenPortalSearchData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/OpenPortalSearchData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "OpenPortalSearchData", "namespace" : "ch.ivy.addon.portal.generic", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/OpenPortalTaskDetailsData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/OpenPortalTaskDetailsData.d.json index 1ed2ed0798c..1d9462f27d7 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/OpenPortalTaskDetailsData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/OpenPortalTaskDetailsData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "OpenPortalTaskDetailsData", "namespace" : "ch.ivy.addon.portal.generic", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/OpenPortalTasksData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/OpenPortalTasksData.d.json index 44c4a9b8e1f..857aff295c6 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/OpenPortalTasksData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/OpenPortalTasksData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "OpenPortalTasksData", "namespace" : "ch.ivy.addon.portal.generic", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/PortalDashboardData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/PortalDashboardData.d.json index ea64033f544..04faefb895f 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/PortalDashboardData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/PortalDashboardData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "PortalDashboardData", "namespace" : "ch.ivy.addon.portal.generic", "isBusinessCaseData" : false diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/PortalStartData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/PortalStartData.d.json index eedca11f422..e076d994800 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/PortalStartData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/PortalStartData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "PortalStartData", "namespace" : "ch.ivy.addon.portal.generic", "isBusinessCaseData" : false, @@ -94,7 +94,7 @@ "type" : "Long" }, { "name" : "notes", - "type" : "java.util.List" + "type" : "List" }, { "name" : "isAuthorized", "type" : "Boolean" @@ -120,5 +120,8 @@ }, { "name" : "id", "type" : "String" + }, { + "name" : "isMainDashboard", + "type" : "Boolean" } ] } \ No newline at end of file diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/SetBusinessEntityIdData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/SetBusinessEntityIdData.d.json index 2c79a8e2008..b160c94394c 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/SetBusinessEntityIdData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/SetBusinessEntityIdData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "SetBusinessEntityIdData", "namespace" : "ch.ivy.addon.portal.generic", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/StatisticData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/StatisticData.d.json index 88f8059226b..ab8fd331f5a 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/StatisticData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivy/addon/portal/generic/StatisticData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "StatisticData", "namespace" : "ch.ivy.addon.portal.generic", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/AbsenceServiceData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/AbsenceServiceData.d.json index 604c9402d39..5b7f0104b10 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/AbsenceServiceData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/AbsenceServiceData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "AbsenceServiceData", "namespace" : "ch.ivyteam.wf.processes", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/CaseServiceData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/CaseServiceData.d.json index b536dae4509..ace5f2dabbd 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/CaseServiceData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/CaseServiceData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "CaseServiceData", "namespace" : "ch.ivyteam.wf.processes", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/FindApplicationsByUserData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/FindApplicationsByUserData.d.json index eb5727e5490..3326a3edd42 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/FindApplicationsByUserData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/FindApplicationsByUserData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "FindApplicationsByUserData", "namespace" : "ch.ivyteam.wf.processes", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/LanguageServiceData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/LanguageServiceData.d.json index 1a292f26d4d..fcd8078077a 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/LanguageServiceData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/LanguageServiceData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "LanguageServiceData", "namespace" : "ch.ivyteam.wf.processes", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/PasswordServiceData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/PasswordServiceData.d.json index 0a6385e5b2d..ffa02e5d450 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/PasswordServiceData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/PasswordServiceData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "PasswordServiceData", "namespace" : "ch.ivyteam.wf.processes", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/ProcessServiceData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/ProcessServiceData.d.json index 5d583fea26f..ee65728ba7d 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/ProcessServiceData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/ProcessServiceData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "ProcessServiceData", "namespace" : "ch.ivyteam.wf.processes", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/SecurityServiceData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/SecurityServiceData.d.json index cd256a64d82..cfc91817edc 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/SecurityServiceData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/SecurityServiceData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "SecurityServiceData", "namespace" : "ch.ivyteam.wf.processes", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/SideStepServiceData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/SideStepServiceData.d.json index 147cdc8cc6e..039f96d7fe0 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/SideStepServiceData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/SideStepServiceData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "SideStepServiceData", "namespace" : "ch.ivyteam.wf.processes", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/SubstituteServiceData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/SubstituteServiceData.d.json index d097fad2bea..bcbb7773a2d 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/SubstituteServiceData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/SubstituteServiceData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "SubstituteServiceData", "namespace" : "ch.ivyteam.wf.processes", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/TaskServiceData.d.json b/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/TaskServiceData.d.json index f8c46f9031f..3446a507477 100644 --- a/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/TaskServiceData.d.json +++ b/AxonIvyPortal/portal/dataclasses/ch/ivyteam/wf/processes/TaskServiceData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "TaskServiceData", "namespace" : "ch.ivyteam.wf.processes", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/com/axonivy/portal/data/functional/DeepLData.d.json b/AxonIvyPortal/portal/dataclasses/com/axonivy/portal/data/functional/DeepLData.d.json index 253ef499755..d0d9dbaf168 100644 --- a/AxonIvyPortal/portal/dataclasses/com/axonivy/portal/data/functional/DeepLData.d.json +++ b/AxonIvyPortal/portal/dataclasses/com/axonivy/portal/data/functional/DeepLData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "DeepLData", "namespace" : "com.axonivy.portal.data.functional", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/portalTemplate/CheckIvySecuritySystemData.d.json b/AxonIvyPortal/portal/dataclasses/portalTemplate/CheckIvySecuritySystemData.d.json index bf952424a7f..26905a6ca44 100644 --- a/AxonIvyPortal/portal/dataclasses/portalTemplate/CheckIvySecuritySystemData.d.json +++ b/AxonIvyPortal/portal/dataclasses/portalTemplate/CheckIvySecuritySystemData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "CheckIvySecuritySystemData", "namespace" : "portalTemplate", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/portalTemplate/UserProfileData.d.json b/AxonIvyPortal/portal/dataclasses/portalTemplate/UserProfileData.d.json index c6d17c0cd9d..729c2a5b381 100644 --- a/AxonIvyPortal/portal/dataclasses/portalTemplate/UserProfileData.d.json +++ b/AxonIvyPortal/portal/dataclasses/portalTemplate/UserProfileData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "UserProfileData", "namespace" : "portalTemplate", "isBusinessCaseData" : false diff --git a/AxonIvyPortal/portal/dataclasses/portalkit/ExportCaseToExcelData.d.json b/AxonIvyPortal/portal/dataclasses/portalkit/ExportCaseToExcelData.d.json index 280dafc0773..b5f6aec0b0a 100644 --- a/AxonIvyPortal/portal/dataclasses/portalkit/ExportCaseToExcelData.d.json +++ b/AxonIvyPortal/portal/dataclasses/portalkit/ExportCaseToExcelData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "ExportCaseToExcelData", "namespace" : "portalkit", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/portalkit/ExportTaskToExcelData.d.json b/AxonIvyPortal/portal/dataclasses/portalkit/ExportTaskToExcelData.d.json index 7c7d24d50eb..b1e21327c22 100644 --- a/AxonIvyPortal/portal/dataclasses/portalkit/ExportTaskToExcelData.d.json +++ b/AxonIvyPortal/portal/dataclasses/portalkit/ExportTaskToExcelData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "ExportTaskToExcelData", "namespace" : "portalkit", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/portalkit/PageHeaderAndFooterData.d.json b/AxonIvyPortal/portal/dataclasses/portalkit/PageHeaderAndFooterData.d.json index b1e3b771a0e..2f7a116b050 100644 --- a/AxonIvyPortal/portal/dataclasses/portalkit/PageHeaderAndFooterData.d.json +++ b/AxonIvyPortal/portal/dataclasses/portalkit/PageHeaderAndFooterData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "PageHeaderAndFooterData", "namespace" : "portalkit", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/portalkit/PortalCallableToolsData.d.json b/AxonIvyPortal/portal/dataclasses/portalkit/PortalCallableToolsData.d.json new file mode 100644 index 00000000000..98bd9b26f72 --- /dev/null +++ b/AxonIvyPortal/portal/dataclasses/portalkit/PortalCallableToolsData.d.json @@ -0,0 +1,55 @@ +{ + "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "simpleName" : "PortalCallableToolsData", + "namespace" : "portalkit", + "isBusinessCaseData" : false, + "fields" : [ { + "name" : "username", + "type" : "String" + }, { + "name" : "role", + "type" : "String" + }, { + "name" : "users", + "type" : "java.util.List" + }, { + "name" : "taskName", + "type" : "String" + }, { + "name" : "taskPriority", + "type" : "String" + }, { + "name" : "taskDescription", + "type" : "String" + }, { + "name" : "taskState", + "type" : "String" + }, { + "name" : "taskDashboardWidget", + "type" : "ch.ivy.addon.portalkit.dto.dashboard.TaskDashboardWidget" + }, { + "name" : "result", + "type" : "com.axonivy.portal.components.dto.AiResultDTO" + }, { + "name" : "validationError", + "type" : "String" + }, { + "name" : "taskId", + "type" : "String" + }, { + "name" : "dateFrom", + "type" : "String" + }, { + "name" : "dateTo", + "type" : "String" + }, { + "name" : "processId", + "type" : "String" + }, { + "name" : "parameters", + "type" : "String" + }, { + "name" : "onlyMyTask", + "type" : "String" + } ] +} \ No newline at end of file diff --git a/AxonIvyPortal/portal/dataclasses/portalkit/PortalToolsData.d.json b/AxonIvyPortal/portal/dataclasses/portalkit/PortalToolsData.d.json new file mode 100644 index 00000000000..1d15edb0dcc --- /dev/null +++ b/AxonIvyPortal/portal/dataclasses/portalkit/PortalToolsData.d.json @@ -0,0 +1,37 @@ +{ + "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "simpleName" : "PortalToolsData", + "namespace" : "portalkit", + "isBusinessCaseData" : false, + "fields" : [ { + "name" : "taskDashboardWidget", + "type" : "ch.ivy.addon.portalkit.dto.dashboard.TaskDashboardWidget" + }, { + "name" : "name", + "type" : "String" + }, { + "name" : "description", + "type" : "String" + }, { + "name" : "priority", + "type" : "String" + }, { + "name" : "state", + "type" : "String" + }, { + "name" : "caseDashboardWidget", + "type" : "ch.ivy.addon.portalkit.dto.dashboard.CaseDashboardWidget" + }, { + "name" : "processDashboardWidget", + "type" : "ch.ivy.addon.portalkit.dto.dashboard.ProcessDashboardWidget" + }, { + "name" : "taskExpiryDateFrom", + "type" : "String" + }, { + "name" : "taskExpiryDateTo", + "type" : "String" + }, { + "name" : "onlyMyTask", + "type" : "String" + } ] +} \ No newline at end of file diff --git a/AxonIvyPortal/portal/dataclasses/portalkit/ResetPasswordData.d.json b/AxonIvyPortal/portal/dataclasses/portalkit/ResetPasswordData.d.json index a73a5f51a1a..801102e763e 100644 --- a/AxonIvyPortal/portal/dataclasses/portalkit/ResetPasswordData.d.json +++ b/AxonIvyPortal/portal/dataclasses/portalkit/ResetPasswordData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "ResetPasswordData", "namespace" : "portalkit", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/dataclasses/portalkit/SendPasswordResetEmailData.d.json b/AxonIvyPortal/portal/dataclasses/portalkit/SendPasswordResetEmailData.d.json index 93fd2de2ae4..a9aa5c65be2 100644 --- a/AxonIvyPortal/portal/dataclasses/portalkit/SendPasswordResetEmailData.d.json +++ b/AxonIvyPortal/portal/dataclasses/portalkit/SendPasswordResetEmailData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "SendPasswordResetEmailData", "namespace" : "portalkit", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/logs/convert-primefaces-version-11-13.log b/AxonIvyPortal/portal/logs/convert-primefaces-version-11-13.log deleted file mode 100644 index 3edeed3fd53..00000000000 --- a/AxonIvyPortal/portal/logs/convert-primefaces-version-11-13.log +++ /dev/null @@ -1,29 +0,0 @@ -# Conversion log for project 'portal' -# Convert project to use Primefaces version from 11 to 13 -# Using Axon Ivy Designer version 11.3.0.2403261805 -# Created on 26.03.2024 18:06:40 -26.03.2024 18:06:41 : New Task : Converting project portal. -26.03.2024 18:06:41 : Info : Log is stored in 'logs/convert-primefaces-version-11-13.log' -26.03.2024 18:06:41 : New Task : Convert to Primefaces 13 -26.03.2024 18:06:41 : Warning : Project is missing the following required projects 'com.axonivy.portal:portal-components'. Conversion may not be successful. Fix missing required projects first. -26.03.2024 18:06:56 : Info : Rename tag p:repeat with ui:repeat in file src_hd/ch/ivy/addon/portal/generic/dashboard/PortalDashboardDetailModification/PortalDashboardAddNewWidgets.xhtml (4 changes) -26.03.2024 18:06:56 : Info : Rename tag p:repeat with ui:repeat in file src_hd/ch/ivy/addon/portal/generic/dashboard/component/CaseDashboardWidget/CaseInfo.xhtml (4 changes) -26.03.2024 18:06:57 : Info : Rename tag p:repeat with ui:repeat in file src_hd/ch/ivy/addon/portal/generic/dashboard/component/TaskDashboardWidget/TaskInfo.xhtml (4 changes) -26.03.2024 18:06:57 : Info : Add missing attribute layout="tabular" to tag p:panelGrid in file src_hd/ch/ivy/addon/portal/setting/AbsenceManagement/SelectDeputy.xhtml (2 changes) -26.03.2024 18:06:57 : Info : Convert value of attribute class from '#{channel.channel.displayIcon()} table-icon p-mr-2 p-mt-1' to '#{channel.channel.displayIcon()} table-icon mr-2 mt-1' in file src_hd/ch/ivy/addon/portal/setting/UserProfile/UserProfile.xhtml (1 change) -26.03.2024 18:06:57 : Info : Convert value of attribute class from 'p-d-flex' to 'flex' in file src_hd/ch/ivy/addon/portal/setting/UserProfile/UserProfile.xhtml (2 changes) -26.03.2024 18:06:57 : Info : Convert value of attribute class from 'p-mr-2 p-mt-1 si table-icon si-#{subscription.icon} subscription-icon ' to 'mr-2 mt-1 si table-icon si-#{subscription.icon} subscription-icon ' in file src_hd/ch/ivy/addon/portal/setting/UserProfile/UserProfile.xhtml (1 change) -26.03.2024 18:06:57 : Info : Add missing attribute columns="0" to tag p:panelGrid in file src_hd/ch/ivy/addon/portalkit/admin/AdminSettings/AdminSettings.xhtml (1 change) -26.03.2024 18:06:57 : Info : Add missing attribute layout="tabular" to tag p:panelGrid in file src_hd/ch/ivy/addon/portalkit/admin/AdminSettings/AdminSettings.xhtml (1 change) -26.03.2024 18:06:57 : Info : Add missing attribute columns="0" to tag p:panelGrid in file src_hd/ch/ivy/addon/portalkit/component/statistic/ChartInformationDialog/ChartInformationDialog.xhtml (2 changes) -26.03.2024 18:06:57 : Info : Add missing attribute layout="tabular" to tag p:panelGrid in file src_hd/ch/ivy/addon/portalkit/component/statistic/ChartInformationDialog/ChartInformationDialog.xhtml (2 changes) -26.03.2024 18:06:57 : Info : Convert value of attribute class from 'p-text-center message' to 'text-center message' in file src_hd/com/axonivy/portal/component/NotificationFullPage/NotificationFullPage.xhtml (1 change) -26.03.2024 18:06:57 : Info : Convert value of attribute class from 'ui-g-2 import-dashboard-label p-mb-2' to 'ui-g-2 import-dashboard-label mb-2' in file src_hd/com/axonivy/portal/dashboard/component/DashboardImportDetails/DashboardImportDetails.xhtml (1 change) -26.03.2024 18:06:57 : Info : Convert value of attribute class from 'p-d-flex' to 'flex' in file src_hd/com/axonivy/portal/dashboard/component/NotificationWidget/NotificationWidget.xhtml (2 changes) -26.03.2024 18:06:57 : Info : Convert value of attribute name from 'primeflex-2.min.css' to 'primeflex-3.min.css' in file webContent/layouts/BasicTemplate.xhtml (1 change) -26.03.2024 18:06:57 : Info : Convert value of attribute class from 'p-d-flex p-jc-between' to 'flex justify-content-between' in file webContent/layouts/includes/notification.xhtml (1 change) -26.03.2024 18:06:57 : Info : Convert value of attribute class from 'notifications-button si si-check-double-1 p-mr-1' to 'notifications-button si si-check-double-1 mr-1' in file webContent/layouts/includes/notification.xhtml (1 change) -26.03.2024 18:06:57 : Info : Convert value of attribute class from 'p-d-flex' to 'flex' in file webContent/layouts/includes/notification.xhtml (3 changes) -26.03.2024 18:06:57 : Info : Convert value of attribute class from 'p-text-center message' to 'text-center message' in file webContent/layouts/includes/notification.xhtml (1 change) -26.03.2024 18:06:57 : New Task : Update project Primefaces version to actual version 13. -26.03.2024 18:06:57 : New Task : Finished conversion of project portal. diff --git a/AxonIvyPortal/portal/processes/AI Tool Processes/PortalCallableTools.p.json b/AxonIvyPortal/portal/processes/AI Tool Processes/PortalCallableTools.p.json new file mode 100644 index 00000000000..c561ae22589 --- /dev/null +++ b/AxonIvyPortal/portal/processes/AI Tool Processes/PortalCallableTools.p.json @@ -0,0 +1,505 @@ +{ + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", + "id" : "18DD4CF26C1CCE45", + "kind" : "CALLABLE_SUB", + "config" : { + "data" : "portalkit.PortalCallableToolsData" + }, + "elements" : [ { + "id" : "f0", + "type" : "CallSubStart", + "name" : "findUsers(String,String)", + "config" : { + "signature" : "findUsers", + "input" : { + "params" : [ + { "name" : "username", "type" : "String", "desc" : "name of user" }, + { "name" : "role", "type" : "String", "desc" : "role of user" } + ], + "map" : { + "out.role" : "param.role", + "out.username" : "param.username" + } + }, + "result" : { + "params" : [ + { "name" : "result", "type" : "com.axonivy.portal.components.dto.AiResultDTO", "desc" : "" } + ], + "map" : { + "result.result" : "in.result" + } + } + }, + "visual" : { + "at" : { "x" : 96, "y" : 64 } + }, + "connect" : [ + { "id" : "f2", "to" : "f3" } + ] + }, { + "id" : "f1", + "type" : "CallSubEnd", + "visual" : { + "at" : { "x" : 352, "y" : 64 } + } + }, { + "id" : "f3", + "type" : "Script", + "name" : "Find users", + "config" : { + "output" : { + "code" : [ + "import com.axonivy.portal.service.AiService;", + "", + "in.result = AiService.getInstance().generateFindUsersAiResult(in.username, in.role);" + ] + }, + "sudo" : true + }, + "visual" : { + "at" : { "x" : 224, "y" : 64 } + }, + "connect" : [ + { "id" : "f4", "to" : "f1" } + ] + }, { + "id" : "f5", + "type" : "CallSubStart", + "name" : "findTasks(String,String,String,String,String,String,String,String)", + "config" : { + "signature" : "findTasks", + "input" : { + "params" : [ + { "name" : "taskName", "type" : "String", "desc" : "" }, + { "name" : "taskDescription", "type" : "String", "desc" : "" }, + { "name" : "taskPriority", "type" : "String", "desc" : "" }, + { "name" : "taskState", "type" : "String", "desc" : "" }, + { "name" : "taskExpiryDateFrom", "type" : "String", "desc" : "" }, + { "name" : "taskExpiryDateTo", "type" : "String", "desc" : "" }, + { "name" : "onlyMyTask", "type" : "String", "desc" : "" } + ], + "map" : { + "out.dateFrom" : "param.taskExpiryDateFrom", + "out.dateTo" : "param.taskExpiryDateTo", + "out.onlyMyTask" : "param.onlyMyTask", + "out.taskDescription" : "param.taskDescription", + "out.taskName" : "param.taskName", + "out.taskPriority" : "param.taskPriority", + "out.taskState" : "param.taskState" + } + }, + "result" : { + "params" : [ + { "name" : "result", "type" : "com.axonivy.portal.components.dto.AiResultDTO", "desc" : "" } + ], + "map" : { + "result.result" : "in.result" + } + } + }, + "visual" : { + "at" : { "x" : 96, "y" : 176 }, + "labelOffset" : { "x" : 31, "y" : 51 } + }, + "connect" : [ + { "id" : "f8", "to" : "f10" } + ] + }, { + "id" : "f6", + "type" : "CallSubEnd", + "visual" : { + "at" : { "x" : 352, "y" : 176 } + } + }, { + "id" : "f10", + "type" : "Script", + "name" : "Validate and find tasks", + "config" : { + "output" : { + "code" : [ + "import com.axonivy.portal.service.AiService;", + "import com.axonivy.portal.components.publicapi.AiAssistantAPI;", + "import org.apache.commons.lang3.StringUtils;", + "import com.axonivy.portal.util.AiToolUtils;", + "", + "in.validationError = AiToolUtils.validateTaskState(in.taskState);", + "if (StringUtils.isBlank(in.validationError)) {", + " in.validationError = AiToolUtils.validateTaskPriority(in.taskPriority);", + "}", + "", + "if(StringUtils.isNotBlank(in.validationError)) {", + " in.result = AiAssistantAPI.generateErrorAiResult(in.validationError);", + "} else {", + " in.result = AiService.getInstance().generateFindTasksAiResult(in.taskName, in.taskDescription, in.taskState, in.taskPriority, in.dateFrom, in.dateTo, in.onlyMyTask);", + "}" + ] + }, + "sudo" : true + }, + "visual" : { + "at" : { "x" : 224, "y" : 176 } + }, + "connect" : [ + { "id" : "f7", "to" : "f6" } + ] + }, { + "id" : "f17", + "type" : "CallSubStart", + "name" : "findCases(String,String,String)", + "config" : { + "signature" : "findCases", + "input" : { + "params" : [ + { "name" : "caseName", "type" : "String", "desc" : "" }, + { "name" : "caseDescription", "type" : "String", "desc" : "" }, + { "name" : "caseState", "type" : "String", "desc" : "" } + ], + "map" : { + "out.taskDescription" : "param.caseDescription", + "out.taskName" : "param.caseName", + "out.taskState" : "param.caseState" + } + }, + "result" : { + "params" : [ + { "name" : "result", "type" : "com.axonivy.portal.components.dto.AiResultDTO", "desc" : "" } + ], + "map" : { + "result.result" : "in.result" + } + } + }, + "visual" : { + "at" : { "x" : 96, "y" : 296 }, + "labelOffset" : { "x" : 31, "y" : 51 } + }, + "connect" : [ + { "id" : "f23", "to" : "f18" } + ] + }, { + "id" : "f18", + "type" : "Script", + "name" : "Validate and find cases", + "config" : { + "output" : { + "code" : [ + "import com.axonivy.portal.service.AiService;", + "import com.axonivy.portal.components.publicapi.AiAssistantAPI;", + "import org.apache.commons.lang3.StringUtils;", + "import com.axonivy.portal.util.AiToolUtils;", + "", + "in.validationError = AiToolUtils.validateCaseState(in.taskState);", + "if(StringUtils.isNotBlank(in.validationError)) {", + " in.result = AiAssistantAPI.generateErrorAiResult(in.validationError);", + "} else {", + " in.result = AiService.getInstance().generateFindCasesAiResult(in.taskName, in.taskDescription, in.taskState);", + "}" + ] + }, + "sudo" : true + }, + "visual" : { + "at" : { "x" : 224, "y" : 296 } + }, + "connect" : [ + { "id" : "f9", "to" : "f22" } + ] + }, { + "id" : "f22", + "type" : "CallSubEnd", + "visual" : { + "at" : { "x" : 352, "y" : 296 } + } + }, { + "id" : "f11", + "type" : "CallSubStart", + "name" : "startTask(String)", + "config" : { + "signature" : "startTask", + "input" : { + "params" : [ + { "name" : "taskId", "type" : "String", "desc" : "" } + ], + "map" : { + "out.taskId" : "param.taskId" + } + }, + "result" : { + "params" : [ + { "name" : "result", "type" : "com.axonivy.portal.components.dto.AiResultDTO", "desc" : "" } + ], + "map" : { + "result.result" : "in.result" + } + } + }, + "visual" : { + "at" : { "x" : 96, "y" : 424 }, + "labelOffset" : { "x" : 41, "y" : 49 } + }, + "connect" : [ + { "id" : "f15", "to" : "f12" } + ] + }, { + "id" : "f12", + "type" : "Script", + "name" : "Start task", + "config" : { + "output" : { + "code" : [ + "import com.axonivy.portal.service.AiService;", + "import com.axonivy.portal.components.publicapi.AiAssistantAPI;", + "import org.apache.commons.lang3.StringUtils;", + "import com.axonivy.portal.util.AiToolUtils;", + "", + "in.result = AiService.getInstance().generateStartTasksAiResult(in.taskId);" + ] + }, + "sudo" : true + }, + "visual" : { + "at" : { "x" : 224, "y" : 424 } + }, + "connect" : [ + { "id" : "f14", "to" : "f13" } + ] + }, { + "id" : "f13", + "type" : "CallSubEnd", + "visual" : { + "at" : { "x" : 352, "y" : 424 } + } + }, { + "id" : "f16", + "type" : "CallSubStart", + "name" : "findProcesses(String,String)", + "config" : { + "signature" : "findProcesses", + "input" : { + "params" : [ + { "name" : "processName", "type" : "String", "desc" : "" }, + { "name" : "processDescription", "type" : "String", "desc" : "" } + ], + "map" : { + "out.taskDescription" : "param.processDescription", + "out.taskName" : "param.processName" + } + }, + "result" : { + "params" : [ + { "name" : "result", "type" : "com.axonivy.portal.components.dto.AiResultDTO", "desc" : "" } + ], + "map" : { + "result.result" : "in.result" + } + } + }, + "visual" : { + "at" : { "x" : 536, "y" : 64 } + }, + "connect" : [ + { "id" : "f20", "to" : "f19" } + ] + }, { + "id" : "f19", + "type" : "Script", + "name" : "Find processes", + "config" : { + "output" : { + "code" : [ + "import ch.ivyteam.ivy.environment.Ivy;", + "import com.axonivy.portal.service.AiService;", + "", + "in.result = AiService.getInstance().generateFindProcessesAiResult(in.taskName, in.taskDescription);" + ] + }, + "sudo" : true + }, + "visual" : { + "at" : { "x" : 736, "y" : 64 } + }, + "connect" : [ + { "id" : "f24", "to" : "f21" } + ] + }, { + "id" : "f21", + "type" : "CallSubEnd", + "visual" : { + "at" : { "x" : 920, "y" : 64 }, + "labelOffset" : { "x" : 13, "y" : 33 } + } + }, { + "id" : "f25", + "type" : "CallSubStart", + "name" : "startProcess(String,String)", + "config" : { + "signature" : "startProcess", + "input" : { + "params" : [ + { "name" : "processId", "type" : "String", "desc" : "" }, + { "name" : "parameters", "type" : "String", "desc" : "" } + ], + "map" : { + "out.parameters" : "param.parameters", + "out.processId" : "param.processId" + } + }, + "result" : { + "params" : [ + { "name" : "result", "type" : "com.axonivy.portal.components.dto.AiResultDTO", "desc" : "" } + ], + "map" : { + "result.result" : "in.result" + } + } + }, + "visual" : { + "at" : { "x" : 536, "y" : 296 } + }, + "connect" : [ + { "id" : "f28", "to" : "f26" } + ] + }, { + "id" : "f26", + "type" : "Script", + "name" : "Generate a link to start the process", + "config" : { + "output" : { + "code" : [ + "import ch.ivyteam.ivy.environment.Ivy;", + "import com.axonivy.portal.service.AiService;", + "", + "in.result = AiService.getInstance().generateAiResultForStartProcess(in.processId, in.parameters);" + ] + }, + "sudo" : true + }, + "visual" : { + "at" : { "x" : 736, "y" : 296 } + }, + "connect" : [ + { "id" : "f29", "to" : "f27" } + ] + }, { + "id" : "f27", + "type" : "CallSubEnd", + "visual" : { + "at" : { "x" : 920, "y" : 296 }, + "labelOffset" : { "x" : 13, "y" : 33 } + } + }, { + "id" : "f30", + "type" : "CallSubStart", + "name" : "getProcessInfo(String)", + "config" : { + "signature" : "getProcessInfo", + "input" : { + "params" : [ + { "name" : "processId", "type" : "String", "desc" : "" } + ], + "map" : { + "out.processId" : "param.processId" + } + }, + "result" : { + "params" : [ + { "name" : "result", "type" : "com.axonivy.portal.components.dto.AiResultDTO", "desc" : "" } + ], + "map" : { + "result.result" : "in.result" + } + } + }, + "visual" : { + "at" : { "x" : 536, "y" : 176 } + }, + "connect" : [ + { "id" : "f33", "to" : "f31" } + ] + }, { + "id" : "f31", + "type" : "Script", + "name" : "Get process info", + "config" : { + "output" : { + "code" : [ + "import com.axonivy.portal.service.AiService;", + "", + "in.result = AiService.getInstance().generateAIResultForWebstartableInfoById(in.processId);" + ] + }, + "sudo" : true + }, + "visual" : { + "at" : { "x" : 736, "y" : 176 } + }, + "connect" : [ + { "id" : "f34", "to" : "f32" } + ] + }, { + "id" : "f32", + "type" : "CallSubEnd", + "visual" : { + "at" : { "x" : 920, "y" : 176 }, + "labelOffset" : { "x" : 13, "y" : 33 } + } + }, { + "id" : "f35", + "type" : "CallSubStart", + "name" : "findTaskDetails(String)", + "config" : { + "signature" : "findTaskDetails", + "input" : { + "params" : [ + { "name" : "taskId", "type" : "String", "desc" : "" } + ], + "map" : { + "out.taskId" : "param.taskId" + } + }, + "result" : { + "params" : [ + { "name" : "result", "type" : "com.axonivy.portal.components.dto.AiResultDTO", "desc" : "" } + ], + "map" : { + "result.result" : "in.result" + } + } + }, + "visual" : { + "at" : { "x" : 96, "y" : 560 }, + "labelOffset" : { "x" : 31, "y" : 51 } + }, + "connect" : [ + { "id" : "f38", "to" : "f36" } + ] + }, { + "id" : "f36", + "type" : "Script", + "name" : "Generate task details link", + "config" : { + "output" : { + "code" : [ + "import com.axonivy.portal.service.AiService;", + "import com.axonivy.portal.components.publicapi.AiAssistantAPI;", + "import org.apache.commons.lang3.StringUtils;", + "import com.axonivy.portal.util.AiToolUtils;", + "", + "in.result = AiService.getInstance().generateFindTaskDetailsAiResult(in.taskId);" + ] + } + }, + "visual" : { + "at" : { "x" : 224, "y" : 560 } + }, + "connect" : [ + { "id" : "f39", "to" : "f37" } + ] + }, { + "id" : "f37", + "type" : "CallSubEnd", + "visual" : { + "at" : { "x" : 352, "y" : 560 } + } + } ] +} \ No newline at end of file diff --git a/AxonIvyPortal/portal/processes/AI Tool Processes/PortalTools.p.json b/AxonIvyPortal/portal/processes/AI Tool Processes/PortalTools.p.json new file mode 100644 index 00000000000..11f13d6a36e --- /dev/null +++ b/AxonIvyPortal/portal/processes/AI Tool Processes/PortalTools.p.json @@ -0,0 +1,235 @@ +{ + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", + "id" : "18DBCE02273EB5B1", + "config" : { + "data" : "portalkit.PortalToolsData" + }, + "elements" : [ { + "id" : "f0", + "type" : "RequestStart", + "name" : "findTasksTool", + "config" : { + "signature" : "findTasksTool", + "input" : { + "params" : [ + { "name" : "taskName", "type" : "String", "desc" : "Name of the task" }, + { "name" : "taskDescription", "type" : "String", "desc" : "Description of the task" }, + { "name" : "taskPriority", "type" : "String", "desc" : "Priority of a task. Valid values for this attribute: low, normal, high, exception" }, + { "name" : "taskState", "type" : "String", "desc" : "state of the task. Valid values for this attribute: open, in progress, done" }, + { "name" : "taskExpiryDateFrom", "type" : "String", "desc" : "" }, + { "name" : "taskExpiryDateTo", "type" : "String", "desc" : "" }, + { "name" : "onlyMyTask", "type" : "String", "desc" : "" } + ], + "map" : { + "out.description" : "param.taskDescription", + "out.name" : "param.taskName", + "out.onlyMyTask" : "param.onlyMyTask", + "out.priority" : "param.taskPriority", + "out.state" : "param.taskState", + "out.taskExpiryDateFrom" : "param.taskExpiryDateFrom", + "out.taskExpiryDateTo" : "param.taskExpiryDateTo" + } + }, + "request" : { + "name" : "FindTask", + "description" : "This is a tool to handle request from user, don't use it to answer question. Helpful when user want to find tasks by attributes.", + "isVisibleOnStartList" : false + } + }, + "visual" : { + "at" : { "x" : 88, "y" : 64 } + }, + "connect" : [ + { "id" : "f2", "to" : "f5" } + ] + }, { + "id" : "f1", + "type" : "TaskEnd", + "visual" : { + "at" : { "x" : 512, "y" : 64 } + } + }, { + "id" : "f3", + "type" : "DialogCall", + "name" : "FindTaskWidget", + "config" : { + "dialog" : "ch.ivy.addon.portal.generic.ai.FindTaskWidget:start(ch.ivy.addon.portalkit.dto.dashboard.TaskDashboardWidget)", + "call" : { + "map" : { + "param.taskWidget" : "in.taskDashboardWidget" + } + } + }, + "visual" : { + "at" : { "x" : 384, "y" : 64 } + }, + "connect" : [ + { "id" : "f4", "to" : "f1" } + ] + }, { + "id" : "f5", + "type" : "Script", + "name" : "Initialize task widget", + "config" : { + "output" : { + "code" : [ + "import com.axonivy.portal.util.AiToolUtils;", + "", + "in.taskDashboardWidget = AiToolUtils.convertIvyToolToTaskDashboardWidget(", + " in.name, in.description, in.priority, in.state, in.taskExpiryDateFrom, in.taskExpiryDateTo, in.onlyMyTask);" + ] + }, + "sudo" : true + }, + "visual" : { + "at" : { "x" : 224, "y" : 64 } + }, + "connect" : [ + { "id" : "f6", "to" : "f3" } + ] + }, { + "id" : "f7", + "type" : "RequestStart", + "name" : "findCasesTool", + "config" : { + "signature" : "findCasesTool", + "input" : { + "params" : [ + { "name" : "caseName", "type" : "String", "desc" : "" }, + { "name" : "caseDescription", "type" : "String", "desc" : "" }, + { "name" : "caseState", "type" : "String", "desc" : "" } + ], + "map" : { + "out.description" : "param.caseDescription", + "out.name" : "param.caseName", + "out.state" : "param.caseState" + } + }, + "request" : { + "isVisibleOnStartList" : false + } + }, + "visual" : { + "at" : { "x" : 88, "y" : 200 } + }, + "connect" : [ + { "id" : "f11", "to" : "f10" } + ] + }, { + "id" : "f8", + "type" : "TaskEnd", + "visual" : { + "at" : { "x" : 512, "y" : 200 } + } + }, { + "id" : "f9", + "type" : "DialogCall", + "name" : "FindCaseWidget", + "config" : { + "dialog" : "ch.ivy.addon.portal.generic.ai.FindCaseWidget:start(ch.ivy.addon.portalkit.dto.dashboard.CaseDashboardWidget)", + "call" : { + "map" : { + "param.caseWidget" : "in.caseDashboardWidget" + } + } + }, + "visual" : { + "at" : { "x" : 384, "y" : 200 } + }, + "connect" : [ + { "id" : "f13", "to" : "f8" } + ] + }, { + "id" : "f10", + "type" : "Script", + "name" : "Initialize case widget", + "config" : { + "output" : { + "code" : [ + "import com.axonivy.portal.util.AiToolUtils;", + "", + "in.caseDashboardWidget = AiToolUtils.convertIvyToolToCaseDashboardWidget(", + " in.name, in.description, in.state);" + ] + }, + "sudo" : true + }, + "visual" : { + "at" : { "x" : 224, "y" : 200 } + }, + "connect" : [ + { "id" : "f12", "to" : "f9" } + ] + }, { + "id" : "f14", + "type" : "RequestStart", + "name" : "findProcessesTool", + "config" : { + "signature" : "findProcessesTool", + "input" : { + "params" : [ + { "name" : "processName", "type" : "String", "desc" : "" }, + { "name" : "processDescription", "type" : "String", "desc" : "" } + ], + "map" : { + "out.description" : "param.processDescription", + "out.name" : "param.processName" + } + }, + "request" : { + "isVisibleOnStartList" : false + } + }, + "visual" : { + "at" : { "x" : 88, "y" : 336 } + }, + "connect" : [ + { "id" : "f16", "to" : "f15" } + ] + }, { + "id" : "f15", + "type" : "Script", + "name" : "Initialize process widget", + "config" : { + "output" : { + "code" : [ + "import com.axonivy.portal.util.AiToolUtils;", + "", + "in.processDashboardWidget = AiToolUtils.convertIvyToolToProcessDashboardWidget(in.name, in.description);" + ] + }, + "sudo" : true + }, + "visual" : { + "at" : { "x" : 224, "y" : 336 } + }, + "connect" : [ + { "id" : "f18", "to" : "f17" } + ] + }, { + "id" : "f17", + "type" : "DialogCall", + "name" : "FindProcessWidget", + "config" : { + "dialog" : "ch.ivy.addon.portal.generic.ai.FindProcessWidget:start(ch.ivy.addon.portalkit.dto.dashboard.ProcessDashboardWidget)", + "call" : { + "map" : { + "param.processWidget" : "in.processDashboardWidget" + } + } + }, + "visual" : { + "at" : { "x" : 400, "y" : 336 } + }, + "connect" : [ + { "id" : "f20", "to" : "f19" } + ] + }, { + "id" : "f19", + "type" : "TaskEnd", + "visual" : { + "at" : { "x" : 512, "y" : 336 }, + "labelOffset" : { "x" : 13, "y" : 33 } + } + } ] +} \ No newline at end of file diff --git a/AxonIvyPortal/portal/processes/Business Processes/FindThirdPartyApplications.p.json b/AxonIvyPortal/portal/processes/Business Processes/FindThirdPartyApplications.p.json index d5241e6d5b2..9d40ac45365 100644 --- a/AxonIvyPortal/portal/processes/Business Processes/FindThirdPartyApplications.p.json +++ b/AxonIvyPortal/portal/processes/Business Processes/FindThirdPartyApplications.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "14C7834636E63BEA", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Business Processes/PortalInit.p.json b/AxonIvyPortal/portal/processes/Business Processes/PortalInit.p.json index 59a8d32c426..6ca3d8a9175 100644 --- a/AxonIvyPortal/portal/processes/Business Processes/PortalInit.p.json +++ b/AxonIvyPortal/portal/processes/Business Processes/PortalInit.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "1633E7FE0C8BCFA6", "config" : { "data" : "ch.ivy.add.portalkit.Data" diff --git a/AxonIvyPortal/portal/processes/Functional Processes/AccessibilityShortcutCustomWidget.p.json b/AxonIvyPortal/portal/processes/Functional Processes/AccessibilityShortcutCustomWidget.p.json new file mode 100644 index 00000000000..aa30d8aa0e7 --- /dev/null +++ b/AxonIvyPortal/portal/processes/Functional Processes/AccessibilityShortcutCustomWidget.p.json @@ -0,0 +1,48 @@ +{ + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", + "id" : "19265F23781A41B1", + "config" : { + "data" : "ch.ivy.add.portalkit.Data" + }, + "elements" : [ { + "id" : "f0", + "type" : "RequestStart", + "name" : "accessibilityShortcut.ivp", + "config" : { + "signature" : "accessibilityShortcut", + "request" : { + "name" : "<%=ivy.cms.co(\"/ch.ivy.addon.portalkit.ui.jsf/AccessibilityShortcuts/processName\")%>", + "customFields" : [ + { "name" : "isDashboardProcess", "value" : "true" } + ], + "isVisibleOnStartList" : false + } + }, + "visual" : { + "at" : { "x" : 96, "y" : 64 } + }, + "connect" : [ + { "id" : "f2", "to" : "f3" } + ] + }, { + "id" : "f1", + "type" : "TaskEnd", + "visual" : { + "at" : { "x" : 384, "y" : 64 }, + "labelOffset" : { "x" : 13, "y" : 33 } + } + }, { + "id" : "f3", + "type" : "DialogCall", + "name" : "AccessibilityShortcut", + "config" : { + "dialog" : "ch.ivy.addon.portalkit.component.AccessibilityShortcut:start()" + }, + "visual" : { + "at" : { "x" : 256, "y" : 64 } + }, + "connect" : [ + { "id" : "f4", "to" : "f1", "color" : "default" } + ] + } ] +} \ No newline at end of file diff --git a/AxonIvyPortal/portal/processes/Functional Processes/AnalyzeStatistic.p.json b/AxonIvyPortal/portal/processes/Functional Processes/AnalyzeStatistic.p.json index e298e62c28f..dec413d2e59 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/AnalyzeStatistic.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/AnalyzeStatistic.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "1602F513613E1225", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Functional Processes/BuildCaseQuery.p.json b/AxonIvyPortal/portal/processes/Functional Processes/BuildCaseQuery.p.json index a1ceda9ccfa..841d6844161 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/BuildCaseQuery.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/BuildCaseQuery.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "15F95D721D0C7224", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Functional Processes/BuildTaskQuery.p.json b/AxonIvyPortal/portal/processes/Functional Processes/BuildTaskQuery.p.json index f34d4cc45fa..24d3bb1b804 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/BuildTaskQuery.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/BuildTaskQuery.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "16812A78CEF8FB1A", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Functional Processes/CalculateTaskDelegate.p.json b/AxonIvyPortal/portal/processes/Functional Processes/CalculateTaskDelegate.p.json index a0708bdd518..03793cfb53c 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/CalculateTaskDelegate.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/CalculateTaskDelegate.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "15B8089000CE1FF7", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Functional Processes/ChangePassword.p.json b/AxonIvyPortal/portal/processes/Functional Processes/ChangePassword.p.json index fd54d4da420..34f002327e0 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/ChangePassword.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/ChangePassword.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "15E13D0DD56B6D3B", "kind" : "CALLABLE_SUB", "config" : { @@ -259,4 +259,4 @@ } } ] } ] -} +} \ No newline at end of file diff --git a/AxonIvyPortal/portal/processes/Functional Processes/DeepL.p.json b/AxonIvyPortal/portal/processes/Functional Processes/DeepL.p.json index 31296c6440b..9e2b6d09be2 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/DeepL.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/DeepL.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "188DC1996B169C8D", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Functional Processes/DeleteDocument.p.json b/AxonIvyPortal/portal/processes/Functional Processes/DeleteDocument.p.json index 3d1b7db3f3c..9ad75d14b1a 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/DeleteDocument.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/DeleteDocument.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "16AC05A855359627", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Functional Processes/DownloadDocument.p.json b/AxonIvyPortal/portal/processes/Functional Processes/DownloadDocument.p.json index 085a4b917b9..bf532df74fa 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/DownloadDocument.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/DownloadDocument.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "16AB5FD24113C5D2", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Functional Processes/ExportCaseToExcel.p.json b/AxonIvyPortal/portal/processes/Functional Processes/ExportCaseToExcel.p.json index fae621d0ed4..62adfcb1ff4 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/ExportCaseToExcel.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/ExportCaseToExcel.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "17554BEDC7CB0381", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Functional Processes/ExportTaskToExcel.p.json b/AxonIvyPortal/portal/processes/Functional Processes/ExportTaskToExcel.p.json index 7b79b440cee..1a0a43d3c0b 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/ExportTaskToExcel.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/ExportTaskToExcel.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "1754F17410CDFE4E", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Functional Processes/GetDocumentList.p.json b/AxonIvyPortal/portal/processes/Functional Processes/GetDocumentList.p.json index 943b1ac0150..04da45ce4ce 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/GetDocumentList.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/GetDocumentList.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "16A7C7CEF44FB794", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Functional Processes/HideSystemCase.p.json b/AxonIvyPortal/portal/processes/Functional Processes/HideSystemCase.p.json index 3041c0bdc60..10425771e37 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/HideSystemCase.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/HideSystemCase.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "15F999559D09FFA4", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Functional Processes/InitializeCaseDataModel.p.json b/AxonIvyPortal/portal/processes/Functional Processes/InitializeCaseDataModel.p.json index 1fea06b45e7..5d9c79c97ae 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/InitializeCaseDataModel.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/InitializeCaseDataModel.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "15FA059633297DF9", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Functional Processes/InitializeTaskDataModel.p.json b/AxonIvyPortal/portal/processes/Functional Processes/InitializeTaskDataModel.p.json index 3b50ca11bed..3d1c8cd46cc 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/InitializeTaskDataModel.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/InitializeTaskDataModel.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "15DBBB9E9FC55C0A", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Functional Processes/Login.p.json b/AxonIvyPortal/portal/processes/Functional Processes/Login.p.json index 87e2fdd3744..4cbbc45b0f9 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/Login.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/Login.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "1694805B8DB28D00", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Functional Processes/Logout.p.json b/AxonIvyPortal/portal/processes/Functional Processes/Logout.p.json index bb5aa264336..9e39058b322 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/Logout.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/Logout.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "15EF0843F1DB39F2", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Functional Processes/Navigator.p.json b/AxonIvyPortal/portal/processes/Functional Processes/Navigator.p.json index b0436d4a05a..011e466d7f3 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/Navigator.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/Navigator.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "1543CB1F7FCE2CC1", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Functional Processes/OpenPortalCaseDetailsHook.p.json b/AxonIvyPortal/portal/processes/Functional Processes/OpenPortalCaseDetailsHook.p.json index 7fd6fb0ba2f..259ca1c7d17 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/OpenPortalCaseDetailsHook.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/OpenPortalCaseDetailsHook.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "16DCDC775655EFD5", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Functional Processes/OpenPortalCases.p.json b/AxonIvyPortal/portal/processes/Functional Processes/OpenPortalCases.p.json index 2e4a62e0b7f..2917ebe3100 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/OpenPortalCases.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/OpenPortalCases.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "1540379C4B7261E4", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Functional Processes/OpenPortalSearch.p.json b/AxonIvyPortal/portal/processes/Functional Processes/OpenPortalSearch.p.json index 4ffed948a14..0c3e1b0867d 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/OpenPortalSearch.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/OpenPortalSearch.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "163AFDEDB4167156", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Functional Processes/OpenPortalTaskDetailsHook.p.json b/AxonIvyPortal/portal/processes/Functional Processes/OpenPortalTaskDetailsHook.p.json index 38b7155c3a8..fcf8f794425 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/OpenPortalTaskDetailsHook.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/OpenPortalTaskDetailsHook.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "16D289860FF9CFCA", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Functional Processes/OpenPortalTasks.p.json b/AxonIvyPortal/portal/processes/Functional Processes/OpenPortalTasks.p.json index 23fbcd42acc..3fa237ac08d 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/OpenPortalTasks.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/OpenPortalTasks.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "15493AEB89F5A807", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Functional Processes/ResetPassword.p.json b/AxonIvyPortal/portal/processes/Functional Processes/ResetPassword.p.json index 891da45d7c3..40e8973d921 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/ResetPassword.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/ResetPassword.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "17641AF79AEE04D7", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Functional Processes/SendPasswordResetEmail.p.json b/AxonIvyPortal/portal/processes/Functional Processes/SendPasswordResetEmail.p.json index a700366af89..005f6bfde4e 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/SendPasswordResetEmail.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/SendPasswordResetEmail.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "1764192CC5D94D93", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Functional Processes/SetBusinessEntityId.p.json b/AxonIvyPortal/portal/processes/Functional Processes/SetBusinessEntityId.p.json index 12db5d3aed9..96fa4be6016 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/SetBusinessEntityId.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/SetBusinessEntityId.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "161936E158EBC57F", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Functional Processes/UploadDocument.p.json b/AxonIvyPortal/portal/processes/Functional Processes/UploadDocument.p.json index 6a539658efb..60688d047c9 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/UploadDocument.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/UploadDocument.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "16AB53A8F6EAADFB", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Functional Processes/UploadDocumentChecker.p.json b/AxonIvyPortal/portal/processes/Functional Processes/UploadDocumentChecker.p.json index c5cbf5f423d..99ccb32833e 100644 --- a/AxonIvyPortal/portal/processes/Functional Processes/UploadDocumentChecker.p.json +++ b/AxonIvyPortal/portal/processes/Functional Processes/UploadDocumentChecker.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "16285772A1F890EE", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Ivy Data Processes/AbsenceService.p.json b/AxonIvyPortal/portal/processes/Ivy Data Processes/AbsenceService.p.json index 5c1e81dbd1d..9c25c2597f2 100644 --- a/AxonIvyPortal/portal/processes/Ivy Data Processes/AbsenceService.p.json +++ b/AxonIvyPortal/portal/processes/Ivy Data Processes/AbsenceService.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "14BDDCD00C5EA267", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Ivy Data Processes/CaseService.p.json b/AxonIvyPortal/portal/processes/Ivy Data Processes/CaseService.p.json index 6c0e2a09ce4..6afafcb0c3a 100644 --- a/AxonIvyPortal/portal/processes/Ivy Data Processes/CaseService.p.json +++ b/AxonIvyPortal/portal/processes/Ivy Data Processes/CaseService.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "14715F955CC5A35F", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Ivy Data Processes/LanguageService.p.json b/AxonIvyPortal/portal/processes/Ivy Data Processes/LanguageService.p.json index 77c910f8bc2..0dc124baa23 100644 --- a/AxonIvyPortal/portal/processes/Ivy Data Processes/LanguageService.p.json +++ b/AxonIvyPortal/portal/processes/Ivy Data Processes/LanguageService.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "14BE80F25BC9033C", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Ivy Data Processes/PasswordService.p.json b/AxonIvyPortal/portal/processes/Ivy Data Processes/PasswordService.p.json index fb0b44b53c4..6bb8f8354a5 100644 --- a/AxonIvyPortal/portal/processes/Ivy Data Processes/PasswordService.p.json +++ b/AxonIvyPortal/portal/processes/Ivy Data Processes/PasswordService.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "15E0CEDE89CC1D0E", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Ivy Data Processes/ProcessService.p.json b/AxonIvyPortal/portal/processes/Ivy Data Processes/ProcessService.p.json index bf0e94c9b80..90d509200c2 100644 --- a/AxonIvyPortal/portal/processes/Ivy Data Processes/ProcessService.p.json +++ b/AxonIvyPortal/portal/processes/Ivy Data Processes/ProcessService.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "1473A12DE00609FB", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Ivy Data Processes/SecurityService.p.json b/AxonIvyPortal/portal/processes/Ivy Data Processes/SecurityService.p.json index 602d4b7ac87..97d7356e449 100644 --- a/AxonIvyPortal/portal/processes/Ivy Data Processes/SecurityService.p.json +++ b/AxonIvyPortal/portal/processes/Ivy Data Processes/SecurityService.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "1485F329FE84F01E", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Ivy Data Processes/SideStepService.p.json b/AxonIvyPortal/portal/processes/Ivy Data Processes/SideStepService.p.json index d141a6f8e7a..e15274f514c 100644 --- a/AxonIvyPortal/portal/processes/Ivy Data Processes/SideStepService.p.json +++ b/AxonIvyPortal/portal/processes/Ivy Data Processes/SideStepService.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "167F3CD1442A57A4", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Ivy Data Processes/SubstituteService.p.json b/AxonIvyPortal/portal/processes/Ivy Data Processes/SubstituteService.p.json index 269c0add105..ba9f053f4dc 100644 --- a/AxonIvyPortal/portal/processes/Ivy Data Processes/SubstituteService.p.json +++ b/AxonIvyPortal/portal/processes/Ivy Data Processes/SubstituteService.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "14BECA923C1F4A4B", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Ivy Data Processes/TaskService.p.json b/AxonIvyPortal/portal/processes/Ivy Data Processes/TaskService.p.json index f18b05661b2..26e97c59a74 100644 --- a/AxonIvyPortal/portal/processes/Ivy Data Processes/TaskService.p.json +++ b/AxonIvyPortal/portal/processes/Ivy Data Processes/TaskService.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "146C8E81DE07F973", "kind" : "CALLABLE_SUB", "config" : { diff --git a/AxonIvyPortal/portal/processes/Start Processes/PortalStart.p.json b/AxonIvyPortal/portal/processes/Start Processes/PortalStart.p.json index da5eb804fdc..9966d5f5f3b 100644 --- a/AxonIvyPortal/portal/processes/Start Processes/PortalStart.p.json +++ b/AxonIvyPortal/portal/processes/Start Processes/PortalStart.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "1549F58C18A6C562", "config" : { "data" : "ch.ivy.addon.portal.generic.PortalStartData" @@ -1022,7 +1022,7 @@ } }, "visual" : { - "at" : { "x" : 96, "y" : 480 }, + "at" : { "x" : 96, "y" : 800 }, "labelOffset" : { "x" : -23, "y" : 41 } }, "connect" : [ @@ -1035,6 +1035,7 @@ "config" : { "output" : { "code" : [ + "import ch.ivy.addon.portalkit.util.DashboardUtils;", "import ch.ivy.addon.portalkit.ivydata.service.impl.TaskService;", "import ch.ivy.addon.portalkit.constant.CustomFields;", "import ch.ivy.addon.portalkit.dto.TaskEndInfo;", @@ -1065,6 +1066,10 @@ " in.dataModel = taskEndInfo.dataModel;", " in.isTaskStartedInDetails = taskEndInfo.isStartedInTaskDetails;", " in.portalPage = taskEndInfo.portalPage;", + " if (StringUtils.isNotBlank(taskEndInfo.getDashboardId())) {", + " in.isMainDashboard = DashboardUtils.isMainDashboard(taskEndInfo.getDashboardId(), true);", + " DashboardUtils.storeDashboardInSession(taskEndInfo.getDashboardId(), in.isMainDashboard);", + " }", " if (!in.isTaskStartedInDetails || in.backFromTaskDetails) {", " SecurityServiceUtils.removeSessionAttribute(taskEndInfoSessionAttributeKey);", " }", @@ -1082,7 +1087,7 @@ "sudo" : true }, "visual" : { - "at" : { "x" : 488, "y" : 480 } + "at" : { "x" : 488, "y" : 800 } }, "connect" : [ { "id" : "f2", "to" : "f1" } @@ -1112,18 +1117,12 @@ } }, "visual" : { - "at" : { "x" : 96, "y" : 320 }, + "at" : { "x" : 96, "y" : 640 }, "labelOffset" : { "x" : -55, "y" : 41 } }, "connect" : [ { "id" : "f204", "to" : "f203" } ] - }, { - "id" : "f57", - "type" : "TaskEnd", - "visual" : { - "at" : { "x" : 592, "y" : 720 } - } }, { "id" : "f58", "type" : "RequestStart", @@ -1135,11 +1134,11 @@ } }, "visual" : { - "at" : { "x" : 96, "y" : 720 }, + "at" : { "x" : 96, "y" : 232 }, "labelOffset" : { "x" : -15, "y" : 41 } }, "connect" : [ - { "id" : "f175", "to" : "S71" } + { "id" : "f175", "to" : "f34" } ] }, { "id" : "f103", @@ -1177,11 +1176,11 @@ } }, "visual" : { - "at" : { "x" : 96, "y" : 880 }, + "at" : { "x" : 96, "y" : 392 }, "labelOffset" : { "x" : -31, "y" : 41 } }, "connect" : [ - { "id" : "f178", "to" : "S80" } + { "id" : "f178", "to" : "f64" } ] }, { "id" : "f105", @@ -1189,12 +1188,6 @@ "visual" : { "at" : { "x" : 736, "y" : 960 } } - }, { - "id" : "f64", - "type" : "TaskEnd", - "visual" : { - "at" : { "x" : 592, "y" : 880 } - } }, { "id" : "f1", "type" : "Alternative", @@ -1205,18 +1198,18 @@ } }, "visual" : { - "at" : { "x" : 592, "y" : 480 } + "at" : { "x" : 592, "y" : 800 } }, "connect" : [ { "id" : "f30", "to" : "f22" }, { "id" : "f36", "to" : "S70" }, - { "id" : "f19", "to" : "f5", "via" : [ { "x" : 592, "y" : 528 }, { "x" : 1008, "y" : 528 } ] } + { "id" : "f19", "to" : "f5", "via" : [ { "x" : 592, "y" : 848 }, { "x" : 1008, "y" : 848 } ] } ] }, { "id" : "f0", "type" : "Alternative", "visual" : { - "at" : { "x" : 1008, "y" : 320 } + "at" : { "x" : 1008, "y" : 640 } }, "connect" : [ { "id" : "f92", "to" : "S60" } @@ -1230,7 +1223,7 @@ } }, "visual" : { - "at" : { "x" : 1008, "y" : 480 } + "at" : { "x" : 1008, "y" : 800 } }, "connect" : [ { "id" : "f20", "to" : "f0" }, @@ -1256,11 +1249,11 @@ } }, "visual" : { - "at" : { "x" : 96, "y" : 560 }, + "at" : { "x" : 96, "y" : 880 }, "labelOffset" : { "x" : -39, "y" : 41 } }, "connect" : [ - { "id" : "f13", "to" : "f4", "via" : [ { "x" : 344, "y" : 560 } ] } + { "id" : "f13", "to" : "f4", "via" : [ { "x" : 344, "y" : 880 } ] } ] }, { "id" : "f39", @@ -1711,7 +1704,7 @@ "homepage if you have" ], "visual" : { - "at" : { "x" : 1240, "y" : 320 }, + "at" : { "x" : 1240, "y" : 640 }, "size" : { "width" : 144, "height" : 44 } } }, { @@ -1733,7 +1726,7 @@ "id" : "f22", "type" : "Alternative", "visual" : { - "at" : { "x" : 592, "y" : 320 } + "at" : { "x" : 592, "y" : 640 } }, "connect" : [ { "id" : "f141", "to" : "f0" } @@ -1747,7 +1740,7 @@ } }, "visual" : { - "at" : { "x" : 344, "y" : 480 } + "at" : { "x" : 344, "y" : 800 } }, "connect" : [ { "id" : "f29", "to" : "f31" }, @@ -1766,7 +1759,7 @@ } }, "visual" : { - "at" : { "x" : 344, "y" : 320 } + "at" : { "x" : 344, "y" : 640 } }, "connect" : [ { "id" : "f49", "to" : "f31" }, @@ -1791,7 +1784,7 @@ } }, "visual" : { - "at" : { "x" : 344, "y" : 400 } + "at" : { "x" : 344, "y" : 720 } } }, { "id" : "f12", @@ -2147,11 +2140,11 @@ } }, "visual" : { - "at" : { "x" : 96, "y" : 240 }, + "at" : { "x" : 96, "y" : 560 }, "labelOffset" : { "x" : -39, "y" : 33 } }, "connect" : [ - { "id" : "f47", "to" : "f21", "via" : [ { "x" : 344, "y" : 240 } ] } + { "id" : "f47", "to" : "f123" } ] }, { "id" : "f122", @@ -2263,7 +2256,7 @@ "sudo" : true }, "visual" : { - "at" : { "x" : 488, "y" : 321 }, + "at" : { "x" : 488, "y" : 641 }, "size" : { "height" : 62 } }, "connect" : [ @@ -2281,23 +2274,28 @@ "type" : "Alternative", "config" : { "conditions" : { - "S60-f7" : "ch.addon.portal.generic.userprofile.homepage.HomepageUtils.isShowDashboard(in.#homepage, in.#isShowDashboard)", - "S60-f5" : "" + "S60-f7" : "in.isMainDashboard", + "S60-f5" : "ch.addon.portal.generic.userprofile.homepage.HomepageUtils.isShowDashboard(in.#homepage, in.#isShowDashboard)" } }, "visual" : { - "at" : { "x" : 284, "y" : 160 } + "at" : { "x" : 288, "y" : 160 } }, "connect" : [ - { "id" : "S60-f5", "to" : "S60-f4", "via" : [ { "x" : 284, "y" : 256 } ], "label" : { - "name" : "others", - "segment" : 1.43, - "offset" : { "y" : -10 } + { "id" : "S60-f7", "to" : "S60-f2", "via" : [ { "x" : 288, "y" : 57 } ], "label" : { + "name" : "main menu", + "segment" : 0.88, + "offset" : { "x" : 49, "y" : -22 } } }, - { "id" : "S60-f7", "to" : "S60-f12", "label" : { + { "id" : "S60-f5", "to" : "S60-f12", "label" : { "name" : "dashboard", - "segment" : 0.41, - "offset" : { "y" : -12 } + "segment" : 0.65, + "offset" : { "x" : -50, "y" : -10 } + } }, + { "id" : "S60-f3", "to" : "S60-f4", "via" : [ { "x" : 288, "y" : 256 } ], "label" : { + "name" : "others", + "segment" : 1.13, + "offset" : { "x" : 24, "y" : -10 } } } ] }, { @@ -2349,7 +2347,7 @@ } }, "visual" : { - "at" : { "x" : 404, "y" : 256 }, + "at" : { "x" : 488, "y" : 256 }, "size" : { "width" : 128 } } }, { @@ -2360,11 +2358,22 @@ "dialog" : "ch.ivy.addon.portal.generic.dashboard.PortalDashboard:start()" }, "visual" : { - "at" : { "x" : 440, "y" : 160 } + "at" : { "x" : 488, "y" : 160 } + } + }, { + "id" : "S60-f2", + "type" : "DialogCall", + "name" : "PortalMainDashboard", + "config" : { + "dialog" : "ch.ivy.addon.portal.generic.dashboard.PortalMainDashboard:start()" + }, + "visual" : { + "at" : { "x" : 488, "y" : 57 }, + "size" : { "width" : 160, "height" : 62 } } } ], "visual" : { - "at" : { "x" : 1096, "y" : 320 } + "at" : { "x" : 1096, "y" : 640 } } }, { "id" : "S10", @@ -2584,209 +2593,9 @@ } } ], "visual" : { - "at" : { "x" : 1165, "y" : 479 }, + "at" : { "x" : 1165, "y" : 799 }, "size" : { "width" : 251, "height" : 65 } } - }, { - "id" : "S30", - "type" : "UserBpmnElement", - "name" : "Case List Page", - "elements" : [ { - "id" : "S30-f62", - "type" : "SubProcessCall", - "name" : [ - "Initialize case ", - "data model" - ], - "config" : { - "processCall" : "Functional Processes/InitializeCaseDataModel:call()", - "output" : { - "map" : { - "out" : "in", - "out.caseDataModel" : "result.caseDataModel" - } - } - }, - "visual" : { - "at" : { "x" : 192, "y" : 160 } - }, - "connect" : [ - { "id" : "S30-f61", "to" : "S30-f59" } - ] - }, { - "id" : "S30-f59", - "type" : "Script", - "name" : [ - "build data model", - "and case view" - ], - "config" : { - "output" : { - "code" : [ - "import ch.ivy.addon.portalkit.util.PermissionUtils;", - "import ch.ivy.addon.portalkit.util.SecurityServiceUtils;", - "import ch.ivy.addon.portal.generic.view.CaseView;", - "", - "boolean hasReadAllCasesPermission = PermissionUtils.checkReadAllCasesPermission();", - "in.caseDataModel.setAdminQuery(hasReadAllCasesPermission);", - "", - "in.caseView = CaseView.create().dataModel(in.caseDataModel).buildNewView();" - ] - } - }, - "visual" : { - "at" : { "x" : 352, "y" : 160 }, - "size" : { "width" : 128 } - }, - "connect" : [ - { "id" : "S30-f60", "to" : "S30-f55" } - ] - }, { - "id" : "S30-f55", - "type" : "SubProcessCall", - "name" : "OpenPortalCases", - "config" : { - "processCall" : "Functional Processes/OpenPortalCases:useView(ch.ivy.addon.portal.generic.view.CaseView)", - "call" : { - "map" : { - "param.view" : "in.caseView" - } - } - }, - "visual" : { - "at" : { "x" : 544, "y" : 160 }, - "size" : { "height" : 48 } - }, - "connect" : [ - { "id" : "S30-f1", "to" : "S30-g1" } - ] - }, { - "id" : "S30-g0", - "type" : "EmbeddedStart", - "name" : "in 1", - "visual" : { - "at" : { "x" : 64, "y" : 160 }, - "labelOffset" : { "x" : 18, "y" : 25 } - }, - "parentConnector" : "f176", - "connect" : [ - { "id" : "S30-f0", "to" : "S30-f62" } - ] - }, { - "id" : "S30-g1", - "type" : "EmbeddedEnd", - "name" : "out 1", - "visual" : { - "at" : { "x" : 672, "y" : 160 }, - "labelOffset" : { "x" : 21, "y" : 25 } - }, - "parentConnector" : "f25" - } ], - "visual" : { - "at" : { "x" : 488, "y" : 720 } - }, - "connect" : [ - { "id" : "f25", "to" : "f57" } - ] - }, { - "id" : "S20", - "type" : "UserBpmnElement", - "name" : "Task List Page", - "elements" : [ { - "id" : "S20-f69", - "type" : "Script", - "name" : [ - "build data model ", - "and task view" - ], - "config" : { - "output" : { - "code" : [ - "import ch.ivy.addon.portalkit.enums.TaskAssigneeType;", - "import ch.ivy.addon.portal.generic.view.TaskView;", - "import ch.ivy.addon.portalkit.util.PermissionUtils;", - "", - "boolean hasReadAllTasksPermisson = PermissionUtils.checkReadAllTasksPermission();", - "in.dataModel.setAdminQuery(hasReadAllTasksPermisson);", - "in.dataModel.setTaskAssigneeType(TaskAssigneeType.ALL);", - "", - "in.taskView = TaskView.create().dataModel(in.dataModel).noTaskFoundMessage(\"\").showHeaderToolbar(false).createNewTaskView();" - ] - } - }, - "visual" : { - "at" : { "x" : 352, "y" : 160 }, - "size" : { "height" : 48 } - }, - "connect" : [ - { "id" : "S20-f67", "to" : "S20-f84" } - ] - }, { - "id" : "S20-f84", - "type" : "SubProcessCall", - "name" : "OpenPortalTasks", - "config" : { - "processCall" : "Functional Processes/OpenPortalTasks:useView(ch.ivy.addon.portal.generic.view.TaskView)", - "call" : { - "map" : { - "param.taskView" : "in.taskView" - } - } - }, - "visual" : { - "at" : { "x" : 544, "y" : 160 }, - "size" : { "width" : 104, "height" : 40 } - }, - "connect" : [ - { "id" : "S20-f1", "to" : "S20-g1" } - ] - }, { - "id" : "S20-f73", - "type" : "SubProcessCall", - "name" : "Init data model", - "config" : { - "processCall" : "Functional Processes/InitializeTaskDataModel:call()", - "output" : { - "map" : { - "out" : "in", - "out.dataModel" : "result.dataModel" - } - } - }, - "visual" : { - "at" : { "x" : 192, "y" : 160 } - }, - "connect" : [ - { "id" : "S20-f118", "to" : "S20-f69" } - ] - }, { - "id" : "S20-g0", - "type" : "EmbeddedStart", - "name" : "in 1", - "visual" : { - "at" : { "x" : 64, "y" : 160 }, - "labelOffset" : { "x" : 18, "y" : 25 } - }, - "parentConnector" : "f179", - "connect" : [ - { "id" : "S20-f0", "to" : "S20-f73" } - ] - }, { - "id" : "S20-g1", - "type" : "EmbeddedEnd", - "name" : "out 1", - "visual" : { - "at" : { "x" : 672, "y" : 160 }, - "labelOffset" : { "x" : 21, "y" : 25 } - }, - "parentConnector" : "f17" - } ], - "visual" : { - "at" : { "x" : 488, "y" : 880 } - }, - "connect" : [ - { "id" : "f17", "to" : "f64" } - ] }, { "id" : "S70", "type" : "ServiceBpmnElement", @@ -2882,7 +2691,7 @@ "parentConnector" : "f40" } ], "visual" : { - "at" : { "x" : 848, "y" : 480 }, + "at" : { "x" : 848, "y" : 800 }, "size" : { "width" : 248, "height" : 64 } }, "connect" : [ @@ -3019,7 +2828,7 @@ "type" : "DialogCall", "name" : "Task Note History", "config" : { - "dialog" : "ch.ivy.addon.portal.generic.TaskNoteHistory:start(java.util.List,String,ch.ivyteam.ivy.workflow.ITask)", + "dialog" : "ch.ivy.addon.portal.generic.TaskNoteHistory:start(List,String,ch.ivyteam.ivy.workflow.ITask)", "call" : { "map" : { "param.notes" : "in.notes", @@ -3196,7 +3005,7 @@ "signature" : "DefaultApplicationHomePageInTeams" }, "visual" : { - "at" : { "x" : 96, "y" : 400 }, + "at" : { "x" : 96, "y" : 720 }, "labelOffset" : { "x" : -79, "y" : 41 } }, "connect" : [ @@ -3218,7 +3027,7 @@ } }, "visual" : { - "at" : { "x" : 200, "y" : 400 } + "at" : { "x" : 200, "y" : 720 } }, "connect" : [ { "id" : "f205", "to" : "f203" } @@ -3227,7 +3036,7 @@ "id" : "f203", "type" : "Alternative", "visual" : { - "at" : { "x" : 200, "y" : 320 } + "at" : { "x" : 200, "y" : 640 } }, "connect" : [ { "id" : "f43", "to" : "f21" } @@ -3240,7 +3049,7 @@ "signature" : "DefaultCaseListPageInTeams" }, "visual" : { - "at" : { "x" : 96, "y" : 640 }, + "at" : { "x" : 96, "y" : 152 }, "labelOffset" : { "x" : -55, "y" : 41 } }, "connect" : [ @@ -3253,19 +3062,21 @@ "config" : { "output" : { "code" : [ + "import ch.addon.portal.generic.userprofile.homepage.HomepageUtils;", "import ch.addon.portal.generic.userprofile.homepage.HomepageType;", "import ch.ivy.addon.portalkit.enums.SessionAttribute;", "import ch.ivy.addon.portalkit.util.SecurityServiceUtils;", "SecurityServiceUtils.setSessionAttribute(SessionAttribute.PORTAL_IN_TEAMS.toString(), true);", - "SecurityServiceUtils.setSessionAttribute(SessionAttribute.DEFAULT_PAGE_IN_TEAMS.toString(), HomepageType.CASE.toString());" + "SecurityServiceUtils.setSessionAttribute(SessionAttribute.DEFAULT_PAGE_IN_TEAMS.toString(), ", + " HomepageUtils.generateDefaultCaseListDashboardHomepageId());" ] } }, "visual" : { - "at" : { "x" : 200, "y" : 640 } + "at" : { "x" : 200, "y" : 152 } }, "connect" : [ - { "id" : "f61", "to" : "S71", "via" : [ { "x" : 344, "y" : 640 } ] } + { "id" : "f61", "to" : "f34", "via" : [ { "x" : 344, "y" : 152 } ] } ] }, { "id" : "f214", @@ -3274,19 +3085,21 @@ "config" : { "output" : { "code" : [ + "import ch.addon.portal.generic.userprofile.homepage.HomepageUtils;", "import ch.addon.portal.generic.userprofile.homepage.HomepageType;", "import ch.ivy.addon.portalkit.enums.SessionAttribute;", "import ch.ivy.addon.portalkit.util.SecurityServiceUtils;", "SecurityServiceUtils.setSessionAttribute(SessionAttribute.PORTAL_IN_TEAMS.toString(), true);", - "SecurityServiceUtils.setSessionAttribute(SessionAttribute.DEFAULT_PAGE_IN_TEAMS.toString(), HomepageType.TASK.toString());" + "SecurityServiceUtils.setSessionAttribute(SessionAttribute.DEFAULT_PAGE_IN_TEAMS.toString(), ", + " HomepageUtils.generateDefaultTaskListDashboardHomepageId());" ] } }, "visual" : { - "at" : { "x" : 200, "y" : 800 } + "at" : { "x" : 200, "y" : 312 } }, "connect" : [ - { "id" : "f24", "to" : "S80", "via" : [ { "x" : 344, "y" : 800 } ] } + { "id" : "f24", "to" : "f64", "via" : [ { "x" : 344, "y" : 312 } ] } ] }, { "id" : "f215", @@ -3296,7 +3109,7 @@ "signature" : "DefaultTaskListPageInTeams" }, "visual" : { - "at" : { "x" : 96, "y" : 800 }, + "at" : { "x" : 96, "y" : 312 }, "labelOffset" : { "x" : -55, "y" : 41 } }, "connect" : [ @@ -3629,143 +3442,6 @@ "connect" : [ { "id" : "f276", "to" : "f105" } ] - }, { - "id" : "S71", - "type" : "EmbeddedProcess", - "name" : "Authorize", - "elements" : [ { - "id" : "S71-f268", - "type" : "TaskEnd", - "visual" : { - "at" : { "x" : 152, "y" : 224 } - } - }, { - "id" : "S71-f209", - "type" : "Alternative", - "name" : "Authorized?", - "config" : { - "conditions" : { - "S71-f2" : "ch.ivy.addon.portalkit.util.PermissionUtils.checkAccessFullCaseListPermission()" - } - }, - "visual" : { - "at" : { "x" : 152, "y" : 144 }, - "labelOffset" : { "y" : -24 } - }, - "connect" : [ - { "id" : "S71-f2", "to" : "S71-g2", "label" : { - "name" : "Yes" - } }, - { "id" : "S71-f269", "to" : "S71-f268", "label" : { - "name" : "No", - "segment" : 0.56 - } } - ] - }, { - "id" : "S71-g0", - "type" : "EmbeddedStart", - "name" : "in 1", - "visual" : { - "at" : { "x" : 64, "y" : 64 } - }, - "parentConnector" : "f61", - "connect" : [ - { "id" : "S71-f0", "to" : "S71-f209", "via" : [ { "x" : 152, "y" : 64 } ] } - ] - }, { - "id" : "S71-g1", - "type" : "EmbeddedStart", - "name" : "in 2", - "visual" : { - "at" : { "x" : 64, "y" : 144 } - }, - "parentConnector" : "f175", - "connect" : [ - { "id" : "S71-f1", "to" : "S71-f209" } - ] - }, { - "id" : "S71-g2", - "type" : "EmbeddedEnd", - "name" : "out 1", - "visual" : { - "at" : { "x" : 224, "y" : 144 } - }, - "parentConnector" : "f176" - } ], - "visual" : { - "at" : { "x" : 344, "y" : 720 } - }, - "connect" : [ - { "id" : "f176", "to" : "S30" } - ] - }, { - "id" : "S80", - "type" : "EmbeddedProcess", - "name" : "Authorize", - "elements" : [ { - "id" : "S80-f212", - "type" : "Alternative", - "name" : "Authorized?", - "config" : { - "conditions" : { - "S80-f2" : "ch.ivy.addon.portalkit.util.PermissionUtils.checkAccessFullTaskListPermission()" - } - }, - "visual" : { - "at" : { "x" : 152, "y" : 144 }, - "labelOffset" : { "y" : -24 } - }, - "connect" : [ - { "id" : "S80-f2", "to" : "S80-g2", "label" : { - "name" : "Yes" - } }, - { "id" : "S80-f271", "to" : "S80-f270", "label" : { - "name" : "No" - } } - ] - }, { - "id" : "S80-f270", - "type" : "TaskEnd", - "visual" : { - "at" : { "x" : 152, "y" : 224 } - } - }, { - "id" : "S80-g0", - "type" : "EmbeddedStart", - "name" : "in 1", - "visual" : { - "at" : { "x" : 72, "y" : 64 } - }, - "parentConnector" : "f24", - "connect" : [ - { "id" : "S80-f0", "to" : "S80-f212", "via" : [ { "x" : 152, "y" : 64 } ] } - ] - }, { - "id" : "S80-g1", - "type" : "EmbeddedStart", - "name" : "in 2", - "visual" : { - "at" : { "x" : 72, "y" : 144 } - }, - "parentConnector" : "f178", - "connect" : [ - { "id" : "S80-f1", "to" : "S80-f212" } - ] - }, { - "id" : "S80-g2", - "type" : "EmbeddedEnd", - "name" : "out 1", - "visual" : { - "at" : { "x" : 232, "y" : 144 } - }, - "parentConnector" : "f179" - } ], - "visual" : { - "at" : { "x" : 344, "y" : 880 } - }, - "connect" : [ - { "id" : "f179", "to" : "S20" } - ] }, { "id" : "f79", "type" : "Script", @@ -4159,10 +3835,10 @@ } }, "visual" : { - "at" : { "x" : 96, "y" : 152 } + "at" : { "x" : 96, "y" : 472 } }, "connect" : [ - { "id" : "f212", "to" : "f170" } + { "id" : "f115", "to" : "f17" } ] }, { "id" : "f170", @@ -4171,12 +3847,14 @@ "config" : { "output" : { "code" : [ + "import ch.ivy.addon.portalkit.dto.dashboard.Dashboard;", "import ch.ivy.addon.portalkit.util.DashboardUtils;", "import ch.addon.portal.generic.userprofile.homepage.HomepageType;", "import ch.ivy.addon.portalkit.enums.SessionAttribute;", "import ch.ivy.addon.portalkit.util.SecurityServiceUtils;", "", - "DashboardUtils.storeDashboardInSession(in.dashboardId);", + "in.isMainDashboard = DashboardUtils.isMainDashboard(in.dashboardId, true);", + "DashboardUtils.storeDashboardInSession(in.dashboardId, in.isMainDashboard);", "in.isOpenDashboardFromLink = true;", "if (in.isOpenWithoutMenu) {", " SecurityServiceUtils.setSessionAttribute(SessionAttribute.PORTAL_IN_TEAMS.toString(), true);", @@ -4186,10 +3864,10 @@ } }, "visual" : { - "at" : { "x" : 216, "y" : 152 } + "at" : { "x" : 880, "y" : 472 } }, "connect" : [ - { "id" : "f218", "to" : "f21", "via" : [ { "x" : 344, "y" : 152 } ] } + { "id" : "f218", "to" : "f123", "via" : [ { "x" : 880, "y" : 560 } ] } ] }, { "id" : "f219", @@ -4612,8 +4290,9 @@ "config" : { "output" : { "code" : [ + "import ch.ivy.addon.portalkit.util.TaskUtils;", "import ch.ivy.addon.portalkit.bean.TaskActionBean;", - "in.isAuthorized = in.#taskSelected is initialized && TaskActionBean.canReset(in.#taskSelected);" + "in.isAuthorized = in.#taskSelected is initialized && TaskUtils.canReset(in.#taskSelected);" ] } }, @@ -4657,5 +4336,153 @@ "connect" : [ { "id" : "f294", "to" : "f271" } ] + }, { + "id" : "f32", + "type" : "Script", + "name" : "Init data", + "config" : { + "output" : { + "code" : [ + "import ch.ivy.addon.portalkit.util.DashboardUtils;", + "in.dashboardId = DashboardUtils.DEFAULT_TASK_LIST_DASHBOARD;" + ] + } + }, + "visual" : { + "at" : { "x" : 488, "y" : 392 } + }, + "connect" : [ + { "id" : "f113", "to" : "f35" } + ] + }, { + "id" : "f64", + "type" : "Alternative", + "visual" : { + "at" : { "x" : 344, "y" : 392 }, + "labelOffset" : { "x" : 14, "y" : 34 } + }, + "connect" : [ + { "id" : "f70", "to" : "f32" } + ] + }, { + "id" : "S74", + "type" : "EmbeddedProcess", + "name" : "Authorize", + "elements" : [ { + "id" : "S74-f26", + "type" : "Alternative", + "name" : "Authorize?", + "config" : { + "conditions" : { + "S74-f27" : "(ch.ivy.addon.portalkit.util.DashboardUtils.DEFAULT_TASK_LIST_DASHBOARD.equals(in.dashboardId) && !ch.ivy.addon.portalkit.util.PermissionUtils.checkAccessFullTaskListPermission()) ||\r\n(ch.ivy.addon.portalkit.util.DashboardUtils.DEFAULT_CASE_LIST_DASHBOARD.equals(in.dashboardId) && !ch.ivy.addon.portalkit.util.PermissionUtils.checkAccessFullCaseListPermission())" + } + }, + "visual" : { + "at" : { "x" : 152, "y" : 144 }, + "labelOffset" : { "x" : -24, "y" : -8 } + }, + "connect" : [ + { "id" : "S74-f27", "to" : "S74-f17", "label" : { + "name" : "No", + "offset" : { "x" : -15, "y" : -2 } + } }, + { "id" : "S74-f2", "to" : "S74-g2", "label" : { + "name" : "Yes", + "offset" : { "x" : -4, "y" : -10 } + } } + ] + }, { + "id" : "S74-f17", + "type" : "TaskEnd", + "visual" : { + "at" : { "x" : 152, "y" : 208 }, + "labelOffset" : { "x" : 13, "y" : 33 } + } + }, { + "id" : "S74-g0", + "type" : "EmbeddedStart", + "name" : "in 1", + "visual" : { + "at" : { "x" : 48, "y" : 144 }, + "labelOffset" : { "x" : 3, "y" : 23 } + }, + "parentConnector" : "f26", + "connect" : [ + { "id" : "S74-f0", "to" : "S74-f26" } + ] + }, { + "id" : "S74-g2", + "type" : "EmbeddedEnd", + "name" : "out 1", + "visual" : { + "at" : { "x" : 256, "y" : 144 }, + "labelOffset" : { "x" : 3, "y" : 23 } + }, + "parentConnector" : "f117" + } ], + "visual" : { + "at" : { "x" : 736, "y" : 472 } + }, + "connect" : [ + { "id" : "f117", "to" : "f170" } + ] + }, { + "id" : "f17", + "type" : "Alternative", + "visual" : { + "at" : { "x" : 592, "y" : 472 }, + "labelOffset" : { "x" : 14, "y" : 34 } + }, + "connect" : [ + { "id" : "f26", "to" : "S74" } + ] + }, { + "id" : "f27", + "type" : "Script", + "name" : "Init data", + "config" : { + "output" : { + "code" : [ + "import ch.ivy.addon.portalkit.util.DashboardUtils;", + "in.dashboardId = DashboardUtils.DEFAULT_CASE_LIST_DASHBOARD;" + ] + } + }, + "visual" : { + "at" : { "x" : 488, "y" : 232 } + }, + "connect" : [ + { "id" : "f121", "to" : "f35", "via" : [ { "x" : 592, "y" : 232 } ] } + ] + }, { + "id" : "f34", + "type" : "Alternative", + "visual" : { + "at" : { "x" : 344, "y" : 232 }, + "labelOffset" : { "x" : 14, "y" : 34 } + }, + "connect" : [ + { "id" : "f25", "to" : "f27" } + ] + }, { + "id" : "f35", + "type" : "Alternative", + "visual" : { + "at" : { "x" : 592, "y" : 392 }, + "labelOffset" : { "x" : 14, "y" : 34 } + }, + "connect" : [ + { "id" : "f57", "to" : "f17", "color" : "default" } + ] + }, { + "id" : "f123", + "type" : "Alternative", + "visual" : { + "at" : { "x" : 344, "y" : 560 }, + "labelOffset" : { "x" : 14, "y" : 34 } + }, + "connect" : [ + { "id" : "f124", "to" : "f21" } + ] } ] } \ No newline at end of file diff --git a/AxonIvyPortal/portal/processes/SynchronizeDataProcesses/CleanUpObsoletedUserData.p.json b/AxonIvyPortal/portal/processes/SynchronizeDataProcesses/CleanUpObsoletedUserData.p.json index 29f7bc55dc2..548677572fb 100644 --- a/AxonIvyPortal/portal/processes/SynchronizeDataProcesses/CleanUpObsoletedUserData.p.json +++ b/AxonIvyPortal/portal/processes/SynchronizeDataProcesses/CleanUpObsoletedUserData.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "1626C02D46BF5153", "description" : "This is a scheduled process of Portal", "config" : { diff --git a/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/CaseSubMenuItem.java b/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/CaseSubMenuItem.java deleted file mode 100644 index 155cfcb042a..00000000000 --- a/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/CaseSubMenuItem.java +++ /dev/null @@ -1,17 +0,0 @@ -package ch.addon.portal.generic.menu; - -import com.axonivy.portal.components.publicapi.ApplicationMultiLanguageAPI; - -import ch.addon.portal.generic.userprofile.homepage.HomepageType; -import ch.ivy.addon.portal.generic.navigation.PortalNavigator; -import ch.ivy.addon.portalkit.enums.MenuKind; - -public class CaseSubMenuItem extends SubMenuItem { - public CaseSubMenuItem() { - this.icon = "si si-layout-bullets"; - this.menuKind = MenuKind.CASE; - this.label = ApplicationMultiLanguageAPI.getCmsValueByUserLocale("/ch.ivy.addon.portalkit.ui.jsf/caseList/cases"); - this.name = HomepageType.CASE.name(); - this.link = PortalNavigator.getSubMenuItemUrlOfCurrentApplication(MenuKind.CASE); - } -} diff --git a/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/MenuView.java b/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/MenuView.java index 2691ea927f8..668df5c4364 100644 --- a/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/MenuView.java +++ b/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/MenuView.java @@ -1,9 +1,9 @@ package ch.addon.portal.generic.menu; -import static ch.ivy.addon.portalkit.util.DashboardUtils.DASHBOARD_MENU_ITEM_PATTERN; import static ch.ivy.addon.portalkit.util.DashboardUtils.DASHBOARD_MENU_JS_CLASS; -import static ch.ivy.addon.portalkit.util.DashboardUtils.DASHBOARD_MENU_PATTERN; import static ch.ivy.addon.portalkit.util.DashboardUtils.DASHBOARD_PAGE_URL; +import static ch.ivy.addon.portalkit.util.DashboardUtils.PARENT_DASHBOARD_MENU_PATTERN; +import static ch.ivy.addon.portalkit.util.DashboardUtils.SUB_DASHBOARD_MENU_PATTERN; import static java.util.Objects.isNull; import java.io.IOException; @@ -20,7 +20,6 @@ import javax.faces.context.FacesContext; import javax.faces.event.ActionEvent; -import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.primefaces.PrimeFaces; @@ -92,6 +91,8 @@ public void buildPortalLeftMenu(ITask workingTask, boolean isWorkingOnATask) { mainMenuModel = new DefaultMenuModel(); mainMenuModel.getElements().add(buildDashboardItem()); // menuIndex = 0 + + List subMenuItems = PortalMenuNavigator.callSubMenuItemsProcess(); int menuIndex = 1; for (SubMenuItem subMenu : subMenuItems) { @@ -99,7 +100,7 @@ public void buildPortalLeftMenu(ITask workingTask, boolean isWorkingOnATask) { mainMenuModel.getElements().add(item); menuIndex++; } - + List thirdPartyApps = PortalMenuNavigator.getThirdPartyApps(); for (Application app : thirdPartyApps) { DefaultMenuItem item = buildThirdPartyItem(app, menuIndex); @@ -144,65 +145,114 @@ private DefaultMenuItem buildThirdPartyItem(Application application, int menuInd private MenuElement buildDashboardItem() { var dashboardTitle = translate(DASHBOARD); var dashboardId = ""; - String dashboardLink = getDefaultPortalStartUrl(); - String defaultHomepageConfig = HomepageUtils.getHomepageName(); + String dashboardLink = determineDashboardLink(); String currentLanguage = UserUtils.getUserLanguage(); - HomepageType configHomepageType = HomepageType.getType(defaultHomepageConfig); - if (HomepageType.DASHBOARD != configHomepageType) { - dashboardLink = getDefaultDashboardUrl(); - } - + MainMenuEntryService mainMenuEntryService = new MainMenuEntryService(); String mainMenuDisplayName = mainMenuEntryService.getNameInCurrentLocale(); String mainMenuIcon = mainMenuEntryService.getMenuIcon(); - + + var subItemDashboards = getSubItemDashboards(); + if (subItemDashboards.size() > 1) { + return buildDashboardGroupMenu(subItemDashboards, dashboardTitle, mainMenuDisplayName, mainMenuIcon, + currentLanguage, dashboardLink); + } + + return buildSingleDashboardMenu(dashboardTitle, dashboardId, dashboardLink); + } + + private String determineDashboardLink() { + String defaultHomepageConfig = HomepageUtils.getHomepageName(); + HomepageType configHomepageType = HomepageType.getType(defaultHomepageConfig); + + if (HomepageType.DASHBOARD != configHomepageType) { + return getDefaultDashboardUrl(); + } + + return getDefaultPortalStartUrl(); + } + + private List getSubItemDashboards() { var dashboards = getDashboardCache().dashboards; - if (CollectionUtils.isNotEmpty(dashboards)) { - DefaultSubMenu dashboardGroupMenu = DefaultSubMenu.builder() - .label(StringUtils.isBlank(mainMenuDisplayName) ? dashboardTitle : mainMenuDisplayName) + return dashboards.stream().filter(dashboard -> !dashboard.getIsTopMenu()).toList(); + } + + private MenuElement buildDashboardGroupMenu(List subItemDashboards, String defaultTitle, + String mainMenuDisplayName, String mainMenuIcon, String currentLanguage, String dashboardLink) { + + DefaultSubMenu dashboardGroupMenu = createDashboardGroupMenu(defaultTitle, mainMenuDisplayName, mainMenuIcon); + + for (Dashboard board : subItemDashboards) { + if (board.getIsTopMenu()) { + continue; + } + String iconClass = determineIconClass(board); + var dashboardMenu = createDashboardMenu(board, dashboardLink, iconClass); + + String localizedTitle = + getLocalizedTitle(board, currentLanguage, (String) ((DefaultMenuItem) dashboardMenu).getValue()); + ((DefaultMenuItem) dashboardMenu).setValue(localizedTitle); + + dashboardGroupMenu.getElements().add(dashboardMenu); + } + + setMenuExpansion(dashboardGroupMenu); + return dashboardGroupMenu; + } + + private DefaultSubMenu createDashboardGroupMenu(String defaultTitle, String mainMenuDisplayName, + String mainMenuIcon) { + return DefaultSubMenu.builder().label(StringUtils.isBlank(mainMenuDisplayName) ? defaultTitle : mainMenuDisplayName) .icon(StringUtils.isBlank(mainMenuIcon) ? PortalMenuItem.DEFAULT_DASHBOARD_ICON : mainMenuIcon) - .id(String.format(DASHBOARD_MENU_PATTERN, MenuKind.DASHBOARD.name())) - .styleClass(DASHBOARD_MENU_JS_CLASS) + .id(String.format(PARENT_DASHBOARD_MENU_PATTERN, MenuKind.DASHBOARD.name())).styleClass(DASHBOARD_MENU_JS_CLASS) .build(); - if (dashboards.size() > 1) { - for (var board : dashboards) { - if (StringUtils.isBlank(board.getIcon())) { - board.setIcon(board.getIsPublic() ? "si-network-share" : "si-single-neutral-shield"); - } - var iconClass = (board.getIcon().startsWith("fa") ? "fa " : "si ") + board.getIcon(); - var dashboardMenu = new PortalMenuBuilder(board.getTitle(), MenuKind.DASHBOARD, this.isWorkingOnATask) - .icon(iconClass).url(dashboardLink).workingTaskId(this.workingTaskId).build(); - dashboardMenu.setId(String.format(DASHBOARD_MENU_ITEM_PATTERN, board.getId())); - - String defaultTitle = (String) dashboardMenu.getValue(); - String title = board.getTitles().stream() - .filter(name -> StringUtils.equalsIgnoreCase(name.getLocale().toString(), currentLanguage) - && StringUtils.isNotBlank(name.getValue())) - .map(DisplayName::getValue).findFirst().orElse(defaultTitle); - dashboardMenu.setValue(title); - dashboardGroupMenu.getElements().add(dashboardMenu); - } - if (StringUtils.endsWith(Ivy.request().getRootRequest().getRequestPath(), DASHBOARD_PAGE_URL)) { - dashboardGroupMenu.setExpanded(true); - } - return dashboardGroupMenu; - } else { - dashboardTitle = dashboards.get(0).getTitle(); - dashboardId = dashboards.get(0).getId(); - } + } + + private String determineIconClass(Dashboard board) { + if (StringUtils.isBlank(board.getIcon())) { + board.setIcon(board.getIsPublic() ? "si-network-share" : "si-single-neutral-shield"); } + return (board.getIcon().startsWith("fa") ? "fa " : "si ") + board.getIcon(); + } + + private MenuElement createDashboardMenu(Dashboard board, String dashboardLink, String iconClass) { + var dashboardMenu = new PortalMenuBuilder(board.getTitle(), MenuKind.DASHBOARD, this.isWorkingOnATask) + .icon(iconClass).url(dashboardLink).workingTaskId(this.workingTaskId).build(); + dashboardMenu.setId(String.format(SUB_DASHBOARD_MENU_PATTERN, board.getId())); + return dashboardMenu; + } + private String getLocalizedTitle(Dashboard board, String currentLanguage, String defaultTitle) { + return board.getTitles().stream() + .filter(name -> StringUtils.equalsIgnoreCase(name.getLocale().toString(), currentLanguage) + && StringUtils.isNotBlank(name.getValue())) + .map(DisplayName::getValue).findFirst().orElse(defaultTitle); + } + + private void setMenuExpansion(DefaultSubMenu dashboardGroupMenu) { + String activeDashboardId = (String) session().getAttribute(SELECTED_MENU_ID); + boolean isMainDashboardMenu = + StringUtils.isNotEmpty(activeDashboardId) && activeDashboardId.endsWith(DashboardUtils.MAIN_DASHBOARD_MENU_POSTFIX); + + if (StringUtils.endsWith(Ivy.request().getRootRequest().getRequestPath(), DASHBOARD_PAGE_URL) + && !isMainDashboardMenu) { + dashboardGroupMenu.setExpanded(true); + } + } + + private MenuElement buildSingleDashboardMenu(String dashboardTitle, String dashboardId, String dashboardLink) { var dashboardMenu = new PortalMenuBuilder(dashboardTitle, MenuKind.DASHBOARD, this.isWorkingOnATask) - .icon(PortalMenuItem.DEFAULT_DASHBOARD_ICON) - .url(dashboardLink) - .workingTaskId(this.workingTaskId).build(); + .icon(PortalMenuItem.DEFAULT_DASHBOARD_ICON).url(dashboardLink).workingTaskId(this.workingTaskId).build(); + if (StringUtils.isBlank(dashboardId)) { dashboardId = dashboardMenu.getId(); } - dashboardMenu.setId(String.format(DASHBOARD_MENU_PATTERN, dashboardId)); + dashboardMenu.setId(String.format(PARENT_DASHBOARD_MENU_PATTERN, dashboardId)); + return dashboardMenu; } + public PortalDashboardItemWrapper getDashboardCache() { String sessionUserId = getSessionUserId(); IvyCacheService cacheService = IvyCacheService.getInstance(); @@ -226,10 +276,12 @@ public void updateDashboardCache(List dashboards) { String sessionUserId = getSessionUserId(); IvyCacheService cacheService = IvyCacheService.getInstance(); - synchronized(PortalDashboardItemWrapper.class) { + synchronized (PortalDashboardItemWrapper.class) { cacheService.setSessionCache(IvyCacheIdentifier.PORTAL_DASHBOARDS, sessionUserId, new PortalDashboardItemWrapper(dashboards)); } + + cacheService.invalidateSessionEntry(IvyCacheIdentifier.PORTAL_MENU, sessionUserId); } private String getSessionUserId() { @@ -267,8 +319,6 @@ public void loadBreadcrumb(String viewName, ITask userTask, ICase userCase) { } BreadCrumbKind breadCrumbKind = BreadCrumbKind.valueOf(viewName); switch (breadCrumbKind) { - case TASK -> buildBreadCrumbForTaskList(); - case CASE -> buildBreadCrumbForCaseList(); case TECHNICAL_CASE -> buildBreadCrumbForTechnicalCaseList(userCase); case RELATED_TASK -> buildBreadCrumbForRelatedTask(userCase); case PROCESS -> buildBreadCrumbForProcess(); @@ -312,21 +362,6 @@ private void buildBreadCrumbForAbsences() { breadcrumbModel.getElements().add(buildGenericMenuItem("/ch.ivy.addon.portalkit.ui.jsf/AbsenceManagement/absenceAndDeputy")); } - private void buildBreadCrumbForTaskList() { - setPortalHomeMenuToBreadcrumbModel(); - DefaultMenuItem taskListSubmenuItem = buildTaskListMenuItem(); - taskListSubmenuItem.setDisabled(true); - breadcrumbModel.getElements().add(taskListSubmenuItem); - } - - private void buildBreadCrumbForCaseList() { - setPortalHomeMenuToBreadcrumbModel(); - - DefaultMenuItem caseListSubmenuItem = buildCaseListMenuItem(); - caseListSubmenuItem.setDisabled(true); - breadcrumbModel.getElements().add(caseListSubmenuItem); - } - private void buildBreadCrumbForTechnicalCaseList(ICase userCase) { setPortalHomeMenuToBreadcrumbModel(); DefaultMenuItem caseListSubmenuItem = buildCaseListMenuItem(); @@ -384,30 +419,25 @@ private MenuItem buildPortalHomeMenuItem() { .build(); } - private DefaultMenuItem buildMenuItemFromPortalSubMenuItem(SubMenuItem subMenuItem) { - return DefaultMenuItem.builder() - .value(subMenuItem.getLabel()) - .url(null) - .build(); + private DefaultMenuItem buildMenuItemFromPortalSubMenuItem(String cmsOfMenuItemLabel) { + return DefaultMenuItem.builder().value(ApplicationMultiLanguageAPI.getCmsValueByUserLocale(cmsOfMenuItemLabel)) + .url(null).build(); } private DefaultMenuItem buildTaskListMenuItem() { - TaskSubMenuItem taskSubMenuItem = new TaskSubMenuItem(); - DefaultMenuItem taskMenu = buildMenuItemFromPortalSubMenuItem(taskSubMenuItem); + DefaultMenuItem taskMenu = buildMenuItemFromPortalSubMenuItem("/ch.ivy.addon.portalkit.ui.jsf/common/tasks"); taskMenu.setOnclick("navigateToTaskList();"); return taskMenu; } private DefaultMenuItem buildCaseListMenuItem() { - CaseSubMenuItem caseSubMenuItem = new CaseSubMenuItem(); - DefaultMenuItem caseMenuItem = buildMenuItemFromPortalSubMenuItem(caseSubMenuItem); + DefaultMenuItem caseMenuItem = buildMenuItemFromPortalSubMenuItem("/ch.ivy.addon.portalkit.ui.jsf/caseList/cases"); caseMenuItem.setOnclick("navigateToCaseList();"); return caseMenuItem; } private DefaultMenuItem buildProcessListMenuItem() { - ProcessSubMenuItem processSubMenuItem = new ProcessSubMenuItem(); - return buildMenuItemFromPortalSubMenuItem(processSubMenuItem); + return buildMenuItemFromPortalSubMenuItem("/ch.ivy.addon.portalkit.ui.jsf/common/processes"); } private MenuItem buildTaskDetailsMenuItem(ITask userTask) { @@ -450,7 +480,6 @@ public void storeSelectedMenuItems() { var isOpenOnNewTab = Optional.ofNullable(requestParamMap.get(IS_OPEN_NEW_TAB)).map(BooleanUtils::toBoolean).orElse(false); session().setAttribute(SELECTED_MENU_ID, selectedMenuItemId); DashboardUtils.updateSelectedDashboardToSession(selectedMenuItemId); - if (!isWorkingOnATask && !isOpenOnNewTab) { session().setAttribute(PREV_SELECTED_MENU_ID, selectedMenuItemId); } @@ -462,6 +491,7 @@ public void storeSelectedMenuItems() { } PrimeFaces.current().executeScript(String.format(CLICK_ON_MENU_ITEM_PATTERN, prevSelectedMenuItemId, session().getAttribute(SELECTED_MENU_ID))); + } } @@ -488,8 +518,9 @@ private IWorkflowSession session() { return Ivy.session(); } - private record PortalDashboardItemWrapper(List dashboards) {} - + public record PortalDashboardItemWrapper(List dashboards) { + } + private void buildBreadCrumbForNotification() { setPortalHomeMenuToBreadcrumbModel(); breadcrumbModel.getElements().add(buildGenericMenuItem("/ch.ivy.addon.portalkit.ui.jsf/notifications/notificationTitle")); diff --git a/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/PortalMenuItem.java b/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/PortalMenuItem.java index c9ecce281e4..9e3bac9337c 100644 --- a/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/PortalMenuItem.java +++ b/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/PortalMenuItem.java @@ -1,14 +1,18 @@ package ch.addon.portal.generic.menu; +import static ch.ivy.addon.portal.generic.navigation.PortalNavigator.DASHBOARD_ID; import static java.util.Objects.isNull; import static org.apache.commons.lang3.StringUtils.EMPTY; +import java.net.URI; +import java.net.URISyntaxException; import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.primefaces.model.menu.DefaultMenuItem; import ch.ivy.addon.portalkit.enums.MenuKind; +import ch.ivy.addon.portalkit.util.DashboardUtils; import ch.ivyteam.ivy.environment.Ivy; public class PortalMenuItem extends DefaultMenuItem { @@ -25,6 +29,7 @@ public class PortalMenuItem extends DefaultMenuItem { public final static String SUB_MENU_ID_FORMAT = "sub-menu-item-%s"; public final static String THIRD_PARTY_MENU_ID_FORMAT = "thirdparty-menu-item-%s"; public final static String EXTERNAL_MENU_ID_FORMAT = "external-menu-item-%s"; + public final static String MAIN_DASHBOARD_MENU_ID_FORMAT = "main-dashboard-menu-item-%s"; public final static String MENU_CLASS_FORMAT = "%s %s"; public final static String MENU_CLASS_SUFFIX = "-menu-js"; @@ -45,7 +50,29 @@ public class PortalMenuItem extends DefaultMenuItem { public PortalMenuItem() { } public PortalMenuItem(PortalMenuBuilder builder) { - this.setId(String.format(MENU_ITEM_ID_FORMAT, builder.menuKind.toString(), builder.menuIndex)); + if (MenuKind.MAIN_DASHBOARD == builder.menuKind) { + try { + String dashboardId = ""; + URI uri = new URI(builder.url); + String query = uri.getQuery(); + String[] pairs = query.split("&"); + + for (String pair : pairs) { + String[] keyValue = pair.split("="); + if (DASHBOARD_ID.equals(keyValue[0])) { + dashboardId = keyValue.length > 1 ? keyValue[1] : ""; + break; + } + } + this.setId(String.format(DashboardUtils.MAIN_DASHBOARD_MENU_PATTERN, dashboardId)); + + } catch (URISyntaxException e) { + // Just ignore + } + } + if (StringUtils.isEmpty(this.getId())) { + this.setId(String.format(MENU_ITEM_ID_FORMAT, builder.menuKind.toString(), builder.menuIndex)); + } this.setValue(builder.name); this.setIcon(builder.icon); this.setIconPos(DEFAULT_ICON_POSITION); @@ -107,11 +134,11 @@ private String generateMenuId(MenuKind menuKind) { menuFormat = MENU_ID_FORMAT; break; case PROCESS: - case TASK: - case CASE: case CUSTOM: menuFormat = SUB_MENU_ID_FORMAT; break; + case MAIN_DASHBOARD: + menuFormat = MAIN_DASHBOARD_MENU_ID_FORMAT; case EXTERNAL_LINK: menuFormat = EXTERNAL_MENU_ID_FORMAT; break; diff --git a/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/PortalMenuNavigator.java b/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/PortalMenuNavigator.java index cbc352d7266..f627e684967 100644 --- a/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/PortalMenuNavigator.java +++ b/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/PortalMenuNavigator.java @@ -1,5 +1,7 @@ package ch.addon.portal.generic.menu; +import static ch.ivy.addon.portalkit.util.DashboardUtils.DEFAULT_CASE_LIST_DASHBOARD; +import static ch.ivy.addon.portalkit.util.DashboardUtils.DEFAULT_TASK_LIST_DASHBOARD; import static java.util.Objects.isNull; import static org.apache.commons.lang3.StringUtils.EMPTY; @@ -15,24 +17,31 @@ import javax.faces.event.ActionEvent; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; import org.primefaces.event.MenuActionEvent; import org.primefaces.model.menu.MenuItem; import com.axonivy.portal.components.publicapi.PortalNavigatorAPI; import com.axonivy.portal.service.CustomSubMenuItemService; +import ch.addon.portal.generic.userprofile.homepage.HomepageUtils; import ch.ivy.addon.portal.generic.navigation.PortalNavigator; import ch.ivy.addon.portalkit.comparator.ApplicationIndexAscendingComparator; import ch.ivy.addon.portalkit.configuration.Application; import ch.ivy.addon.portalkit.constant.IvyCacheIdentifier; +import ch.ivy.addon.portalkit.dto.DisplayName; +import ch.ivy.addon.portalkit.dto.dashboard.Dashboard; import ch.ivy.addon.portalkit.enums.BreadCrumbKind; import ch.ivy.addon.portalkit.enums.MenuKind; import ch.ivy.addon.portalkit.enums.SessionAttribute; import ch.ivy.addon.portalkit.service.IvyCacheService; import ch.ivy.addon.portalkit.service.RegisteredApplicationService; +import ch.ivy.addon.portalkit.util.DashboardUtils; import ch.ivy.addon.portalkit.util.PermissionUtils; import ch.ivy.addon.portalkit.util.PrimeFacesUtils; 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.workflow.ITask; import ch.ivyteam.ivy.workflow.TaskState; @@ -49,6 +58,7 @@ public static void navigateToTargetPage(Map> params) throws switch (selectedMenuKind) { case DASHBOARD: + case MAIN_DASHBOARD: case CUSTOM: case EXTERNAL_LINK: redirectToSelectedMenuUrl(params); @@ -56,12 +66,6 @@ public static void navigateToTargetPage(Map> params) throws case PROCESS: PortalNavigator.navigateToPortalProcess(); break; - case TASK: - PortalNavigator.navigateToPortalTask(); - break; - case CASE: - PortalNavigator.navigateToPortalCase(); - break; default: break; } @@ -122,9 +126,8 @@ public static List callSubMenuItemsProcess() { cacheService.invalidateSessionEntry(IvyCacheIdentifier.PORTAL_MENU, sessionUserId); } - if (portalSubMenuItemWrapper == null - || !requestLocale.equals(portalSubMenuItemWrapper.loadedLocale)) { - synchronized(PortalSubMenuItemWrapper.class) { + if (portalSubMenuItemWrapper == null || !requestLocale.equals(portalSubMenuItemWrapper.loadedLocale)) { + synchronized (PortalSubMenuItemWrapper.class) { List subMenuItems = new ArrayList<>(); try { subMenuItems = getSubmenuList(); @@ -139,38 +142,79 @@ public static List callSubMenuItemsProcess() { return portalSubMenuItemWrapper.portalSubMenuItems; } - public static void navigateToTargetPage(boolean isClickOnBreadcrumb, String destinationPage, Map> params) throws IOException { + public static void navigateToTargetPage(boolean isClickOnBreadcrumb, String destinationPage, + Map> params) throws IOException { if (isClickOnBreadcrumb) { if (BreadCrumbKind.TASK.name().equals(destinationPage)) { PortalNavigator.navigateToPortalTask(); - } - else if (BreadCrumbKind.HOME.name().equals(destinationPage)) { + } else if (BreadCrumbKind.HOME.name().equals(destinationPage)) { PortalNavigatorAPI.navigateToPortalHome(); - } - else { + } else { redirectToSelectedMenuUrl(params); } } navigateToTargetPage(params); } - private record PortalSubMenuItemWrapper(Locale loadedLocale, List portalSubMenuItems) {} + + private record PortalSubMenuItemWrapper(Locale loadedLocale, List portalSubMenuItems) { + } private static List getSubmenuList() { + String currentLanguage = UserUtils.getUserLanguage(); List subMenuItems = new ArrayList<>(); - if(PermissionUtils.checkAccessFullProcessListPermission()) { - subMenuItems.add(new ProcessSubMenuItem()); + addProcessSubmenuItems(subMenuItems); + + List mainDashboards = DashboardUtils.collectMainDashboards(); + for (Dashboard dashboard : mainDashboards) { + if (isDefaultTaskCaseListDashboardButNoAccessPermission(dashboard)) { + continue; + } + subMenuItems.add(convertDashboardToSubMenuItem(dashboard, currentLanguage)); } - if(PermissionUtils.checkAccessFullTaskListPermission()) { - subMenuItems.add(new TaskSubMenuItem()); + subMenuItems.addAll(CustomSubMenuItemService.findAll()); + + return subMenuItems; + } + + private static boolean isDefaultTaskCaseListDashboardButNoAccessPermission(Dashboard dashboard) { + return (DEFAULT_TASK_LIST_DASHBOARD.equals(dashboard.getId()) + && !PermissionUtils.checkAccessFullTaskListPermission()) + || (DEFAULT_CASE_LIST_DASHBOARD.equals(dashboard.getId()) + && !PermissionUtils.checkAccessFullCaseListPermission()); + } + + private static void addProcessSubmenuItems(List subMenuItems) { + if (PermissionUtils.checkAccessFullProcessListPermission()) { + subMenuItems.add(new ProcessSubMenuItem()); } + } + + private static SubMenuItem convertDashboardToSubMenuItem(Dashboard dashboard, String currentLanguage) { + SubMenuItem item = new SubMenuItem(); + String defaultTitle = dashboard.getTitle(); - if(PermissionUtils.checkAccessFullCaseListPermission()) { - subMenuItems.add(new CaseSubMenuItem()); + // Set default icon if it's blank + if (StringUtils.isBlank(dashboard.getIcon())) { + dashboard.setIcon(dashboard.getIsPublic() ? "si-network-share" : "si-single-neutral-shield"); } - subMenuItems.addAll(CustomSubMenuItemService.findAll()); - return subMenuItems; + // Set icon with the appropriate prefix + item.icon = (dashboard.getIcon().startsWith("fa") ? "fa " : "si ") + dashboard.getIcon(); + + // Set the name of the submenu item based on the current language or use default title + item.label = dashboard.getTitles().stream() + .filter(name -> StringUtils.equalsIgnoreCase(name.getLocale().toString(), currentLanguage) + && StringUtils.isNotBlank(name.getValue())) + .map(DisplayName::getValue).findFirst().orElse(defaultTitle); + + // Set other properties + item.menuKind = MenuKind.MAIN_DASHBOARD; + item.name = HomepageUtils.generateHomepageId(MenuKind.MAIN_DASHBOARD, dashboard.getId()); + item.link = UrlUtils.getServerUrl() + PortalNavigator.getDashboardPageUrl(dashboard.getId()); + + return item; } -} \ No newline at end of file + +} diff --git a/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/TaskSubMenuItem.java b/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/TaskSubMenuItem.java deleted file mode 100644 index 287562faf91..00000000000 --- a/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/TaskSubMenuItem.java +++ /dev/null @@ -1,17 +0,0 @@ -package ch.addon.portal.generic.menu; - -import com.axonivy.portal.components.publicapi.ApplicationMultiLanguageAPI; - -import ch.addon.portal.generic.userprofile.homepage.HomepageType; -import ch.ivy.addon.portal.generic.navigation.PortalNavigator; -import ch.ivy.addon.portalkit.enums.MenuKind; - -public class TaskSubMenuItem extends SubMenuItem { - public TaskSubMenuItem() { - this.icon = "si si-task-list-edit"; - this.menuKind = MenuKind.TASK; - this.label = ApplicationMultiLanguageAPI.getCmsValueByUserLocale("/ch.ivy.addon.portalkit.ui.jsf/common/tasks"); - this.name = HomepageType.TASK.name(); - this.link = PortalNavigator.getSubMenuItemUrlOfCurrentApplication(MenuKind.TASK); - } -} diff --git a/AxonIvyPortal/portal/src/ch/addon/portal/generic/userprofile/homepage/HomepageMapper.java b/AxonIvyPortal/portal/src/ch/addon/portal/generic/userprofile/homepage/HomepageMapper.java index 07a8c049dbf..c73bc56cf18 100644 --- a/AxonIvyPortal/portal/src/ch/addon/portal/generic/userprofile/homepage/HomepageMapper.java +++ b/AxonIvyPortal/portal/src/ch/addon/portal/generic/userprofile/homepage/HomepageMapper.java @@ -11,7 +11,7 @@ public class HomepageMapper { public static List toHomepages(List menuItems) { return menuItems.stream().map(HomepageMapper::toHomepage).collect(Collectors.toList()); } - + public static Homepage toHomepage(SubMenuItem menuItem) { Homepage homepage = new Homepage(); homepage.setName(menuItem.getName()); @@ -19,10 +19,8 @@ public static Homepage toHomepage(SubMenuItem menuItem) { homepage.setLink(menuItem.buildLink()); if (menuItem.getMenuKind() == MenuKind.PROCESS) { homepage.setType(HomepageType.PROCESS); - } else if (menuItem.getMenuKind() == MenuKind.TASK) { - homepage.setType(HomepageType.TASK); - } else if (menuItem.getMenuKind() == MenuKind.CASE) { - homepage.setType(HomepageType.CASE); + } else if (menuItem.getMenuKind() == MenuKind.MAIN_DASHBOARD) { + homepage.setType(HomepageType.MAIN_DASHBOARD); } else if (menuItem.getMenuKind() == MenuKind.CUSTOM) { homepage.setType(HomepageType.CUSTOM); } else { diff --git a/AxonIvyPortal/portal/src/ch/addon/portal/generic/userprofile/homepage/HomepageType.java b/AxonIvyPortal/portal/src/ch/addon/portal/generic/userprofile/homepage/HomepageType.java index 1daa0efa627..d1af2ea38dc 100644 --- a/AxonIvyPortal/portal/src/ch/addon/portal/generic/userprofile/homepage/HomepageType.java +++ b/AxonIvyPortal/portal/src/ch/addon/portal/generic/userprofile/homepage/HomepageType.java @@ -1,7 +1,7 @@ package ch.addon.portal.generic.userprofile.homepage; public enum HomepageType { - DASHBOARD, PROCESS, TASK, CASE, CUSTOM; + DASHBOARD, PROCESS, CUSTOM, MAIN_DASHBOARD; public static HomepageType getType(String typeName) { for (HomepageType type : HomepageType.values()) { diff --git a/AxonIvyPortal/portal/src/ch/addon/portal/generic/userprofile/homepage/HomepageUtils.java b/AxonIvyPortal/portal/src/ch/addon/portal/generic/userprofile/homepage/HomepageUtils.java index a0e09fa30ed..3aca3bf45ef 100644 --- a/AxonIvyPortal/portal/src/ch/addon/portal/generic/userprofile/homepage/HomepageUtils.java +++ b/AxonIvyPortal/portal/src/ch/addon/portal/generic/userprofile/homepage/HomepageUtils.java @@ -1,5 +1,8 @@ package ch.addon.portal.generic.userprofile.homepage; +import static ch.ivy.addon.portalkit.util.DashboardUtils.DEFAULT_CASE_LIST_DASHBOARD; +import static ch.ivy.addon.portalkit.util.DashboardUtils.DEFAULT_TASK_LIST_DASHBOARD; + import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.List; @@ -24,10 +27,12 @@ public class HomepageUtils { + public static final String HOMEPAGE_ID_PATTERN = "%s_%s"; + public static List loadHomepages() { List homepages = new ArrayList<>(); List subMenuItems = PortalMenuNavigator.callSubMenuItemsProcess(); - homepages.add(initDashboard()); + homepages.add(defaultHompage()); for (SubMenuItem item : subMenuItems) { if (item.getMenuKind() != MenuKind.EXTERNAL_LINK) { homepages.add(HomepageMapper.toHomepage(item)); @@ -36,7 +41,7 @@ public static List loadHomepages() { return homepages; } - private static Homepage initDashboard() { + private static Homepage defaultHompage() { Homepage dashboard = new Homepage(); dashboard.setName(HomepageType.DASHBOARD.name()); dashboard.setLabel(Ivy.cms().co("/ch.ivy.addon.portalkit.ui.jsf/common/dashboard")); @@ -50,26 +55,54 @@ private static String findRelativeUrlByKeywork(String keyword) { String newDashboardLink = ProcessStartAPI.findRelativeUrlByProcessStartFriendlyRequestPath(friendlyRequestPath); return newDashboardLink; } - + public static Homepage findHomepageInMyProfile() { Homepage homepage = new Homepage(); - String homepageName = Ivy.session().getSessionUser().getProperty(UserProperty.HOMEPAGE); + String homepageName = getHomepageId(); if (StringUtils.isBlank(homepageName)) { homepage.setName(StringUtils.EMPTY); return homepage; } - + List homepages = loadHomepages(); homepage.setName(homepageName); - return homepages.get(homepages.indexOf(homepage)); + int index = homepages.indexOf(homepage); + if (index == -1) { + index = 0; + } + return homepages.get(index); + } + + public static String generateHomepageId(MenuKind menuKind, String dashboardId) { + return String.format(HOMEPAGE_ID_PATTERN, menuKind.name(), dashboardId); + } + + public static String generateDefaultCaseListDashboardHomepageId() { + return generateHomepageId(MenuKind.MAIN_DASHBOARD, DEFAULT_CASE_LIST_DASHBOARD); + } + + public static String generateDefaultTaskListDashboardHomepageId() { + return generateHomepageId(MenuKind.MAIN_DASHBOARD, DEFAULT_TASK_LIST_DASHBOARD); + } + + private static String getHomepageId() { + String originHomepage = Ivy.session().getSessionUser().getProperty(UserProperty.HOMEPAGE); + if ("TASK".equals(originHomepage)) { // for backward compatible + return generateDefaultTaskListDashboardHomepageId(); + } else if ("CASE".equals(originHomepage)) { // for backward compatible + return generateDefaultCaseListDashboardHomepageId(); + } + return originHomepage; } public static Homepage findHomepage() { List homepages = loadHomepages(); - Boolean isPortalInTeams = (Boolean) SecurityServiceUtils.getSessionAttribute(SessionAttribute.PORTAL_IN_TEAMS.toString()); + Boolean isPortalInTeams = + (Boolean) SecurityServiceUtils.getSessionAttribute(SessionAttribute.PORTAL_IN_TEAMS.toString()); Homepage homepage = new Homepage(); if (BooleanUtils.isTrue(isPortalInTeams)) { - String homePageName = SecurityServiceUtils.getSessionAttribute(SessionAttribute.DEFAULT_PAGE_IN_TEAMS.toString()).toString(); + String homePageName = + SecurityServiceUtils.getSessionAttribute(SessionAttribute.DEFAULT_PAGE_IN_TEAMS.toString()).toString(); homepage.setName(homePageName); } else { homepage.setName(getHomepageName()); @@ -79,15 +112,13 @@ public static Homepage findHomepage() { adjustHomepageStartLink(seletedHomepage); return seletedHomepage; } else { - return homepage; + return defaultHompage(); } } private static void adjustHomepageStartLink(Homepage homepage) { String relativeUrl = switch (homepage.getType()) { case PROCESS -> findRelativeUrlByKeywork(PortalNavigator.PORTAL_PROCESS_START); - case TASK -> findRelativeUrlByKeywork(PortalNavigator.PORTAL_TASK_START); - case CASE -> findRelativeUrlByKeywork(PortalNavigator.PORTAL_CASE_START); default -> ""; }; if (StringUtils.isNotEmpty(relativeUrl)) { @@ -96,24 +127,28 @@ private static void adjustHomepageStartLink(Homepage homepage) { } public static String getHomepageName() { - String homepageName = Ivy.session().getSessionUser().getProperty(UserProperty.HOMEPAGE); + String homepageName = getHomepageId(); if (StringUtils.isBlank(homepageName)) { homepageName = findHomepageSetting(); } return homepageName; } - + public static Homepage findDefaultHomepage() { List homepages = loadHomepages(); Homepage homepage = new Homepage(); homepage.setName(findHomepageSetting()); - return homepages.get(homepages.indexOf(homepage)); + int index = homepages.indexOf(homepage); + if (index == -1) { + index = 0; + } + return homepages.get(index); } private static String findHomepageSetting() { return GlobalSettingService.getInstance().findGlobalSettingValue(GlobalVariable.DEFAULT_HOMEPAGE); } - + public static Map getHomepageOptionsForAdminSettings() { Map result = new LinkedHashMap<>(); for (Homepage homepage : HomepageUtils.loadHomepages()) { @@ -121,7 +156,7 @@ public static Map getHomepageOptionsForAdminSettings() { } return result; } - + public static boolean isShowDashboard(Homepage homepage, boolean isClickOnDashboard) { return homepage == null || homepage.getType() == HomepageType.DASHBOARD || isClickOnDashboard; } 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 dcfff0cca55..736734afaa4 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,8 +13,11 @@ import com.axonivy.portal.components.service.IvyAdapterService; import ch.ivy.addon.portalkit.enums.GlobalVariable; +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 @@ -23,6 +27,7 @@ public class ChatRendererBean implements Serializable { private Boolean isGroupChatRendered; private Boolean isPrivateChatRendered; + private IProcessStart assistantDashboardProcess; public boolean getIsChatRendered() { return getIsGroupChatRendered() || getIsPrivateChatRendered(); @@ -55,4 +60,15 @@ public void getGroupChatName() { String groupChatName = Ivy.cms().co("/ch.ivy.addon.portalkit.ui.jsf/common/case") + "-{caseId}" + " {caseName}"; PrimeFaces.current().executeScript("var groupChatFormat = '" + groupChatName + "'"); } + + 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 47d53fddeff..b573ec9dde1 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,13 @@ package ch.ivy.addon.portal.generic.bean; +import static ch.ivy.addon.portalkit.enums.SessionAttribute.SELECTED_DASHBOARD_ID; +import static ch.ivy.addon.portalkit.enums.SessionAttribute.SELECTED_SUB_DASHBOARD_ID; + 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 java.util.Optional; import javax.annotation.PostConstruct; import javax.faces.bean.ManagedBean; @@ -40,7 +41,6 @@ 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; @@ -66,6 +66,7 @@ public class DashboardBean implements Serializable { private static final long serialVersionUID = -4224901891867040688L; + private static final String ACCESSIBILITY_DASHBOARD_TEMPLATE_ID = "accessibility-dashboard-template"; protected List dashboards; protected Dashboard selectedDashboard; @@ -90,24 +91,28 @@ public void init() { currentDashboardIndex = 0; dashboards = collectDashboards(); + if (isReadOnlyMode) { MenuView menuView = (MenuView) ManagedBeans.get("menuView"); menuView.updateDashboardCache(dashboards); } - if (CollectionUtils.isNotEmpty(dashboards)) { - selectedDashboardId = readDashboardFromSession(); + if (CollectionUtils.isNotEmpty(DashboardUtils.getDashboardsWithoutMenuItem())) { + updateSelectedDashboardIdFromSessionAttribute(); currentDashboardIndex = findIndexOfDashboardById(selectedDashboardId); selectedDashboard = dashboards.get(currentDashboardIndex); + String selectedDashboardName = selectedDashboard.getTitles().stream() - .filter(displayName -> displayName.getLocale().equals(Ivy.session().getContentLocale())).findFirst() + .filter(displayName -> displayName.getLocale().equals(Ivy.session().getContentLocale())) + .findFirst() .orElseGet(() -> selectedDashboard.getTitles().get(0)).getValue(); setSelectedDashboardName(selectedDashboardName); initShareDashboardLink(selectedDashboard); // can not find dashboard by dashboard id session in view mode if (StringUtils.isBlank(selectedDashboardId) - || (!selectedDashboardId.equalsIgnoreCase(selectedDashboard.getId()) && dashboards.size() > 1)) { - storeDashboardInSession(selectedDashboard.getId()); + || (!selectedDashboardId.equalsIgnoreCase(selectedDashboard.getId()) + && DashboardUtils.getDashboardsWithoutMenuItem().size() > 1)) { + DashboardUtils.storeDashboardInSession(selectedDashboard.getId()); } if (isReadOnlyMode) { DashboardUtils.highlightDashboardMenuItem(selectedDashboard.getId()); @@ -198,7 +203,13 @@ private void handleSelectedTask(ITask task) throws IOException { public void handleStartTask(ITask task) throws IOException { selectedTask = task; - TaskUtils.handleStartTask(task, PortalPage.HOME_PAGE, PortalConstants.RESET_TASK_CONFIRMATION_DIALOG); + if (selectedDashboard.getIsTopMenu()) { + TaskUtils.handleStartTask(task, PortalPage.HOME_PAGE, PortalConstants.RESET_TASK_CONFIRMATION_DIALOG, + selectedDashboardId); + } else { + TaskUtils.handleStartTask(task, PortalPage.HOME_PAGE, PortalConstants.RESET_TASK_CONFIRMATION_DIALOG); + } + } public void navigateToSelectedTaskDetails(ITask task) { @@ -229,7 +240,7 @@ public String createExtractedTextFromHtml(String text) { return HtmlParser.extractTextFromHtml(text); } - public String createParseTextFromHtml (String text) { + public String createParseTextFromHtml(String text) { return HtmlUtils.parseTextFromHtml(text); } @@ -327,7 +338,7 @@ public void onClickSavedFilterItem(WidgetFilterModel filter, DashboardWidget wid caseWidget.setUserFilters(savedFilters); return; } - + if (widget.getType() == DashboardWidgetType.TASK) { TaskDashboardWidget taskWidget = ((TaskDashboardWidget) widget); @@ -396,26 +407,20 @@ public void setDashboardTemplates(List dashboardTemplates) { this.dashboardTemplates = dashboardTemplates; } - private String readDashboardFromSession() { - return (String) Ivy.session().getAttribute(SessionAttribute.SELECTED_DASHBOARD_ID.toString()); - } + private int findIndexOfDashboardById(String selectedDashboardId) { - private void storeDashboardInSession(String id) { - Ivy.session().setAttribute(SessionAttribute.SELECTED_DASHBOARD_ID.toString(), id); - } - private int findIndexOfDashboardById(String selectedDashboardId) { - int currentDashboardIndex = 0; - if(StringUtils.isNotBlank(selectedDashboardId)) { - currentDashboardIndex = dashboards.indexOf(dashboards.stream() - .filter(dashboard -> dashboard.getId().contentEquals(selectedDashboardId)).findFirst().orElse(null)); - if(currentDashboardIndex == -1) { - currentDashboardIndex = 0; - } + if (StringUtils.isNotBlank(selectedDashboardId)) { + return dashboards.stream().filter(dashboard -> dashboard.getId().contentEquals(selectedDashboardId)).findFirst() + .map(dashboards::indexOf).orElse(dashboards.stream().filter(dashboard -> !dashboard.getIsTopMenu()) + .findFirst().map(dashboards::indexOf).orElse(0)); } - return currentDashboardIndex; + + return dashboards.stream().filter(dashboard -> !dashboard.getIsTopMenu()).findFirst().map(dashboards::indexOf) + .orElse(0); } + public int getMaxRowNumberInExcel() { return Exporter.MAX_ROW_NUMBER_IN_EXCEL; } @@ -452,6 +457,7 @@ public boolean isRequiredField(DisplayName displayName) { public String getWarningText() { return warningText; } + public String getDashboardUrl() { return dashboardUrl; } @@ -483,21 +489,21 @@ public String getClientStatisticApiUri() { public boolean canEnableQuickSearch(DashboardWidget widget) { return widget.getType().canEnableQuickSearch(); } - + public boolean canShowWidgetInfoIcon(DashboardWidget widget) { return widget.getType().canShowWidgetInfoOption(); } - + public boolean canShowExpandMode(DashboardWidget widget) { return widget.getType().canShowFullscreenModeOption(); } - + public void setSelectedDashboardName(String dashboardName) { this.selectedDashboardName = dashboardName; } - + public String getSelectedDashboardName() { - if (selectedDashboardName.isBlank()) { + if (StringUtils.isBlank(selectedDashboardName)) { return Ivy.cms().co("/ch.ivy.addon.portalkit.ui.jsf/common/dashboard"); } return selectedDashboardName; @@ -506,4 +512,29 @@ public String getSelectedDashboardName() { public boolean isHideCaseCreator() { return GlobalSettingService.getInstance().isHideCaseCreator(); } + + public String getScreenReaderNotificationContent() { + String templateId = Optional.ofNullable(this.selectedDashboard) + .map(Dashboard::getTemplateId).orElse(StringUtils.EMPTY); + + if (StringUtils.isNotBlank(templateId) + && ACCESSIBILITY_DASHBOARD_TEMPLATE_ID.equals(templateId)) { + return Ivy.cms().co("/Dialogs/com/axonivy/portal/dashboard/component/AccessibilityShortcuts/title"); + } + return StringUtils.EMPTY; + } + + public boolean isMainDashboardSelected() { + return DashboardUtils.isMainDashboard(selectedDashboardId, true); + } + + + private void updateSelectedDashboardIdFromSessionAttribute() { + if (Ivy.request().getRequestPath().endsWith("/PortalMainDashboard.xhtml")) { + selectedDashboardId = (String) Ivy.session().getAttribute(SELECTED_DASHBOARD_ID.name()); + } else { + selectedDashboardId = (String) Ivy.session().getAttribute(SELECTED_SUB_DASHBOARD_ID.name()); + } + } + } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/DashboardCaseWidgetBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/DashboardCaseWidgetBean.java new file mode 100644 index 00000000000..5d29f326499 --- /dev/null +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/DashboardCaseWidgetBean.java @@ -0,0 +1,46 @@ +package ch.ivy.addon.portal.generic.bean; + +import java.io.Serializable; +import java.util.List; +import java.util.Random; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.faces.bean.ManagedBean; +import javax.faces.bean.ViewScoped; + +import org.primefaces.event.SelectEvent; + +import ch.ivy.addon.portal.generic.navigation.PortalNavigator; +import ch.ivy.addon.portalkit.enums.CaseEmptyMessage; +import ch.ivy.addon.portalkit.support.HtmlParser; +import ch.ivyteam.ivy.workflow.ICase; + +@ViewScoped +@ManagedBean +public class DashboardCaseWidgetBean implements Serializable { + + private static final long serialVersionUID = 4733478835925712413L; + + private CaseEmptyMessage noCasesMessage; + + public void navigateToSelectedCaseDetails(SelectEvent event) { + String uuid = ((ICase) event.getObject()).uuid(); + PortalNavigator.navigateToPortalCaseDetails(uuid); + } + + public CaseEmptyMessage getNoCasesMessage() { + if (noCasesMessage == null) { + List messages = Stream.of(CaseEmptyMessage.values()) + .collect(Collectors.toList()); + Random random = new Random(); + int index = random.ints(0, messages.size()).findFirst().getAsInt(); + noCasesMessage = messages.get(index); + } + return noCasesMessage; + } + + public String createExtractedTextFromHtml(String text) { + return HtmlParser.extractTextFromHtml(text); + } +} diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/DashboardDetailModificationBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/DashboardDetailModificationBean.java index 3c0483041ba..5727ffb6499 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/DashboardDetailModificationBean.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/DashboardDetailModificationBean.java @@ -9,6 +9,8 @@ import static ch.ivy.addon.portalkit.enums.DashboardWidgetType.PROCESS_VIEWER; import static ch.ivy.addon.portalkit.enums.DashboardWidgetType.TASK; import static ch.ivy.addon.portalkit.enums.DashboardWidgetType.WELCOME; +import static ch.ivy.addon.portalkit.util.DashboardUtils.DEFAULT_CASE_LIST_DASHBOARD; +import static ch.ivy.addon.portalkit.util.DashboardUtils.DEFAULT_TASK_LIST_DASHBOARD; import static org.apache.commons.lang3.StringUtils.EMPTY; import java.beans.PropertyChangeEvent; @@ -35,8 +37,10 @@ import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; import org.apache.logging.log4j.util.Strings; import org.primefaces.PrimeFaces; +import org.primefaces.event.ColumnResizeEvent; import com.axonivy.portal.bo.ClientStatistic; import com.axonivy.portal.components.dto.UserDTO; @@ -176,9 +180,9 @@ protected List collectDashboards() { collectedDashboards = getVisibleDashboards(dashboardInUserProperty); } } catch (PortalException e) { - // If errors like parsing JSON errors, ignore them Ivy.log().error(e); } + DashboardUtils.addDefaultTaskCaseListDashboardsIfMissing(collectedDashboards); return collectedDashboards.stream() .filter(dashboard -> dashboard.getId().equals(selectedDashboardId)).collect(Collectors.toList()); } @@ -503,7 +507,7 @@ public void onCancel(DashboardWidget widget) { } } - public void onReset(DashboardWidget widget) { + public void onReset(@SuppressWarnings("unused") DashboardWidget widget) { resetUserFilter(); } @@ -671,12 +675,26 @@ protected void saveSelectedDashboard() { DashboardWidgetUtils.simplifyWidgetColumnData(widget); }); - DashboardService.getInstance().save(selectedDashboard); + saveDashboardsWithHandlingDefaultDashboards(); selectedDashboard.getWidgets().forEach(widget -> { DashboardWidgetUtils.buildWidgetColumns(widget); }); } + private Dashboard saveDashboardsWithHandlingDefaultDashboards() { + DashboardService dashboardService = DashboardService.getInstance(); + boolean isAddingDefaultTaskListDashboard = (DEFAULT_TASK_LIST_DASHBOARD.equals(selectedDashboard.getId())) + && dashboardService.findById(DEFAULT_TASK_LIST_DASHBOARD) == null; + boolean isAddingDefaultCaseListDashboard = (DEFAULT_CASE_LIST_DASHBOARD.equals(selectedDashboard.getId())) + && dashboardService.findById(DEFAULT_CASE_LIST_DASHBOARD) == null; + if (isAddingDefaultTaskListDashboard || isAddingDefaultCaseListDashboard) { + dashboardService.saveDefaultDashboardAsFirstDashboard(selectedDashboard); + } else { + dashboardService.save(selectedDashboard); + } + return selectedDashboard; + } + protected Map getRequestParameterMap() { return FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap(); } @@ -1003,4 +1021,63 @@ public boolean displayFullscreenModeOption() { .map(DashboardWidgetType::canShowFullscreenModeOption).orElse(false); } + public void onResizeColumn(ColumnResizeEvent event) { + String widgetId = (String) event.getComponent().getAttributes() + .getOrDefault("widgetId", ""); + + if (StringUtils.isBlank(widgetId)) { + return; + } + + DashboardWidget targetWidget = selectedDashboard.getWidgets() + .stream().filter(widget -> widget.getId().contentEquals(widgetId)) + .findFirst().orElse(null); + + if (targetWidget == null) { + return; + } + + if (targetWidget instanceof TaskDashboardWidget) { + handleResizeColumnOfTaskWidget( + (TaskDashboardWidget) targetWidget, + getColumnIndexFromColumnKey(event.getColumn().getColumnKey()), + event.getWidth()); + } + + if (targetWidget instanceof CaseDashboardWidget) { + handleResizeColumnOfCaseWidget( + (CaseDashboardWidget) targetWidget, + getColumnIndexFromColumnKey(event.getColumn().getColumnKey()), + event.getWidth()); + } + + selectedDashboard = saveDashboardsWithHandlingDefaultDashboards(); + } + + /** + * Split the ID and get the last part to get the order of the column Example: + * ID = 'task-1:task-component:dashboard-tasks:dashboard-tasks-columns:1' + * Then, the result should be 1 + * + * @param columnKey + * @return column index + */ + private Integer getColumnIndexFromColumnKey(String columnKey) { + List idParts = Arrays.asList(columnKey.split("\\:")); + return NumberUtils.toInt(idParts.get(idParts.size() - 1), -1); + } + + private void handleResizeColumnOfTaskWidget(TaskDashboardWidget widget, + int fieldPosition, int widthValue) { + widget.getColumns().get(fieldPosition) + .setWidth(Integer.toString(widthValue)); + widget.getColumns().forEach(col -> col.initDefaultStyle()); + } + + private void handleResizeColumnOfCaseWidget(CaseDashboardWidget widget, + int fieldPosition, int widthValue) { + widget.getColumns().get(fieldPosition) + .setWidth(Integer.toString(widthValue)); + widget.getColumns().forEach(col -> col.initDefaultStyle()); + } } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/DashboardModificationBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/DashboardModificationBean.java index f7c7cbe55fe..c6c86eafd56 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/DashboardModificationBean.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/DashboardModificationBean.java @@ -72,6 +72,7 @@ protected void collectDashboardsForManagement() { String dashboardInUserProperty = readDashboardBySessionUser(); if (isPublicDashboard) { this.dashboards = DashboardUtils.getPublicDashboards(); + DashboardUtils.addDefaultTaskCaseListDashboardsIfMissing(this.dashboards); } else if (StringUtils.isNoneEmpty(dashboardInUserProperty)) { List myDashboards = getVisibleDashboards(dashboardInUserProperty); this.dashboards.addAll(myDashboards); diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/DashboardTaskWidgetBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/DashboardTaskWidgetBean.java new file mode 100644 index 00000000000..521be776c4d --- /dev/null +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/DashboardTaskWidgetBean.java @@ -0,0 +1,106 @@ +package ch.ivy.addon.portal.generic.bean; + +import java.io.IOException; +import java.io.Serializable; +import java.util.List; +import java.util.Optional; +import java.util.Random; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import javax.annotation.PostConstruct; +import javax.faces.bean.ManagedBean; +import javax.faces.bean.ViewScoped; +import javax.faces.context.FacesContext; + +import org.primefaces.event.SelectEvent; + +import com.axonivy.portal.components.util.HtmlUtils; + +import ch.ivy.addon.portal.generic.navigation.PortalNavigator; +import ch.ivy.addon.portalkit.constant.PortalConstants; +import ch.ivy.addon.portalkit.enums.BehaviourWhenClickingOnLineInTaskList; +import ch.ivy.addon.portalkit.enums.GlobalVariable; +import ch.ivy.addon.portalkit.enums.PortalPage; +import ch.ivy.addon.portalkit.enums.TaskEmptyMessage; +import ch.ivy.addon.portalkit.jsf.ManagedBeans; +import ch.ivy.addon.portalkit.service.GlobalSettingService; +import ch.ivy.addon.portalkit.support.HtmlParser; +import ch.ivy.addon.portalkit.util.TaskUtils; +import ch.ivyteam.ivy.workflow.ITask; + +@ViewScoped +@ManagedBean +public class DashboardTaskWidgetBean implements Serializable { + + private static final long serialVersionUID = 1098133393632524689L; + + private ITask selectedTask; + private boolean isRunningTaskWhenClickingOnTaskInList; + private TaskEmptyMessage noTasksMessage; + + @PostConstruct + public void init() { + isRunningTaskWhenClickingOnTaskInList = GlobalSettingService.getInstance() + .findGlobalSettingValue( + GlobalVariable.DEFAULT_BEHAVIOUR_WHEN_CLICKING_ON_LINE_IN_TASK_LIST) + .equals(BehaviourWhenClickingOnLineInTaskList.RUN_TASK.name()); + } + + public void resetAndOpenTask() throws IOException { + TaskUtils.resetTask(selectedTask); + FacesContext.getCurrentInstance().getExternalContext() + .redirect(selectedTask.getStartLinkEmbedded().getRelative()); + } + + public void handleRowSelectEventOnTaskWidget(SelectEvent event) + throws IOException { + ITask task = ((ITask) event.getObject()); + handleSelectedTask(task); + } + + private void handleSelectedTask(ITask task) throws IOException { + if (isRunningTaskWhenClickingOnTaskInList) { + handleStartTask(task); + } else { + navigateToSelectedTaskDetails(task); + } + } + + public void handleStartTask(ITask task) throws IOException { + DashboardBean dashboardBean = ManagedBeans.get("dashboardBean"); + String selectedDashboardId = + Optional.ofNullable(dashboardBean).map(DashboardBean::getSelectedDashboardId).orElse(null); + selectedTask = task; + TaskUtils.handleStartTask(task, PortalPage.HOME_PAGE, + PortalConstants.RESET_TASK_CONFIRMATION_DIALOG, selectedDashboardId); + } + + public void navigateToSelectedTaskDetails(SelectEvent event) { + String uuid = ((ITask) event.getObject()).uuid(); + PortalNavigator.navigateToPortalTaskDetails(uuid); + } + + public void navigateToSelectedTaskDetails(ITask task) { + PortalNavigator.navigateToPortalTaskDetails(task.uuid()); + } + + public String createParseTextFromHtml(String text) { + return HtmlUtils.parseTextFromHtml(text); + } + + public TaskEmptyMessage getNoTasksMessage() { + if (noTasksMessage == null) { + List messages = Stream.of(TaskEmptyMessage.values()) + .collect(Collectors.toList()); + Random random = new Random(); + int index = random.ints(0, messages.size()).findFirst().getAsInt(); + noTasksMessage = messages.get(index); + } + return noTasksMessage; + } + + public String createExtractedTextFromHtml(String text) { + return HtmlParser.extractTextFromHtml(text); + } +} diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/NavigatorBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/NavigatorBean.java index c354bba7337..e1eed2bbde0 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/NavigatorBean.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/NavigatorBean.java @@ -6,7 +6,6 @@ import javax.faces.bean.RequestScoped; import ch.ivy.addon.portal.generic.navigation.PortalNavigator; -import ch.ivy.addon.portalkit.enums.MenuKind; @ManagedBean @RequestScoped @@ -16,17 +15,5 @@ public class NavigatorBean implements Serializable { public void navigateToCaseDetail(String uuid) { PortalNavigator.navigateToPortalCaseDetails(uuid); } - - public String getProcessPage() { - return MenuKind.PROCESS.toString(); - } - - public String getTaskPage() { - return MenuKind.TASK.toString(); - } - - public String getCasePage() { - return MenuKind.CASE.toString(); - } } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/UserMenuBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/UserMenuBean.java index eaba4acc941..602d2ee8aea 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/UserMenuBean.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/UserMenuBean.java @@ -31,6 +31,7 @@ import ch.ivy.addon.portalkit.service.AnnouncementService; import ch.ivy.addon.portalkit.service.GlobalSettingService; import ch.ivy.addon.portalkit.service.IvyCacheService; +import ch.ivy.addon.portalkit.util.DashboardUtils; import ch.ivy.addon.portalkit.util.PermissionUtils; import ch.ivy.addon.portalkit.util.RequestUtils; import ch.ivy.addon.portalkit.util.TaskUtils; @@ -84,7 +85,7 @@ public void init() { boolean isShowGlobalSearchByTasks = GlobalSearchService.getInstance().isShowGlobalSearchByTasks(); boolean isShowGlobalSearchByCases = GlobalSearchService.getInstance().isShowGlobalSearchByCases(); isShowGlobalSearch = GlobalSettingService.getInstance().findGlobalSettingValueAsBoolean(GlobalVariable.SHOW_GLOBAL_SEARCH) - && (isShowGlobalSearchByProcesses || isShowGlobalSearchByCases || isShowGlobalSearchByTasks);; + && (isShowGlobalSearchByProcesses || isShowGlobalSearchByCases || isShowGlobalSearchByTasks); isShowQuickGlobalSearch = GlobalSettingService.getInstance() .findGlobalSettingValueAsBoolean(GlobalVariable.SHOW_QUICK_GLOBAL_SEARCH) && (isShowGlobalSearchByProcesses || isShowGlobalSearchByCases || isShowGlobalSearchByTasks); @@ -210,7 +211,7 @@ public void resetTaskAndNavigateWithGrowl(ITask task) throws IOException { private void executeJSResetPortalMenuState() { PrimeFaces.current().executeScript("resetPortalLeftMenuState()"); } - + private void openTaskLosingConfirmationDialog() { PrimeFaces.current().executeScript("PF('logo-task-losing-confirmation-dialog').show()"); } @@ -257,7 +258,11 @@ public void navigateToHomePage() throws IOException { public void navigateToUserProfile() throws IOException { getExternalContext().redirect(getUserProfileUrl()); } - + + public void navigateToAssistantDashboard() throws IOException { + getExternalContext().redirect(getAssistantDashboardUrl()); + } + private void navigateToTargetPage() throws IOException { getExternalContext().redirect(targetPage); } @@ -266,6 +271,10 @@ private String getUserProfileUrl() { return PortalNavigator.buildUserProfileUrl(); } + private String getAssistantDashboardUrl() { + return PortalNavigator.buildAssistantDashboardUrl(); + } + private void navigateToPortalManagement() throws IOException { getExternalContext().redirect(getPortalManagementUrl()); } @@ -368,4 +377,17 @@ public String getGooglePlayImageLink() { return GOOGLE_PLAY_IMAGE_CMS_URL; } + public String getInfoToHighlightMenu() { + return DashboardUtils.getSelectedMainDashboardIdFromSession(); + } + + public void navigateToChatBotOrDisplayWorkingTaskWarning(boolean isWorkingOnATask, ITask task) throws IOException { + if (isWorkingOnATask && task.getState() != TaskState.DONE) { + openTaskLosingConfirmationDialog(); + targetPage = getAssistantDashboardUrl(); + } else { + executeJSResetPortalMenuState(); + navigateToAssistantDashboard(); + } + } } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/UserProfileBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/UserProfileBean.java index 8649b6e8ec0..80ea36b5055 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/UserProfileBean.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/UserProfileBean.java @@ -1,10 +1,7 @@ package ch.ivy.addon.portal.generic.bean; import java.io.Serializable; -import java.util.Arrays; import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; import javax.faces.bean.ManagedBean; import javax.faces.bean.ViewScoped; @@ -15,15 +12,9 @@ import com.axonivy.portal.components.util.FacesMessageUtils; import ch.ivy.addon.portalkit.constant.UserProperty; -import ch.ivy.addon.portalkit.enums.CaseSortField; -import ch.ivy.addon.portalkit.enums.GlobalVariable; -import ch.ivy.addon.portalkit.enums.SortDirection; -import ch.ivy.addon.portalkit.enums.TaskSortField; import ch.ivy.addon.portalkit.ivydata.dto.IvyNotificationChannelDTO; import ch.ivy.addon.portalkit.ivydata.dto.IvyNotificationChannelSubcriptionDTO; import ch.ivy.addon.portalkit.ivydata.dto.IvyNotificationEventDTO; -import ch.ivy.addon.portalkit.ivydata.service.impl.UserSettingService; -import ch.ivy.addon.portalkit.service.GlobalSettingService; import ch.ivy.addon.portalkit.util.PermissionUtils; import ch.ivyteam.ivy.environment.Ivy; import ch.ivyteam.ivy.notification.channel.NotificationSubscription; @@ -34,9 +25,7 @@ @ManagedBean @ViewScoped public class UserProfileBean implements Serializable { - private static final String DEFAULT_OPTION = "/ch.ivy.addon.portalkit.ui.jsf/MyProfile/defaultOption"; private static final long serialVersionUID = 4952280551311826903L; - private static final String DEFAULT = UserSettingService.DEFAULT; public UserProfileBean() {} @@ -60,74 +49,6 @@ public void saveHomepage(String homepageName) { user.setProperty(UserProperty.HOMEPAGE, homepageName); } - public String getDisplayNameOfTaskSortField(String sortField) { - List sortFieldNames = Stream.of(TaskSortField.values()).map(Enum::name).collect(Collectors.toList()); - - if (StringUtils.equals(sortField, DEFAULT)) { - GlobalSettingService globalSettingService = GlobalSettingService.getInstance(); - String defaultSortField = globalSettingService - .findGlobalSettingByGlobalVariable(GlobalVariable.DEFAULT_SORT_FIELD_OF_TASK_LIST).getValue(); - - String displaySortField = - sortFieldNames.contains(defaultSortField) ? TaskSortField.valueOf(defaultSortField).getLabel() - : defaultSortField; - return getDefaultSelection(displaySortField); - } - - return sortFieldNames.contains(sortField) ? TaskSortField.valueOf(sortField).getLabel() : sortField; - } - - public String getDisplayNameOfCaseSortField(String sortField) { - List sortFieldNames = Stream.of(CaseSortField.values()).map(Enum::name).collect(Collectors.toList()); - if (StringUtils.equals(sortField, DEFAULT)) { - GlobalSettingService globalSettingService = GlobalSettingService.getInstance(); - String defaultSortField = globalSettingService - .findGlobalSettingByGlobalVariable(GlobalVariable.DEFAULT_SORT_FIELD_OF_CASE_LIST).getValue(); - - String displaySortField = - sortFieldNames.contains(defaultSortField) ? CaseSortField.valueOf(defaultSortField).getLabel() - : defaultSortField; - return getDefaultSelection(displaySortField); - } - - return sortFieldNames.contains(sortField) ? CaseSortField.valueOf(sortField).getLabel() : sortField; - } - - public String getDisplayNameOfTaskSortDirection(String sortDirection) { - List sortDirectionNames = Stream.of(SortDirection.values()).map(Enum::name).collect(Collectors.toList()); - if (StringUtils.equals(sortDirection, DEFAULT)) { - GlobalSettingService globalSettingService = GlobalSettingService.getInstance(); - String defaultDirection = globalSettingService - .findGlobalSettingByGlobalVariable(GlobalVariable.DEFAULT_SORT_DIRECTION_OF_TASK_LIST).getValue(); - - String displayDirection = - sortDirectionNames.contains(defaultDirection) ? SortDirection.valueOf(defaultDirection).getLabel() : ""; - return getDefaultSelection(displayDirection); - } - - return sortDirectionNames.contains(sortDirection) ? SortDirection.valueOf(sortDirection).getLabel() : ""; - } - - public String getDisplayNameOfCaseSortDirection(String sortDirection) { - List sortDirectionNames = Stream.of(SortDirection.values()).map(Enum::name).collect(Collectors.toList()); - if (StringUtils.equals(sortDirection, DEFAULT)) { - GlobalSettingService globalSettingService = GlobalSettingService.getInstance(); - String defaultDirection = globalSettingService - .findGlobalSettingByGlobalVariable(GlobalVariable.DEFAULT_SORT_DIRECTION_OF_CASE_LIST).getValue(); - - String displayDirection = - sortDirectionNames.contains(defaultDirection) ? SortDirection.valueOf(defaultDirection).getLabel() : ""; - return getDefaultSelection(displayDirection); - } - - - return sortDirectionNames.contains(sortDirection) ? SortDirection.valueOf(sortDirection).getLabel() : ""; - } - - private String getDefaultSelection(String sortFieldName) { - return Ivy.cms().co(DEFAULT_OPTION, Arrays.asList(sortFieldName)); - } - public void onloadChannel() { events = IvyNotificationEventDTO.all(); channels = IvyNotificationChannelDTO.all(subscriber, securityContext); @@ -172,11 +93,4 @@ public Boolean canAccessProcessList() { return PermissionUtils.checkAccessFullProcessListPermission(); } - public Boolean canAccessTaskList() { - return PermissionUtils.checkAccessFullTaskListPermission(); - } - - public Boolean canAccessCaseList() { - return PermissionUtils.checkAccessFullCaseListPermission(); - } } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/navigation/PortalNavigator.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/navigation/PortalNavigator.java index b02592f9776..87d33ff23da 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/navigation/PortalNavigator.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/navigation/PortalNavigator.java @@ -1,9 +1,13 @@ package ch.ivy.addon.portal.generic.navigation; +import static ch.ivy.addon.portalkit.util.DashboardUtils.DEFAULT_CASE_LIST_DASHBOARD; +import static ch.ivy.addon.portalkit.util.DashboardUtils.DEFAULT_TASK_LIST_DASHBOARD; + import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Map; +import java.util.Optional; import java.util.stream.Collectors; import org.apache.commons.lang3.StringUtils; @@ -14,16 +18,17 @@ import ch.ivy.addon.portalkit.enums.MenuKind; import ch.ivy.addon.portalkit.enums.SessionAttribute; +import ch.ivy.addon.portalkit.service.AiProcessService; import ch.ivy.addon.portalkit.util.RequestUtils; import ch.ivyteam.ivy.environment.Ivy; +import ch.ivyteam.ivy.model.value.WebLink; import ch.ivyteam.ivy.request.IHttpRequest; +import ch.ivyteam.ivy.workflow.IProcessStart; import ch.ivyteam.ivy.workflow.StandardProcessType; public final class PortalNavigator extends BaseNavigator{ private static final String PORTAL_DASHBOARD = "Start Processes/PortalStart/DefaultDashboardPage.ivp"; private static final String PORTAL_PROCESS = "Start Processes/PortalStart/DefaultProcessStartListPage.ivp"; - private static final String PORTAL_TASK = "Start Processes/PortalStart/DefaultTaskListPage.ivp"; - private static final String PORTAL_CASE = "Start Processes/PortalStart/CaseListPage.ivp"; private static final String PORTAL_CASE_DETAILS = "Start Processes/PortalStart/DefaultCaseDetailPage.ivp"; private static final String PORTAL_RELATED_TASKS_OF_CASE = "Start Processes/PortalStart/RelatedTasksOfCasePage.ivp"; private static final String PORTAL_RELATED_TASKS_OF_CASE_IN_FRAME = "Start Processes/PortalStart/RelatedTasksOfCasePageInFrame.ivp"; @@ -42,10 +47,10 @@ public final class PortalNavigator extends BaseNavigator{ public static final String PORTAL_DASHBOARD_START = "/DefaultDashboardPage.ivp"; public static final String PORTAL_PROCESS_START = "/DefaultProcessStartListPage.ivp"; - public static final String PORTAL_TASK_START = "/DefaultTaskListPage.ivp"; - public static final String PORTAL_CASE_START = "/CaseListPage.ivp"; public static final String PORTAL_USER_PROFILE_START = "/UserProfile.ivp"; public static final String PORTAL_CASE_DETAILS_IN_IFRAME_START = "/CaseDetailsInIFrame.ivp"; + public static final String PORTAL_DASHBOARD_PAGE_START = "/DashboardPage.ivp"; + public static final String DASHBOARD_ID = "dashboardId"; private static final String UUID = "uuid"; private static final String ID = "id"; private static final String PORTAL_DASHBOARD_PAGE = "Start Processes/PortalStart/DashboardPage.ivp"; @@ -85,18 +90,17 @@ public static String getPasswordResetUrl(String token, String username) { public static void redirect(String url) { redirectURL(url); } - + public static String getDashboardPageUrl(String dashboardId) { Map params = new HashMap<>(); - params.put("dashboardId", dashboardId); + params.put(DASHBOARD_ID, dashboardId); return buildUrl(PORTAL_DASHBOARD_PAGE, params); } public static String getSubMenuItemUrlOfCurrentApplication(MenuKind menuKind) { String subMenuUrl = switch (menuKind) { case PROCESS -> PORTAL_PROCESS; - case TASK -> PORTAL_TASK; - case CASE -> PORTAL_CASE; + case MAIN_DASHBOARD -> PORTAL_DASHBOARD_PAGE; default -> StringUtils.EMPTY; }; return ProcessStartAPI.findRelativeUrlByProcessStartFriendlyRequestPath(subMenuUrl); @@ -113,11 +117,17 @@ public static void navigateToPortalProcess() { } public static void navigateToPortalCase() { - navigateByKeyword(PORTAL_CASE_START, PORTAL_CASE, new HashMap<>()); + navigateToDashboard(DEFAULT_CASE_LIST_DASHBOARD); } public static void navigateToPortalTask() { - navigateByKeyword(PORTAL_TASK_START, PORTAL_TASK, new HashMap<>()); + navigateToDashboard(DEFAULT_TASK_LIST_DASHBOARD); + } + + private static void navigateToDashboard(String dashboardId) { + Map params = new HashMap<>(); + params.put(DASHBOARD_ID, dashboardId); + navigateByKeyword(PORTAL_DASHBOARD_PAGE_START, PORTAL_DASHBOARD_PAGE, params); } public static void navigateToPortalCaseDetails(String uuid) { @@ -180,7 +190,7 @@ public static void navigateToUserProfile() { public static void navigateToDashboardDetailsPage(String dashboardId, boolean isPublicDashboard) { Map params = new HashMap<>(); - params.put("dashboardId", dashboardId); + params.put(DASHBOARD_ID, dashboardId); params.put("isPublicDashboard", Boolean.valueOf(isPublicDashboard).toString()); navigateByKeyword("DashboardDetails.ivp", PORTAL_DASHBOARD_DETAILS, params); } @@ -270,4 +280,11 @@ public static void navigateToNotificationFullPage() { public static String buildNotificationFullPageUrl() { return buildUrlByKeyword(PORTAL_NOTIFICATION_FULLPAGE_START, PORTAL_NOTIFICATION_FULLPAGE, new HashMap<>()); } + + public static String buildAssistantDashboardUrl() { + IProcessStart process = AiProcessService.getInstance() + .findAssistantDashboardProcess(); + return Optional.ofNullable(process).map(IProcessStart::getLinkEmbedded) + .map(WebLink::getRelative).orElse(""); + } } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/util/ProcessStepUtils.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/util/ProcessStepUtils.java index 0f37a083d58..8f88bec3ab9 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/util/ProcessStepUtils.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/util/ProcessStepUtils.java @@ -39,7 +39,7 @@ public static List findProcessStepsOfProcess(UserProcess process) { return Sudo.get(() -> { IProcessModelVersion releasedProcessModelVersion = null; - List applicationsInSecurityContext = IApplicationRepository.instance().allOf(ISecurityContext.current()); + List applicationsInSecurityContext = IApplicationRepository.of(ISecurityContext.current()).all(); for (IApplication app : applicationsInSecurityContext) { IProcessModel findProcessModel = app.findProcessModel(processModelName); if (findProcessModel != null) { diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/AbstractProcessBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/AbstractProcessBean.java index 96c5d1375e4..716c9b61865 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/AbstractProcessBean.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/AbstractProcessBean.java @@ -51,7 +51,7 @@ public String getProcessInformationPageUrl(Process process) { if (nestedProcess instanceof IWebStartable) { processId = ((IWebStartable) nestedProcess).getId(); } - return PortalNavigator.buildProcessInfoUrl(processId); + return PortalNavigator.buildProcessInfoUrl(processId.isEmpty() ? process.getId() : processId ); } protected abstract List findProcesses(); diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/CaseActionBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/CaseActionBean.java index b3a82791d21..92a2d1e15bc 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/CaseActionBean.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/CaseActionBean.java @@ -187,7 +187,7 @@ public String getProcessViewerPageUri(ICase selectedCase) { return PortalProcessViewerUtils.getStartProcessViewerPageUri(selectedCase); } - public boolean showProcessOverviewLink(ICase iCase) { + public boolean showProcessOverviewLink(@SuppressWarnings("unused") ICase iCaze) { return GlobalSettingService.getInstance().findGlobalSettingValueAsBoolean(GlobalVariable.SHOW_PROCESS_INFORMATION); } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/CaseBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/CaseBean.java index d45910f3855..58294196828 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/CaseBean.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/CaseBean.java @@ -2,6 +2,7 @@ import java.io.Serializable; import java.text.SimpleDateFormat; +import java.util.ArrayList; import java.util.Date; import java.util.List; @@ -9,13 +10,14 @@ import javax.faces.bean.ManagedBean; import javax.faces.bean.ViewScoped; -import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; import com.axonivy.portal.components.publicapi.ProcessStartAPI; import com.axonivy.portal.components.util.ProcessStartUtils; import ch.ivy.addon.portal.generic.navigation.PortalNavigator; +import ch.ivy.addon.portalkit.dto.dashboard.casecolumn.CaseColumnModel; +import ch.ivy.addon.portalkit.enums.DashboardStandardCaseColumn; import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivy.addon.portalkit.service.GlobalSettingService; import ch.ivy.addon.portalkit.util.DateTimeFormatterUtils; @@ -24,7 +26,6 @@ import ch.ivyteam.ivy.environment.Ivy; import ch.ivyteam.ivy.workflow.ICase; import ch.ivyteam.ivy.workflow.caze.CaseBusinessState; -import ch.ivyteam.ivy.workflow.caze.owner.ICaseOwner; @ManagedBean(name = "caseBean") @ViewScoped @@ -114,27 +115,30 @@ public boolean isCaseOwnerEnabled() { public void setCaseOwnerEnabled(boolean isCaseOwnerEnabled) { this.isCaseOwnerEnabled = isCaseOwnerEnabled; } - - public String getAriaLabel(ICase icase) { - String ariaLabel = Ivy.cms().co("/ch.ivy.addon.portalkit.ui.jsf/common/caseName") + ": " + icase.getName(); - ariaLabel += " - " + Ivy.cms().co("/ch.ivy.addon.portalkit.ui.jsf/common/state") + ": " + getState(icase); - - if (icase.getStartTimestamp() != null) { - String createdDateString = new SimpleDateFormat(DateTimeGlobalSettingService.getInstance().getGlobalDateTimePattern()).format(icase.getStartTimestamp()); - ariaLabel += " - " + Ivy.cms().co("/ch.ivy.addon.portalkit.ui.jsf/caseList/defaultColumns/CREATION_TIME") + ": " + createdDateString; - } - - if (icase.getEndTimestamp() != null) { - String finishedDateString = new SimpleDateFormat(DateTimeGlobalSettingService.getInstance().getGlobalDateTimePattern()).format(icase.getEndTimestamp()); - ariaLabel += " - " + Ivy.cms().co("/ch.ivy.addon.portalkit.ui.jsf/caseList/defaultColumns/FINISHED_TIME") + ": " + finishedDateString; - } - List owners = icase.owners().all(); - if (CollectionUtils.isNotEmpty(owners)) { - ariaLabel += " - " + Ivy.cms().co("/ch.ivy.addon.portalkit.ui.jsf/caseList/defaultColumns/OWNER") + ": " + owners.getFirst().member().getDisplayName(); + public String getAriaLabel(ICase icase, List columns) { + List displayTexts = new ArrayList<>(); + for (CaseColumnModel col : columns) { + if (col.getVisible()) { + if (DashboardStandardCaseColumn.STATE.getField().equalsIgnoreCase(col.getField())) { + displayTexts.add(col.getHeaderText() + ": " + getState(icase)); + } else if (DashboardStandardCaseColumn.CREATED.getField().equalsIgnoreCase(col.getField())) { + String createdDateString = new SimpleDateFormat(DateTimeGlobalSettingService.getInstance().getGlobalDateTimePattern()).format(icase.getStartTimestamp()); + displayTexts.add(col.getHeaderText() + ": " + createdDateString); + } else if (DashboardStandardCaseColumn.FINISHED.getField().equalsIgnoreCase(col.getField())) { + if (icase.getEndTimestamp() != null) { + String finishDateString = new SimpleDateFormat(DateTimeGlobalSettingService.getInstance().getGlobalDateTimePattern()).format(icase.getEndTimestamp()); + displayTexts.add(col.getHeaderText() + ": " + finishDateString); + } + } else { + Object displayObject = col.display(icase); + if (displayObject != null && StringUtils.isNotEmpty(displayObject.toString())) { + displayTexts.add(col.getHeaderText() + ": " + displayObject.toString()); + } + } + } } - - return ariaLabel; + return String.join(" - ", displayTexts); } } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/CaseDetailsBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/CaseDetailsBean.java index 0de5f7f6eab..d397d3337e1 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/CaseDetailsBean.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/CaseDetailsBean.java @@ -9,6 +9,7 @@ import javax.faces.bean.ManagedBean; import javax.faces.bean.ViewScoped; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.BooleanUtils; import org.apache.commons.lang3.StringUtils; import org.primefaces.event.SelectEvent; @@ -33,12 +34,14 @@ import ch.ivy.addon.portalkit.jsf.ManagedBeans; import ch.ivy.addon.portalkit.service.GlobalSettingService; import ch.ivy.addon.portalkit.util.PermissionUtils; +import ch.ivy.addon.portalkit.util.SecurityMemberDisplayNameUtils; import ch.ivy.addon.portalkit.util.SortFieldUtil; import ch.ivy.addon.portalkit.util.TaskUtils; import ch.ivyteam.ivy.environment.Ivy; import ch.ivyteam.ivy.workflow.ICase; import ch.ivyteam.ivy.workflow.ITask; import ch.ivyteam.ivy.workflow.caze.CaseBusinessState; +import ch.ivyteam.ivy.workflow.caze.owner.CaseOwner; import ch.ivyteam.ivy.workflow.query.CaseQuery; @ManagedBean @@ -60,6 +63,7 @@ public class CaseDetailsBean extends AbstractConfigurableContentBean getCaseOwners() { + return selectedCase.owners().all(); + } } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/CaseTaskDocumentBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/CaseTaskDocumentBean.java index 157c7709f51..4d834930018 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/CaseTaskDocumentBean.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/CaseTaskDocumentBean.java @@ -15,7 +15,6 @@ import ch.ivy.addon.portalkit.util.SortFieldUtil; import ch.ivyteam.ivy.security.IPermission; import ch.ivyteam.ivy.workflow.ICase; -import ch.ivyteam.ivy.workflow.INoteable; import ch.ivyteam.ivy.workflow.ITask; import ch.ivyteam.ivy.workflow.caze.CaseBusinessState; @@ -33,33 +32,31 @@ public boolean isShowMoreDocument() { return PermissionUtils.hasPermission(IPermission.DOCUMENT_READ); } - public boolean canWriteDocument(INoteable iNoteable) { - ICase currentCase = getCurrentBusinessCase(iNoteable); - if (currentCase == null) { + public boolean canWriteDocument(ICase caze) { + if (caze == null) { return false; } var isHideUploadDocForDoneCase = GlobalSettingService.getInstance() .findGlobalSettingValueAsBoolean(GlobalVariable.HIDE_UPLOAD_DOCUMENT_FOR_DONE_CASE); - return !(currentCase.getBusinessState() == CaseBusinessState.DONE && isHideUploadDocForDoneCase) && hasPermissionWriteDocument(iNoteable); + return !(caze.getBusinessState() == CaseBusinessState.DONE && isHideUploadDocForDoneCase) && hasPermissionWriteDocument(caze); } - - private ICase getCurrentBusinessCase(INoteable iNoteable) { - if (iNoteable instanceof ICase) { - return (ICase) iNoteable; - } - if (iNoteable instanceof ITask) { - var task = (ITask) iNoteable; - return task.getCase().getBusinessCase(); + + public boolean canWriteDocument(ITask task) { + ICase currentCase = task.getCase().getBusinessCase(); + if (currentCase == null) { + return false; } - return null; + var isHideUploadDocForDoneCase = GlobalSettingService.getInstance() + .findGlobalSettingValueAsBoolean(GlobalVariable.HIDE_UPLOAD_DOCUMENT_FOR_DONE_CASE); + return !(currentCase.getBusinessState() == CaseBusinessState.DONE && isHideUploadDocForDoneCase) && hasPermissionWriteDocument(task); } - public boolean hasPermissionWriteDocument(INoteable iNoteable) { + private boolean hasPermissionWriteDocument(Object iNoteable) { return hasPermission(iNoteable, IPermission.DOCUMENT_WRITE) || hasPermission(iNoteable, IPermission.DOCUMENT_OF_INVOLVED_CASE_WRITE); } - private boolean hasPermission(INoteable iNoteable, IPermission permission) { + private boolean hasPermission(Object iNoteable, IPermission permission) { if (iNoteable == null || permission == null) { return false; } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/CaseTaskNoteHistoryBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/CaseTaskNoteHistoryBean.java index b9d3f3990f3..f0c3b80eaaa 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/CaseTaskNoteHistoryBean.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/CaseTaskNoteHistoryBean.java @@ -19,8 +19,8 @@ import ch.ivy.addon.portalkit.util.SortFieldUtil; import ch.ivyteam.ivy.environment.Ivy; import ch.ivyteam.ivy.workflow.ICase; -import ch.ivyteam.ivy.workflow.INote; import ch.ivyteam.ivy.workflow.ITask; +import ch.ivyteam.ivy.workflow.note.Note; @ManagedBean(name = "caseTaskNoteHistoryBean") public class CaseTaskNoteHistoryBean implements Serializable { @@ -73,7 +73,7 @@ private String createContentWithTaskState(String taskStateCmsUrl, String content return String.format("%s: %s", Ivy.cms().co(taskStateCmsUrl), content); } - public StreamedContent getExportedFileOfTaskNoteHistory(List taskNoteHistory, String fileName) { + public StreamedContent getExportedFileOfTaskNoteHistory(List taskNoteHistory, String fileName) { NoteHistoryExporter exporter = new NoteHistoryExporter(); return exporter.getStreamedContentOfTaskNoteHistory(taskNoteHistory, fileName + ".xlsx"); } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/CompactDashboardProcessBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/CompactDashboardProcessBean.java index 752d065ccc8..3c213177b86 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/CompactDashboardProcessBean.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/CompactDashboardProcessBean.java @@ -5,6 +5,8 @@ import java.io.IOException; import java.io.Serializable; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.List; import java.util.Objects; @@ -15,6 +17,7 @@ import javax.faces.bean.ViewScoped; import org.apache.commons.collections4.CollectionUtils; +import org.primefaces.PrimeFaces; import ch.ivy.addon.portalkit.dto.dashboard.ColumnModel; import ch.ivy.addon.portalkit.dto.dashboard.CompactProcessDashboardWidget; @@ -151,8 +154,19 @@ private ColumnModel getFilterableColumnByField(DashboardStandardProcessColumn co } public void startProcessWithCompactMode(DashboardProcess process) throws IOException { + startProcessWithCompactMode(process, false); + } + + public void startProcessWithCompactMode(DashboardProcess process, + boolean isAiResult) throws IOException { Objects.requireNonNull(process, "Process must not be null"); String link = process.getStartLink(); + + if (isAiResult) { + handleNavigateAsAiResult(process, link); + return; + } + if (dashboardProcessBean.isExternalLink(process)) { dashboardProcessBean.redirectToLink(link, false); return; @@ -161,6 +175,16 @@ public void startProcessWithCompactMode(DashboardProcess process) throws IOExcep dashboardProcessBean.redirectToLink(link, true); } + private void handleNavigateAsAiResult(DashboardProcess process, String link) + throws IOException { + link = dashboardProcessBean.getRedirectLink(link, + !dashboardProcessBean.isExternalLink(process)); + + String statement = "parent.parent.redirectToUrlCommand([{name: 'url', value: '" + + URLDecoder.decode(link, StandardCharsets.UTF_8) + "'}])"; + PrimeFaces.current().executeScript(statement); + } + public boolean isBrokenLink(DashboardProcess dashboardProcess) { return !getAllPortalProcesses() .stream() diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/DashboardProcessBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/DashboardProcessBean.java index 053a54ba9f8..5bdb552c1ff 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/DashboardProcessBean.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/DashboardProcessBean.java @@ -125,6 +125,13 @@ protected void redirectToLink(String link, boolean isEmbedInFrame) throws IOExce FacesContext.getCurrentInstance().getExternalContext().redirect(link); } + protected String getRedirectLink(String link, boolean isEmbedInFrame) { + if (isEmbedInFrame) { + link += (link.contains("?") ? "&" : "?" + "embedInFrame"); + } + return link; + } + public boolean isCaseMap(DashboardProcess process) { return !Objects.isNull(process) && process.getStartLink().endsWith(".icm"); } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/DocumentIconBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/DocumentIconBean.java index 7d96b51b6cf..505974baf16 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/DocumentIconBean.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/DocumentIconBean.java @@ -52,7 +52,7 @@ public class DocumentIconBean implements Serializable { * @param documentName is a name of file * @return return CSS class for icon */ - public static String getIconCssClass(String documentName) { + public String getIconCssClass(String documentName) { String iconClass = StringUtils.EMPTY; if (StringUtils.isNotEmpty(documentName)) { String fileExtension = getExtensionByFileName(documentName); @@ -84,7 +84,7 @@ public static String getIconCssClass(String documentName) { return iconClass; } - private static String getExtensionByFileName(String documentName) { + private String getExtensionByFileName(String documentName) { String fileName = StringUtils.trimToEmpty(documentName); fileName = RegExUtils.removeAll(fileName, FILE_NAME_REGEX); return FilenameUtils.getExtension(StringUtils.lowerCase(fileName)); diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/MasterDataBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/MasterDataBean.java index 30077850aad..e6d7e06fd3d 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/MasterDataBean.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/MasterDataBean.java @@ -2,12 +2,14 @@ import java.io.Serializable; import java.util.Arrays; +import java.util.List; import javax.faces.application.FacesMessage; import javax.faces.bean.ManagedBean; import javax.faces.bean.SessionScoped; import javax.faces.context.FacesContext; +import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.io.FileUtils; import org.apache.commons.lang.BooleanUtils; import org.primefaces.PrimeFaces; @@ -23,6 +25,7 @@ import ch.ivy.addon.portalkit.ivydata.service.impl.LanguageService; import ch.ivy.addon.portalkit.masterdata.AwesomeIcon; import ch.ivy.addon.portalkit.masterdata.MasterData; +import ch.ivy.addon.portalkit.service.CaseDocumentService; import ch.ivy.addon.portalkit.util.GrowlMessageUtils; import ch.ivy.addon.portalkit.util.SecurityServiceUtils; import ch.ivyteam.ivy.environment.Ivy; @@ -125,4 +128,12 @@ public String getApplicationName() { public String getUserLanguage() { return LanguageService.getInstance().getUserLanguage(); } + + public String getAllowedUploadFileType() { + List extensionList = CaseDocumentService.getAllowedUploadFileType(); + if (CollectionUtils.isEmpty(extensionList)) { + return Ivy.cms().co("/ch.ivy.addon.portalkit.ui.jsf/common/allTypes"); + } else + return String.join(", ", extensionList); + } } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/TaskActionBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/TaskActionBean.java index 728b2329944..2452356aaa8 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/TaskActionBean.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/TaskActionBean.java @@ -52,25 +52,8 @@ public TaskActionBean() { isShowReadWorkflowEvent = PermissionUtils.hasPortalPermission(PortalPermission.TASK_DISPLAY_WORKFLOW_EVENT_ACTION); } - public static boolean canReset(ITask task) { - if (task == null) { - return false; - } - - EnumSet taskStates = EnumSet.of(TaskState.RESUMED, TaskState.PARKED, TaskState.READY_FOR_JOIN, - TaskState.FAILED); - if (!taskStates.contains(task.getState())) { - return false; - } - - if (task.getState() == TaskState.READY_FOR_JOIN) { - IPermission resetTaskReadyForJoin = IPermissionRepository.instance().findByName(PortalPermission.TASK_RESET_READY_FOR_JOIN.getValue()); - return hasPermission(task, resetTaskReadyForJoin); - } - - - return (hasPermission(task, IPermission.TASK_RESET_OWN_WORKING_TASK) && canResume(task)) - || hasPermission(task, IPermission.TASK_RESET); + public boolean canReset(ITask task) { + return TaskUtils.canReset(task); } public boolean canDelegate(ITask task) { @@ -104,7 +87,7 @@ private boolean userCanOnlyDelegateAssignedTask(ITask task) { return hasPermission(task, permission) && !hasPermission(task, IPermission.TASK_WRITE_ACTIVATOR); } - public static boolean canResume(ITask task) { + public boolean canResume(ITask task) { return TaskUtils.canResume(task); } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/TaskBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/TaskBean.java index 11e719aeb13..7c66011583b 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/TaskBean.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/TaskBean.java @@ -13,6 +13,8 @@ import org.apache.commons.lang3.StringUtils; import org.primefaces.model.SortMeta; +import ch.ivy.addon.portalkit.dto.dashboard.taskcolumn.TaskColumnModel; +import ch.ivy.addon.portalkit.enums.DashboardStandardTaskColumn; import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivy.addon.portalkit.util.SortFieldUtil; import ch.ivyteam.ivy.environment.Ivy; @@ -119,20 +121,32 @@ public SortMeta getTaskWorkflowEventSortByTimestamp() { return SortFieldUtil.buildSortMeta("timestamp", true); } - public String getAriaLabel(ITask task) { - String ariaLabel = Ivy.cms().co("/ch.ivy.addon.portalkit.ui.jsf/dashboard/taskStart"); - ariaLabel += " - " + Ivy.cms().co("/ch.ivy.addon.portalkit.ui.jsf/common/taskName") + ": " + task.getName(); - ariaLabel += " - " + Ivy.cms().co("/ch.ivy.addon.portalkit.ui.jsf/taskList/defaultColumns/PRIORITY") + ": " - + Ivy.cms().co("/ch.ivy.addon.portalkit.ui.jsf/taskPriority/" + task.getPriority().name()); - ariaLabel += " - " + Ivy.cms().co("/ch.ivy.addon.portalkit.ui.jsf/taskList/defaultColumns/STATE") + ": " - + Ivy.cms().co("/ch.ivy.addon.portalkit.ui.jsf/taskState/" + task.getState().name()); - - if (task.getExpiryTimestamp() != null) { - String expiryDateString = new SimpleDateFormat( - DateTimeGlobalSettingService.getInstance().getGlobalDateTimePattern()).format(task.getExpiryTimestamp()); - ariaLabel += " - " + Ivy.cms().co("/ch.ivy.addon.portalkit.ui.jsf/taskList/defaultColumns/EXPIRY_TIME") + ": " - + expiryDateString; + public String getAriaLabel(ITask task, List columns) { + List displayTexts = new ArrayList<>(); + for (TaskColumnModel col : columns) { + if (col.getVisible()) { + if (DashboardStandardTaskColumn.START.getField().equalsIgnoreCase(col.getField())) { + displayTexts.add(cms("/ch.ivy.addon.portalkit.ui.jsf/dashboard/taskStart")); + } else if (DashboardStandardTaskColumn.PRIORITY.getField().equalsIgnoreCase(col.getField())) { + displayTexts.add(col.getHeaderText() + ": " + getPriority(task.getPriority())); + } else if (DashboardStandardTaskColumn.STATE.getField().equalsIgnoreCase(col.getField())) { + displayTexts.add(col.getHeaderText() + ": " + getTaskBusinessState(task.getBusinessState())); + } else if (DashboardStandardTaskColumn.CREATED.getField().equalsIgnoreCase(col.getField())) { + String createdDateString = new SimpleDateFormat(DateTimeGlobalSettingService.getInstance().getGlobalDateTimePattern()).format(task.getStartTimestamp()); + displayTexts.add(col.getHeaderText() + ": " + createdDateString); + } else if (DashboardStandardTaskColumn.EXPIRY.getField().equalsIgnoreCase(col.getField())) { + if (task.getExpiryTimestamp() != null) { + String expiryDateString = new SimpleDateFormat(DateTimeGlobalSettingService.getInstance().getGlobalDateTimePattern()).format(task.getExpiryTimestamp()); + displayTexts.add(col.getHeaderText() + ": " + expiryDateString); + } + } else { + Object displayObject = col.display(task); + if (displayObject != null && StringUtils.isNotEmpty(displayObject.toString())) { + displayTexts.add(col.getHeaderText() + ": " + displayObject.toString()); + } + } + } } - return ariaLabel; + return String.join(" - ", displayTexts); } } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/TaskWidgetBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/TaskWidgetBean.java index d2da1f60f48..0228d9aa9c0 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/TaskWidgetBean.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bean/TaskWidgetBean.java @@ -51,8 +51,7 @@ public class TaskWidgetBean implements Serializable { public TaskWidgetBean() { expandedTaskId = -1L; - String taskListRefreshIntervalUserSetting = - GlobalSettingService.getInstance().findGlobalSettingValue(GlobalVariable.REFRESH_TASK_LIST_INTERVAL); + String taskListRefreshIntervalUserSetting = "10000"; // set default value instead of variable taskListRefreshInterval = StringUtils.isNumeric(taskListRefreshIntervalUserSetting) ? Long.parseLong(taskListRefreshIntervalUserSetting) : DEFAULT_TASK_LIST_REFRESH_INTERVAL; @@ -62,7 +61,7 @@ public TaskWidgetBean() { .equals(BehaviourWhenClickingOnLineInTaskList.RUN_TASK.name()); } - public void preRender(TaskLazyDataModel dataModel) {} + public void preRender(@SuppressWarnings("unused") TaskLazyDataModel dataModel) {} public Long getExpandedTaskId() { return expandedTaskId; diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bo/ExternalLinkProcessItem.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bo/ExternalLinkProcessItem.java index cfea912f826..a24f681484b 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bo/ExternalLinkProcessItem.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/bo/ExternalLinkProcessItem.java @@ -17,7 +17,7 @@ */ public class ExternalLinkProcessItem implements Process { - public static final String DEFAULT_ICON = "si si-hyperlink-3"; + public static final String DEFAULT_ICON = "si-hyperlink-3"; private ExternalLink externalLink; public ExternalLinkProcessItem(ExternalLink externalLink) { diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/casefilter/impl/CaseApplicationFilter.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/casefilter/impl/CaseApplicationFilter.java index 86fcc4f192c..be57cf38e0e 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/casefilter/impl/CaseApplicationFilter.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/casefilter/impl/CaseApplicationFilter.java @@ -25,7 +25,7 @@ public class CaseApplicationFilter extends CaseFilter { private boolean isSelectedAll; public CaseApplicationFilter() { - this.filteredApplications = IApplicationRepository.instance().allOf(ISecurityContext.current()).stream().map(IApplication::getName).collect(Collectors.toList()); + this.filteredApplications = IApplicationRepository.of(ISecurityContext.current()).all().stream().map(IApplication::getName).collect(Collectors.toList()); this.selectedFilteredApplications = new ArrayList<>(); } @@ -61,7 +61,7 @@ public CaseQuery buildQuery() { CaseQuery query = CaseUtils.createBusinessCaseQuery(); IFilterQuery filterQuery = query.where(); selectedFilteredApplications.forEach(applicationName -> { - final List allApps = IApplicationRepository.instance().allOf(ISecurityContext.current()); + final List allApps = IApplicationRepository.of(ISecurityContext.current()).all(); for (IApplication app : allApps) { if (app.getName().equals(applicationName)) { filterQuery.or().applicationId().isEqual(app.getId()); diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/comparator/NoteComparator.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/comparator/NoteComparator.java index 6fcf772aa1a..633f379d948 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/comparator/NoteComparator.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/comparator/NoteComparator.java @@ -2,13 +2,13 @@ import java.util.Comparator; -import ch.ivyteam.ivy.workflow.INote; +import ch.ivyteam.ivy.workflow.note.Note; -public class NoteComparator implements Comparator { +public class NoteComparator implements Comparator { @Override - public int compare(INote o1, INote o2) { - return o2.getCreationTimestamp().compareTo(o1.getCreationTimestamp()); + public int compare(Note o1, Note o2) { + return o2.createdAt().compareTo(o1.createdAt()); } } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/constant/CustomFields.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/constant/CustomFields.java index 20ea8f8fadb..e66a258906f 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/constant/CustomFields.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/constant/CustomFields.java @@ -2,7 +2,7 @@ public class CustomFields { - @Deprecated(forRemoval = true, since = "9.4") + @Deprecated(since = "9.4") public static final String CUSTOM_TIMESTAMP_FIELD5 = "CustomTimestampField5"; public static final String EMBED_IN_FRAME = "embedInFrame"; diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/constant/IvyCacheIdentifier.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/constant/IvyCacheIdentifier.java index 447e29ade61..cdd17232a67 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/constant/IvyCacheIdentifier.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/constant/IvyCacheIdentifier.java @@ -8,7 +8,9 @@ public final class IvyCacheIdentifier { public static final String STATISTIC_COLOR = "STATISTIC_COLOR"; public static final String ROLES_IN_SECURITY_CONTEXT = "ROLES_IN_SECURITY_CONTEXT"; public static final String PORTAL_MENU = "PORTAL_MENU"; + public static final String PORTAL_CUSTOM_MENU = "PORTAL_CUSTOM_MENU"; public static final String PORTAL_DASHBOARDS = "PORTAL_DASHBOARDS"; + public static final String PORTAL_DASHBOARDS_MENU_ITEM = "PORTAL_DASHBOARDS_MENU_ITEM"; // for caching locales public static final String PORTAL_CONTENT_LOCALES = "PORTAL_CONTENT_LOCALES"; diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/constant/UserProperty.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/constant/UserProperty.java index 49ab620ccae..b50ee72983b 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/constant/UserProperty.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/constant/UserProperty.java @@ -3,11 +3,7 @@ public class UserProperty { public static final String HOMEPAGE = "HOMEPAGE"; - public static final String DEFAULT_SORT_FIELD_OF_TASK_LIST = "DEFAULT_SORT_FIELD_OF_TASK_LIST"; - public static final String DEFAULT_SORT_DIRECTION_OF_TASK_LIST = "DEFAULT_SORT_DIRECTION_OF_TASK_LIST"; public static final String DEFAULT_TASK_BEHAVIOUR_WHEN_CLICKING_ON_LINE_IN_TASK_LIST = "DEFAULT_TASK_BEHAVIOUR_WHEN_CLICKING_ON_LINE_IN_TASK_LIST"; - public static final String DEFAULT_SORT_FIELD_OF_CASE_LIST = "DEFAULT_SORT_FIELD_OF_CASE_LIST"; - public static final String DEFAULT_SORT_DIRECTION_OF_CASE_LIST = "DEFAULT_SORT_DIRECTION_OF_CASE_LIST"; public static final String RESET_PASSWORD_TOKEN = "RESET_PASSWORD_TOKEN"; public static final String RESET_PASSWORD_TOKEN_EXPIRY = "RESET_PASSWORD_TOKEN_EXPIRY"; public static final String ENABLE_CUSTOM_MAIL = "useCustomMails"; diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/datamodel/CaseLazyDataModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/datamodel/CaseLazyDataModel.java index 8036394dc20..83134a3b1e4 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/datamodel/CaseLazyDataModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/datamodel/CaseLazyDataModel.java @@ -31,9 +31,8 @@ import ch.ivy.addon.portalkit.constant.PortalConstants; import ch.ivy.addon.portalkit.enums.CaseSortField; import ch.ivy.addon.portalkit.enums.FilterType; -import ch.ivy.addon.portalkit.enums.GlobalVariable; +import ch.ivy.addon.portalkit.enums.SortDirection; import ch.ivy.addon.portalkit.ivydata.searchcriteria.CaseSearchCriteria; -import ch.ivy.addon.portalkit.ivydata.service.impl.UserSettingService; import ch.ivy.addon.portalkit.jsf.Attrs; import ch.ivy.addon.portalkit.service.CaseColumnsConfigurationService; import ch.ivy.addon.portalkit.service.CaseFilterService; @@ -128,7 +127,7 @@ public CaseFilterData buildDefaultCaseFilterData() { } public void updateDisableCaseCount() { - disableCaseCount = GlobalSettingService.getInstance().findGlobalSettingValueAsBoolean(GlobalVariable.DISABLE_CASE_COUNT); + disableCaseCount = false; } @Override @@ -449,23 +448,11 @@ private void buildSort() { } private String getDefaultSortField() { - String defaultSortField = UserSettingService.newInstance().getDefaultSortFieldOfCaseList(); - if (StringUtils.isBlank(defaultSortField) || UserSettingService.DEFAULT.equals(defaultSortField)) { - GlobalSettingService globalSettingService = GlobalSettingService.getInstance(); - defaultSortField = globalSettingService.findGlobalSettingValue(GlobalVariable.DEFAULT_SORT_FIELD_OF_CASE_LIST); - } - return defaultSortField; + return CaseSortField.ID.name(); // set default value instead of variable } private boolean isSortedDescendingByDefault() { - String defaultSortDirection = UserSettingService.newInstance().getDefaultSortDirectionOfCaseList(); - if (StringUtils.isBlank(defaultSortDirection) || UserSettingService.DEFAULT.equals(defaultSortDirection)) { - GlobalSettingService globalSettingService = GlobalSettingService.getInstance(); - defaultSortDirection = - globalSettingService.findGlobalSettingValue(GlobalVariable.DEFAULT_SORT_DIRECTION_OF_CASE_LIST); - } - - return !SortFieldUtil.isAscendingSort(defaultSortDirection); + return !SortFieldUtil.isAscendingSort(SortDirection.DESC.name()); } private void applyCustomSettings(CaseFilterData caseFilterData) { diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/datamodel/TaskLazyDataModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/datamodel/TaskLazyDataModel.java index 9ac6bfc3d11..6fd29c119fb 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/datamodel/TaskLazyDataModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/datamodel/TaskLazyDataModel.java @@ -26,13 +26,11 @@ import ch.ivy.addon.portalkit.bo.TaskColumnsConfiguration; import ch.ivy.addon.portalkit.constant.PortalConstants; import ch.ivy.addon.portalkit.enums.FilterType; -import ch.ivy.addon.portalkit.enums.GlobalVariable; +import ch.ivy.addon.portalkit.enums.SortDirection; import ch.ivy.addon.portalkit.enums.TaskAssigneeType; import ch.ivy.addon.portalkit.enums.TaskSortField; import ch.ivy.addon.portalkit.ivydata.searchcriteria.TaskSearchCriteria; -import ch.ivy.addon.portalkit.ivydata.service.impl.UserSettingService; import ch.ivy.addon.portalkit.jsf.Attrs; -import ch.ivy.addon.portalkit.service.GlobalSettingService; import ch.ivy.addon.portalkit.service.TaskColumnsConfigurationService; import ch.ivy.addon.portalkit.service.TaskFilterService; import ch.ivy.addon.portalkit.taskfilter.TaskFilter; @@ -140,7 +138,7 @@ public TaskLazyDataModel() { } public void updateDisableTaskCount() { - disableTaskCount = GlobalSettingService.getInstance().findGlobalSettingValueAsBoolean(GlobalVariable.DISABLE_TASK_COUNT); + disableTaskCount = false; // set default value instead of variable } /** @@ -318,23 +316,11 @@ protected void buildCriteria() { } private String getDefaultSortField() { - String defaultSortField = UserSettingService.newInstance().getDefaultSortFieldOfTaskList(); - if (StringUtils.isBlank(defaultSortField) || UserSettingService.DEFAULT.equals(defaultSortField)) { - GlobalSettingService globalSettingService = GlobalSettingService.getInstance(); - defaultSortField = globalSettingService.findGlobalSettingValue(GlobalVariable.DEFAULT_SORT_FIELD_OF_TASK_LIST); - } - return defaultSortField; + return TaskSortField.ID.name(); } private boolean isSortedDescendingByDefault() { - String defaultSortDirection = UserSettingService.newInstance().getDefaultSortDirectionOfTaskList(); - if (StringUtils.isBlank(defaultSortDirection) || UserSettingService.DEFAULT.equals(defaultSortDirection)) { - GlobalSettingService globalSettingService = GlobalSettingService.getInstance(); - defaultSortDirection = - globalSettingService.findGlobalSettingValue(GlobalVariable.DEFAULT_SORT_DIRECTION_OF_TASK_LIST); - } - - return !SortFieldUtil.isAscendingSort(defaultSortDirection); + return !SortFieldUtil.isAscendingSort(SortDirection.DESC.name()); } /** diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/datamodel/internal/RelatedTaskLazyDataModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/datamodel/internal/RelatedTaskLazyDataModel.java index e27434583e5..9e354ecfb9b 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/datamodel/internal/RelatedTaskLazyDataModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/datamodel/internal/RelatedTaskLazyDataModel.java @@ -60,13 +60,21 @@ private void updateCriteria() { criteria.setSortDescending(false); this.getCriteria().setKeyword(StringUtils.EMPTY); this.setQueryByBusinessCaseId(true); - boolean isOwner = iCase != null && iCase.getOwner() != null ? iCase.getOwner().isMember(Ivy.session(), true) : false; + boolean isOwner = isCaseOwnerUser(iCase); this.setAdminQuery(PermissionUtils.checkReadAllTasksPermission() || PermissionUtils.checkTaskReadOwnCaseTasksPermission() || isOwner); if (HiddenTasksCasesConfig.isHiddenTasksCasesExcluded()) { criteria.setCustomTaskQuery(TaskQuery.create().where().customField().stringField(AdditionalProperty.HIDE.toString()).isNull()); } } + + private boolean isCaseOwnerUser(ICase caze) { + return caze != null && caze.owners() != null && caze + .owners() + .all() + .stream() + .anyMatch(item -> item.member().isMember(Ivy.session(), true)); + } @Override public List load(int first, int pageSize, Map sortBy, Map filterBy) { diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/TaskEndInfo.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/TaskEndInfo.java index ce2925df090..649ac1dcfbc 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/TaskEndInfo.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/TaskEndInfo.java @@ -10,6 +10,7 @@ public class TaskEndInfo { private NavigationHistory navigationHistory; private PortalPage portalPage; private Boolean isStartedInTaskDetails; + private String dashboardId; // used if main menu public TaskLazyDataModel getDataModel() { return dataModel; @@ -42,5 +43,14 @@ public Boolean getIsStartedInTaskDetails() { public void setIsStartedInTaskDetails(Boolean isStartedInTaskDetails) { this.isStartedInTaskDetails = isStartedInTaskDetails; } + + public String getDashboardId() { + return dashboardId; + } + + public void setDashboardId(String dashboardId) { + this.dashboardId = dashboardId; + } + } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/AbstractColumn.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/AbstractColumn.java index 574afbc3686..63858d48a91 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/AbstractColumn.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/AbstractColumn.java @@ -11,6 +11,7 @@ import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; @@ -33,13 +34,17 @@ public abstract class AbstractColumn implements Serializable { private static final long serialVersionUID = -8430449835327597359L; @JsonIgnore - public static final String TINY_WIDTH = "width: 80px"; + private static final String DEFAULT_WIDTH_UNIT = "px"; @JsonIgnore - public static final String SMALL_WIDTH = "width: 100px"; + public static final int TINY_WIDTH = 80; @JsonIgnore - public static final String NORMAL_WIDTH = "width: 120px"; + public static final int SMALL_WIDTH = 100; @JsonIgnore - public static final String EXTRA_WIDTH = "width: 150px"; + public static final int NORMAL_WIDTH = 120; + @JsonIgnore + public static final int EXTRA_WIDTH = 150; + @JsonIgnore + public static final int LARGE_WIDTH = 200; @Deprecated(since = "10.0", forRemoval = true) @JsonProperty(access = Access.WRITE_ONLY) @@ -77,6 +82,10 @@ public abstract class AbstractColumn implements Serializable { protected Date userDateFilterFrom; protected Date userDateFilterTo; protected List userFilterListOptions; + protected String width; + + @JsonIgnore + protected String styleToDisplay; public void initDefaultValue() { if (isNull(this.visible)) { @@ -100,6 +109,11 @@ public void initDefaultValue() { if (isNull(this.userFilterList)) { this.userFilterList = new ArrayList<>(); } + if (isNull(this.style)) { + this.style = getDefaultStyle(); + } + + this.styleToDisplay = initDefaultStyle(); } @JsonIgnore @@ -129,7 +143,7 @@ public String getDefaultHeaderCMS() { @JsonIgnore public String getDefaultStyle() { - return SMALL_WIDTH; + return ""; } @JsonIgnore @@ -330,6 +344,25 @@ public String getUserFilterTo() { public void setUserFilterTo(String userFilterTo) { this.userFilterTo = userFilterTo; } + + public String getWidth() { + return width; + } + + public void setWidth(String width) { + this.width = width; + } + + @JsonIgnore + public String getStyleToDisplay() { + return styleToDisplay; + } + + @JsonIgnore + public void setStyleToDisplay(String styleToDisplay) { + this.styleToDisplay = styleToDisplay; + } + @JsonIgnore public String getHeaderText() { @@ -417,6 +450,27 @@ public void resetUserFilter() { setUserDateFilterFrom(null); setUserDateFilterTo(null); } + + @JsonIgnore + protected int getDefaultColumnWidth() { + return SMALL_WIDTH; + } + + @JsonIgnore + protected int resolveColumnWidth() { + return NumberUtils.toInt(width, getDefaultColumnWidth()); + } + + @JsonIgnore + protected String initDefaultWidth() { + return "width: " + resolveColumnWidth() + "px"; + } + + @JsonIgnore + public String initDefaultStyle() { + return String.join(";", initDefaultWidth(), + StringUtils.defaultIfBlank(this.style, "")); + } @JsonIgnore public Boolean getIsCustomAction() { diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/CaseDashboardWidget.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/CaseDashboardWidget.java index e140b7980e3..82bfb5d720f 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/CaseDashboardWidget.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/CaseDashboardWidget.java @@ -31,7 +31,6 @@ public class CaseDashboardWidget extends DashboardWidget { private static final long serialVersionUID = 3048837559125720787L; - private int rowsPerPage = 5; @JsonIgnore private DashboardCaseLazyDataModel dataModel; @JsonIgnore @@ -192,14 +191,6 @@ public DashboardWidgetType getType() { return DashboardWidgetType.CASE; } - public int getRowsPerPage() { - return rowsPerPage; - } - - public void setRowsPerPage(int rowsPerPage) { - this.rowsPerPage = rowsPerPage; - } - public List getFilters() { return this.dataModel.getCriteria().getFilters(); } @@ -234,12 +225,17 @@ public void setUserFilters(List userFilters) { this.dataModel.getCriteria().setUserFilters(userFilters); } + @Override @JsonIgnore public void loadUserFilter() { updateSavedFiltersSelection(); // Don't load user filters when already loaded from session - if (CollectionUtils.isNotEmpty(getUserFilters())) { + List userFilters = getUserFilters(); + if (CollectionUtils.isNotEmpty(userFilters)) { + // Clear temporary filters + setUserFilters(userFilters.stream().filter(filter -> !filter.isTemp()) + .collect(Collectors.toList())); return; } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/Dashboard.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/Dashboard.java index 38961a8b822..0896ec2dc67 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/Dashboard.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/Dashboard.java @@ -33,8 +33,12 @@ public class Dashboard extends AbstractConfiguration implements Serializable { private List permissionDTOs; @JsonIgnore private String displayedPermission; + private Boolean isTopMenu; - public Dashboard() {} + public Dashboard() { + // Set default values + isTopMenu = false; + } public Dashboard(Dashboard dashboard) { setId(dashboard.getId()); @@ -49,8 +53,9 @@ public Dashboard(Dashboard dashboard) { permissions = dashboard.permissions; permissionDTOs = dashboard.permissionDTOs; displayedPermission = dashboard.displayedPermission; + isTopMenu = dashboard.isTopMenu; } - + public String getTitle() { return LanguageUtils.getLocalizedName(titles, title); } @@ -133,6 +138,14 @@ public void setTemplateId(String templateId) { this.templateId = templateId; } + public Boolean getIsTopMenu() { + return isTopMenu; + } + + public void setIsTopMenu(Boolean isTopMenu) { + this.isTopMenu = isTopMenu; + } + @Override public int hashCode() { final int prime = 31; diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/TaskDashboardWidget.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/TaskDashboardWidget.java index 1ffa9bfd5c1..8fe651d2aca 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/TaskDashboardWidget.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/TaskDashboardWidget.java @@ -32,7 +32,6 @@ public class TaskDashboardWidget extends DashboardWidget { private static final long serialVersionUID = 3246735956282078091L; protected static final String LIKE_FORMAT = "%%%s%%"; - private int rowsPerPage = 5; @JsonIgnore private DashboardTaskLazyDataModel dataModel; @JsonIgnore @@ -49,6 +48,9 @@ public class TaskDashboardWidget extends DashboardWidget { private boolean showWidgetInfo; private boolean showFullscreenMode; + @JsonIgnore + private List errors; + public TaskDashboardWidget() { dataModel = new DashboardTaskLazyDataModel(); setColumns(new ArrayList<>()); @@ -200,14 +202,6 @@ public DashboardWidgetType getType() { return DashboardWidgetType.TASK; } - public int getRowsPerPage() { - return isInConfiguration() ? 5 : rowsPerPage; - } - - public void setRowsPerPage(int rowsPerPage) { - this.rowsPerPage = rowsPerPage; - } - @Override public void setQuickSearchKeyword() { if (BooleanUtils.isTrue(this.enableQuickSearch)) { @@ -259,12 +253,17 @@ public boolean isShowFullscreenMode() { return showFullscreenMode; } + @Override @JsonIgnore public void loadUserFilter() { updateSavedFiltersSelection(); // Don't load user filters when already loaded from session - if (CollectionUtils.isNotEmpty(getUserFilters())) { + List userFilters = getUserFilters(); + if (CollectionUtils.isNotEmpty(userFilters)) { + // Clear temporary filters + setUserFilters(userFilters.stream().filter(filter -> !filter.isTemp()) + .collect(Collectors.toList())); return; } @@ -294,4 +293,12 @@ public void cancelUserFilter() { setUserFilters(getUserFilters().stream().filter(filter -> !filter.isTemp()).collect(Collectors.toList())); } + +public List getErrors() { + return errors; +} + +public void setErrors(List errors) { + this.errors = errors; +} } \ No newline at end of file diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/ActionsColumnModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/ActionsColumnModel.java index 1af592e30c5..4893847e441 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/ActionsColumnModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/ActionsColumnModel.java @@ -14,7 +14,7 @@ public class ActionsColumnModel extends CaseColumnModel implements Serializable public void initDefaultValue() { super.initDefaultValue(); this.field = DashboardStandardCaseColumn.ACTIONS.getField(); - this.style = defaultIfEmpty(this.style, getDefaultStyle()); + this.styleToDisplay = initDefaultStyle(); this.styleClass = defaultIfEmpty(this.styleClass, getDefaultStyleClass()); this.sortable = getDefaultSortable(); this.format = getDefaultFormat(); @@ -35,11 +35,6 @@ public Boolean getDefaultSortable() { return false; } - @Override - public String getDefaultStyle() { - return SMALL_WIDTH; - } - @Override public String getDefaultStyleClass() { return "dashboard-cases__actions u-text-align-center"; diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/ApplicationColumnModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/ApplicationColumnModel.java index b96efb7e8e0..5173f155081 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/ApplicationColumnModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/ApplicationColumnModel.java @@ -23,7 +23,7 @@ public class ApplicationColumnModel extends CaseColumnModel implements Serializa public void initDefaultValue() { super.initDefaultValue(); this.field = DashboardStandardCaseColumn.APPLICATION.getField(); - this.style = defaultIfEmpty(this.style, TINY_WIDTH); + this.styleToDisplay = initDefaultStyle(); this.styleClass = defaultIfEmpty(this.styleClass, "dashboard-tasks__priority u-text-align-center"); this.format = DashboardColumnFormat.CUSTOM; this.quickSearch = defaultIfEmpty(this.quickSearch, false); @@ -44,7 +44,7 @@ public Object display(ICase iCase) { @JsonIgnore public List getApplications() { - return ListUtilities.transformList(IApplicationRepository.instance().allOf(ISecurityContext.current()), IApplication::getName); + return ListUtilities.transformList(IApplicationRepository.of(ISecurityContext.current()).all(), IApplication::getName); } @JsonIgnore diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/CategoryColumnModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/CategoryColumnModel.java index fb28b4766d2..3b23b9cb2fe 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/CategoryColumnModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/CategoryColumnModel.java @@ -34,7 +34,7 @@ public class CategoryColumnModel extends CaseColumnModel { public void initDefaultValue() { super.initDefaultValue(); this.field = DashboardStandardTaskColumn.CATEGORY.getField(); - this.style = defaultIfEmpty(this.style, getDefaultStyle()); + this.styleToDisplay = initDefaultStyle(); this.styleClass = defaultIfEmpty(this.styleClass, getDefaultStyleClass()); this.format = getDefaultFormat(); this.sortable = getDefaultSortable(); @@ -56,11 +56,6 @@ public Boolean getDefaultSortable() { return false; } - @Override - public String getDefaultStyle() { - return NORMAL_WIDTH; - } - @Override public boolean canQuickSearch() { return true; diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/CreatedDateColumnModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/CreatedDateColumnModel.java index fd62916befe..37addfd8679 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/CreatedDateColumnModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/CreatedDateColumnModel.java @@ -26,7 +26,7 @@ public class CreatedDateColumnModel extends CaseColumnModel implements Serializa public void initDefaultValue() { super.initDefaultValue(); this.field = DashboardStandardCaseColumn.CREATED.getField(); - this.style = defaultIfEmpty(this.style, getDefaultStyle()); + this.styleToDisplay = initDefaultStyle(); this.styleClass = defaultIfEmpty(this.styleClass, getDefaultStyleClass()); this.format = getDefaultFormat(); } @@ -41,11 +41,6 @@ public DashboardColumnFormat getDefaultFormat() { return DashboardColumnFormat.TIMESTAMP; } - @Override - public String getDefaultStyle() { - return SMALL_WIDTH; - } - @Override public String getDefaultStyleClass() { return "dashboard-cases__created-date u-text-align-center"; diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/CreatorColumnModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/CreatorColumnModel.java index e6ca6cf97b7..363010077a0 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/CreatorColumnModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/CreatorColumnModel.java @@ -30,7 +30,7 @@ public void initDefaultValue() { this.setVisible(!GlobalSettingService.getInstance().isHideCaseCreator()); super.initDefaultValue(); this.field = DashboardStandardCaseColumn.CREATOR.getField(); - this.style = defaultIfEmpty(this.style, getDefaultStyle()); + this.styleToDisplay = initDefaultStyle(); this.format = getDefaultFormat(); this.styleClass = defaultIfEmpty(this.styleClass, getDefaultStyleClass()); this.quickSearch = defaultIfEmpty(this.quickSearch, false); @@ -47,7 +47,8 @@ public DashboardColumnFormat getDefaultFormat() { } @Override - public String getDefaultStyle() { + @JsonIgnore + protected int getDefaultColumnWidth() { return EXTRA_WIDTH; } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/DescriptionColumnModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/DescriptionColumnModel.java index 8f41a0af849..0456a0a4582 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/DescriptionColumnModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/DescriptionColumnModel.java @@ -13,7 +13,7 @@ public class DescriptionColumnModel extends CaseColumnModel implements Serializa public void initDefaultValue() { super.initDefaultValue(); this.field = DashboardStandardCaseColumn.DESCRIPTION.getField(); - this.style = defaultIfEmpty(this.style, getDefaultStyle()); + this.styleToDisplay = initDefaultStyle(); this.styleClass = defaultIfEmpty(this.styleClass, getDefaultStyleClass()); this.sortable = defaultIfEmpty(this.sortable, getDefaultSortable()); this.quickSearch = defaultIfEmpty(this.quickSearch, true); @@ -30,8 +30,8 @@ public Boolean getDefaultSortable() { } @Override - public String getDefaultStyle() { - return "width: 200px"; + protected int getDefaultColumnWidth() { + return 200; } @Override diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/FinishedDateColumnModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/FinishedDateColumnModel.java index c472f3709f4..23248b9e6bb 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/FinishedDateColumnModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/FinishedDateColumnModel.java @@ -28,6 +28,7 @@ public void initDefaultValue() { this.field = DashboardStandardCaseColumn.FINISHED.getField(); this.styleClass = defaultIfEmpty(this.styleClass, getDefaultStyleClass()); this.format = getDefaultFormat(); + this.styleToDisplay = initDefaultStyle(); } @Override diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/IdColumnModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/IdColumnModel.java index 076d7ee5550..508dac24a42 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/IdColumnModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/IdColumnModel.java @@ -15,6 +15,7 @@ public void initDefaultValue() { this.field = DashboardStandardCaseColumn.ID.getField(); this.styleClass = defaultIfEmpty(this.styleClass, getDefaultStyleClass()); this.quickSearch = defaultIfEmpty(this.quickSearch, false); + this.styleToDisplay = initDefaultStyle(); } @Override diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/NameColumnModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/NameColumnModel.java index 8da735ca756..d14b6ba692a 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/NameColumnModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/NameColumnModel.java @@ -16,6 +16,12 @@ public void initDefaultValue() { this.field = DashboardStandardCaseColumn.NAME.getField(); this.styleClass = defaultIfEmpty(this.styleClass, getDefaultStyleClass()); this.quickSearch = defaultIfEmpty(this.quickSearch, true); + this.styleToDisplay = initDefaultStyle(); + } + + @Override + protected int getDefaultColumnWidth() { + return 200; } @Override diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/OwnerColumnModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/OwnerColumnModel.java index 688116c632f..c5ea811f154 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/OwnerColumnModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/OwnerColumnModel.java @@ -17,7 +17,6 @@ import ch.ivy.addon.portalkit.ivydata.utils.ServiceUtilities; import ch.ivy.addon.portalkit.util.SecurityMemberDisplayNameUtils; import ch.ivy.addon.portalkit.util.SecurityMemberUtils; -import ch.ivyteam.ivy.security.ISecurityMember; import ch.ivyteam.ivy.workflow.ICase; public class OwnerColumnModel extends CaseColumnModel implements Serializable { @@ -28,7 +27,7 @@ public class OwnerColumnModel extends CaseColumnModel implements Serializable { public void initDefaultValue() { super.initDefaultValue(); this.field = DashboardStandardCaseColumn.OWNER.getField(); - this.style = defaultIfEmpty(this.style, getDefaultStyle()); + this.styleToDisplay = initDefaultStyle(); this.format = getDefaultFormat(); this.styleClass = defaultIfEmpty(this.styleClass, getDefaultStyleClass()); } @@ -44,7 +43,7 @@ public DashboardColumnFormat getDefaultFormat() { } @Override - public String getDefaultStyle() { + protected int getDefaultColumnWidth() { return EXTRA_WIDTH; } @@ -55,11 +54,10 @@ public String getDefaultStyleClass() { @Override public Object display(ICase caze) { - if (caze == null || caze.getOwner() == null) { + if (caze == null || CollectionUtils.isEmpty(caze.owners().all())) { return StringUtils.EMPTY; } - ISecurityMember member = caze.getOwner(); - return SecurityMemberDisplayNameUtils.generateBriefDisplayNameForSecurityMember(member, member.getMemberName()); + return SecurityMemberDisplayNameUtils.generateBriefDisplayNameForCaseOwners(caze.owners()); } @JsonIgnore @@ -71,9 +69,9 @@ public List getOwners() { public void setOwners(List owner) { if (owner != null) { this.filterList = owner.stream().map(SecurityMemberDTO::getMemberName).collect(Collectors.toList()); - } else { - this.filterList = new ArrayList<>(); - } + return; + } + this.filterList = new ArrayList<>(); } @JsonIgnore @@ -85,9 +83,9 @@ public List getUserFilterOwners() { public void setUserFilterOwners(List owners) { if (owners != null) { this.userFilterList = owners.stream().map(SecurityMemberDTO::getMemberName).collect(Collectors.toList()); - } else { - this.userFilterList = new ArrayList<>(); - } + return; + } + this.userFilterList = new ArrayList<>(); } public List completeUserFilterOwners(String query) { @@ -111,4 +109,10 @@ private List toSecurityMemberDTOs(List filters, Strin private SecurityMemberDTO findSecurityMember(String memberName) { return ServiceUtilities.findSecurityMemberByName(memberName); } + + @Override + public Boolean getDefaultSortable() { + return false; + } + } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/StateColumnModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/StateColumnModel.java index db8e14a01c8..e911efd6b80 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/StateColumnModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/casecolumn/StateColumnModel.java @@ -23,7 +23,7 @@ public class StateColumnModel extends CaseColumnModel implements Serializable { public void initDefaultValue() { super.initDefaultValue(); this.field = DashboardStandardCaseColumn.STATE.getField(); - this.style = defaultIfEmpty(this.style, getDefaultStyle()); + this.styleToDisplay = initDefaultStyle(); this.styleClass = defaultIfEmpty(this.styleClass, getDefaultStyleClass()); this.format = getDefaultFormat(); } @@ -39,7 +39,7 @@ public DashboardColumnFormat getDefaultFormat() { } @Override - public String getDefaultStyle() { + protected int getDefaultColumnWidth() { return NORMAL_WIDTH; } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/process/ApplicationColumnModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/process/ApplicationColumnModel.java index cb10266dd73..36fd5674d85 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/process/ApplicationColumnModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/process/ApplicationColumnModel.java @@ -17,7 +17,6 @@ import ch.ivy.addon.portalkit.dto.dashboard.ProcessDashboardWidget; import ch.ivy.addon.portalkit.dto.dashboard.SingleProcessDashboardWidget; import ch.ivy.addon.portalkit.enums.DashboardColumnFormat; -import ch.ivy.addon.portalkit.enums.DashboardStandardProcessColumn; import ch.ivy.addon.portalkit.enums.ProcessWidgetMode; import ch.ivy.addon.portalkit.jsf.ManagedBeans; import ch.ivy.addon.portalkit.util.ListUtilities; @@ -31,8 +30,9 @@ public class ApplicationColumnModel extends ProcessColumnModel implements Serial @Override public void initDefaultValue() { super.initDefaultValue(); - this.field = DashboardStandardProcessColumn.APPLICATION.getField(); - this.style = defaultIfEmpty(this.style, TINY_WIDTH); + this.styleToDisplay = initDefaultStyle(); + this.styleClass = defaultIfEmpty(this.styleClass, + "dashboard-tasks__priority u-text-align-center widget-column"); this.styleClass = defaultIfEmpty(this.styleClass, "dashboard-tasks__priority u-text-align-center"); this.format = DashboardColumnFormat.CUSTOM; } @@ -44,7 +44,7 @@ public String getDefaultHeaderCMS() { @JsonIgnore public List getApplications() { - return ListUtilities.transformList(IApplicationRepository.instance().allOf(ISecurityContext.current()), IApplication::getName); + return ListUtilities.transformList(IApplicationRepository.of(ISecurityContext.current()).all(), IApplication::getName); } @JsonIgnore @@ -57,6 +57,11 @@ public Boolean getDefaultSortable() { return false; } + @Override + protected int getDefaultColumnWidth() { + return TINY_WIDTH; + } + public void initializeApplications(ProcessDashboardWidget widget) { if (widget == null) { return; @@ -89,10 +94,10 @@ public void updateApplications(ProcessDashboardWidget widget) { if (widget instanceof CompactProcessDashboardWidget) { ((CompactProcessDashboardWidget) widget).setProcesses(null); - final List filterableColumns = ((CompactProcessDashboardWidget) widget).getFilterableColumns(); + final List filterableColumns = widget.getFilterableColumns(); for (ColumnModel column : filterableColumns) { if (column instanceof CategoryColumnModel) { - ((CategoryColumnModel) column).setFilterList(new ArrayList<>()); + column.setFilterList(new ArrayList<>()); ((CategoryColumnModel) column).setSelectionCategoryNodes(null); } } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/process/DashboardProcess.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/process/DashboardProcess.java index 3bd179fc83c..5809a8ef854 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/process/DashboardProcess.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/process/DashboardProcess.java @@ -210,4 +210,8 @@ public void setProcessElementId(String processElementId) { public String getPortalProcessInformation() { return portalProcessInformation; } + + public String getDefaultImageDarkLink() { + return getContentImageUrl(DefaultImage.PROCESSMODELINGDARK.getPath()); + } } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/process/DescriptionColumnModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/process/DescriptionColumnModel.java new file mode 100644 index 00000000000..11db9b89e2a --- /dev/null +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/process/DescriptionColumnModel.java @@ -0,0 +1,24 @@ +package ch.ivy.addon.portalkit.dto.dashboard.process; + +import java.io.Serializable; + +import com.fasterxml.jackson.annotation.JsonInclude; + +import ch.ivy.addon.portalkit.enums.DashboardStandardProcessColumn; + +@JsonInclude(JsonInclude.Include.NON_EMPTY) +public class DescriptionColumnModel extends ProcessColumnModel implements Serializable { + + private static final long serialVersionUID = -327372992675183938L; + + @Override + public void initDefaultValue() { + super.initDefaultValue(); + this.field = DashboardStandardProcessColumn.DESCRIPTION.getField(); + } + + @Override + public String getDefaultHeaderCMS() { + return "/ch.ivy.addon.portalkit.ui.jsf/common/description"; + } +} diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/ActionsColumnModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/ActionsColumnModel.java index c0980be70b8..3c2ca6e4ba3 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/ActionsColumnModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/ActionsColumnModel.java @@ -13,10 +13,10 @@ public class ActionsColumnModel extends TaskColumnModel implements Serializable public void initDefaultValue() { super.initDefaultValue(); this.field = DashboardStandardTaskColumn.ACTIONS.getField(); - this.style = defaultIfEmpty(this.style, getDefaultStyle()); - this.styleClass = defaultIfEmpty(this.styleClass, getDefaultStyleClass()); + this.styleToDisplay = initDefaultStyle(); this.sortable = defaultIfEmpty(this.sortable, getDefaultSortable()); this.format = getDefaultFormat(); + this.styleClass = defaultIfEmpty(this.styleClass, getDefaultStyleClass()); } @Override @@ -28,19 +28,19 @@ public String getDefaultHeaderCMS() { public DashboardColumnFormat getDefaultFormat() { return DashboardColumnFormat.CUSTOM; } - + @Override - public Boolean getDefaultSortable() { - return false; + public int getDefaultColumnWidth() { + return TINY_WIDTH; } @Override - public String getDefaultStyle() { - return SMALL_WIDTH; + public Boolean getDefaultSortable() { + return false; } @Override public String getDefaultStyleClass() { - return "dashboard-tasks__actions u-text-align-center"; + return "dashboard-tasks__actions u-text-align-center widget-column"; } } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/ApplicationColumnModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/ApplicationColumnModel.java index 66a55beec64..89064f0b89f 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/ApplicationColumnModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/ApplicationColumnModel.java @@ -23,8 +23,8 @@ public class ApplicationColumnModel extends TaskColumnModel implements Serializa public void initDefaultValue() { super.initDefaultValue(); this.field = DashboardStandardTaskColumn.APPLICATION.getField(); - this.style = defaultIfEmpty(this.style, TINY_WIDTH); - this.styleClass = defaultIfEmpty(this.styleClass, "dashboard-tasks__priority u-text-align-center"); + this.styleToDisplay = initDefaultStyle(); + this.styleClass = defaultIfEmpty(this.styleClass, "dashboard-tasks__priority u-text-align-center widget-column"); this.format = DashboardColumnFormat.CUSTOM; this.quickSearch = defaultIfEmpty(this.quickSearch, false); } @@ -34,6 +34,11 @@ public String getDefaultHeaderCMS() { return "/ch.ivy.addon.portalkit.ui.jsf/taskList/defaultColumns/APPLICATION"; } + @Override + protected int getDefaultColumnWidth() { + return TINY_WIDTH; + } + @Override public Object display(ITask task) { if (task == null) { @@ -44,7 +49,7 @@ public Object display(ITask task) { @JsonIgnore public List getApplications() { - return ListUtilities.transformList(IApplicationRepository.instance().allOf(ISecurityContext.current()), IApplication::getName); + return ListUtilities.transformList(IApplicationRepository.of(ISecurityContext.current()).all(), IApplication::getName); } @JsonIgnore diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/CategoryColumnModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/CategoryColumnModel.java index f82b04310e4..a178f4d55b7 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/CategoryColumnModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/CategoryColumnModel.java @@ -34,7 +34,7 @@ public class CategoryColumnModel extends TaskColumnModel { public void initDefaultValue() { super.initDefaultValue(); this.field = DashboardStandardTaskColumn.CATEGORY.getField(); - this.style = defaultIfEmpty(this.style, getDefaultStyle()); + this.styleToDisplay = initDefaultStyle(); this.styleClass = defaultIfEmpty(this.styleClass, getDefaultStyleClass()); this.format = getDefaultFormat(); this.sortable = getDefaultSortable(); @@ -58,13 +58,13 @@ public Boolean getDefaultSortable() { } @Override - public String getDefaultStyle() { + protected int getDefaultColumnWidth() { return NORMAL_WIDTH; } @Override public String getDefaultStyleClass() { - return "dashboard-tasks__category u-text-align-center"; + return "dashboard-tasks__category u-text-align-center widget-column"; } @Override diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/CreatedDateColumnModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/CreatedDateColumnModel.java index 062e8f9ded5..f7c3a680bd5 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/CreatedDateColumnModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/CreatedDateColumnModel.java @@ -26,7 +26,7 @@ public class CreatedDateColumnModel extends TaskColumnModel implements Serializa public void initDefaultValue() { super.initDefaultValue(); this.field = DashboardStandardTaskColumn.CREATED.getField(); - this.style = defaultIfEmpty(this.style, getDefaultStyle()); + this.styleToDisplay = initDefaultStyle(); this.styleClass = defaultIfEmpty(this.styleClass, getDefaultStyleClass()); this.format = getDefaultFormat(); } @@ -42,13 +42,13 @@ public DashboardColumnFormat getDefaultFormat() { } @Override - public String getDefaultStyle() { + protected int getDefaultColumnWidth() { return SMALL_WIDTH; } @Override public String getDefaultStyleClass() { - return "dashboard-tasks__created-date u-text-align-center"; + return "dashboard-tasks__created-date u-text-align-center widget-column"; } @Override diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/DescriptionColumnModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/DescriptionColumnModel.java index 8a381373f01..151c88403a8 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/DescriptionColumnModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/DescriptionColumnModel.java @@ -13,7 +13,7 @@ public class DescriptionColumnModel extends TaskColumnModel implements Serializa public void initDefaultValue() { super.initDefaultValue(); this.field = DashboardStandardTaskColumn.DESCRIPTION.getField(); - this.style = defaultIfEmpty(this.style, getDefaultStyle()); + this.styleToDisplay = initDefaultStyle(); this.styleClass = defaultIfEmpty(this.styleClass, getDefaultStyleClass()); this.sortable = defaultIfEmpty(this.sortable, getDefaultSortable()); this.quickSearch = defaultIfEmpty(this.quickSearch, true); @@ -30,13 +30,13 @@ public Boolean getDefaultSortable() { } @Override - public String getDefaultStyle() { - return "width: 200px"; + protected int getDefaultColumnWidth() { + return LARGE_WIDTH; } @Override public String getDefaultStyleClass() { - return "dashboard-tasks__description"; + return "dashboard-tasks__description widget-column"; } @Override diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/ExpiryDateColumnModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/ExpiryDateColumnModel.java index bcf80896d61..c9149bacaba 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/ExpiryDateColumnModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/ExpiryDateColumnModel.java @@ -26,7 +26,7 @@ public class ExpiryDateColumnModel extends TaskColumnModel implements Serializab public void initDefaultValue() { super.initDefaultValue(); this.field = DashboardStandardTaskColumn.EXPIRY.getField(); - this.style = defaultIfEmpty(this.style, getDefaultStyle()); + this.styleToDisplay = initDefaultStyle(); this.styleClass = defaultIfEmpty(this.styleClass, getDefaultStyleClass()); this.format = getDefaultFormat(); } @@ -42,13 +42,13 @@ public DashboardColumnFormat getDefaultFormat() { } @Override - public String getDefaultStyle() { + protected int getDefaultColumnWidth() { return NORMAL_WIDTH; } @Override public String getDefaultStyleClass() { - return "dashboard-tasks__expiry-date u-text-align-center u-padding-0"; + return "dashboard-tasks__expiry-date u-text-align-center widget-column"; } @Override diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/IdColumnModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/IdColumnModel.java index d8fc8b99c2d..ff70a5733b2 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/IdColumnModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/IdColumnModel.java @@ -15,6 +15,7 @@ public void initDefaultValue() { this.field = DashboardStandardTaskColumn.ID.getField(); this.styleClass = defaultIfEmpty(this.styleClass, getDefaultStyleClass()); this.quickSearch = defaultIfEmpty(this.quickSearch, false); + this.styleToDisplay = initDefaultStyle(); } @Override @@ -24,7 +25,7 @@ public String getDefaultHeaderCMS() { @Override public String getDefaultStyleClass() { - return "dashboard-tasks__id u-text-align-center u-padding-0"; + return "dashboard-tasks__id u-text-align-center widget-column"; } @Override diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/NameColumnModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/NameColumnModel.java index 9c6ca11d2d0..1009da13278 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/NameColumnModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/NameColumnModel.java @@ -15,6 +15,7 @@ public void initDefaultValue() { this.field = DashboardStandardTaskColumn.NAME.getField(); this.styleClass = defaultIfEmpty(this.styleClass, getDefaultStyleClass()); this.quickSearch = defaultIfEmpty(this.quickSearch, true); + this.styleToDisplay = initDefaultStyle(); } @Override @@ -24,9 +25,14 @@ public String getDefaultHeaderCMS() { @Override public String getDefaultStyleClass() { - return "dashboard-tasks__name"; + return "dashboard-tasks__name widget-column"; } - + + @Override + protected int getDefaultColumnWidth() { + return 200; + } + @Override public Object display(ITask task) { if (task == null) { diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/PriorityColumnModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/PriorityColumnModel.java index 9388d778daf..669836d032f 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/PriorityColumnModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/PriorityColumnModel.java @@ -22,7 +22,7 @@ public class PriorityColumnModel extends TaskColumnModel implements Serializable public void initDefaultValue() { super.initDefaultValue(); this.field = DashboardStandardTaskColumn.PRIORITY.getField(); - this.style = defaultIfEmpty(this.style, getDefaultStyle()); + this.styleToDisplay = initDefaultStyle(); this.styleClass = defaultIfEmpty(this.styleClass, getDefaultStyleClass()); this.format = getDefaultFormat(); } @@ -38,13 +38,13 @@ public DashboardColumnFormat getDefaultFormat() { } @Override - public String getDefaultStyle() { - return "width: 50px"; + protected int getDefaultColumnWidth() { + return TINY_WIDTH; } @Override public String getDefaultStyleClass() { - return "dashboard-tasks__priority u-text-align-center"; + return "dashboard-tasks__priority u-text-align-center widget-column"; } @Override diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/ResponsibleColumnModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/ResponsibleColumnModel.java index 1c7f933ef9f..c097cd7e6cc 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/ResponsibleColumnModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/ResponsibleColumnModel.java @@ -28,7 +28,7 @@ public class ResponsibleColumnModel extends TaskColumnModel implements Serializa public void initDefaultValue() { super.initDefaultValue(); this.field = DashboardStandardTaskColumn.RESPONSIBLE.getField(); - this.style = defaultIfEmpty(this.style, getDefaultStyle()); + this.styleToDisplay = initDefaultStyle(); this.format = getDefaultFormat(); this.styleClass = defaultIfEmpty(this.styleClass, getDefaultStyleClass()); this.quickSearch = defaultIfEmpty(this.quickSearch, false); @@ -45,13 +45,13 @@ public DashboardColumnFormat getDefaultFormat() { } @Override - public String getDefaultStyle() { + protected int getDefaultColumnWidth() { return EXTRA_WIDTH; } @Override public String getDefaultStyleClass() { - return "dashboard-tasks__responsible"; + return "dashboard-tasks__responsible widget-column"; } @Override diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/StartColumnModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/StartColumnModel.java index ba286e83cd0..91c901ccbc4 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/StartColumnModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/StartColumnModel.java @@ -12,7 +12,7 @@ public class StartColumnModel extends TaskColumnModel implements Serializable { public void initDefaultValue() { super.initDefaultValue(); this.field = DashboardStandardTaskColumn.START.getField(); - this.style = defaultIfEmpty(this.style, getDefaultStyle()); + this.styleToDisplay = initDefaultStyle(); this.styleClass = defaultIfEmpty(this.styleClass, getDefaultStyleClass()); this.sortable = getDefaultSortable(); } @@ -28,12 +28,12 @@ public Boolean getDefaultSortable() { } @Override - public String getDefaultStyle() { - return "width: 50px"; + protected int getDefaultColumnWidth() { + return TINY_WIDTH; } @Override public String getDefaultStyleClass() { - return "dashboard-tasks__start u-text-align-center"; + return "dashboard-tasks__start u-text-align-center widget-column ui-sm-hidden"; } } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/StateColumnModel.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/StateColumnModel.java index 94110063f7f..c5fdbdce229 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/StateColumnModel.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/dto/dashboard/taskcolumn/StateColumnModel.java @@ -24,7 +24,7 @@ public class StateColumnModel extends TaskColumnModel implements Serializable { public void initDefaultValue() { super.initDefaultValue(); this.field = DashboardStandardTaskColumn.STATE.getField(); - this.style = defaultIfEmpty(this.style, getDefaultStyle()); + this.styleToDisplay = initDefaultStyle(); this.styleClass = defaultIfEmpty(this.styleClass, getDefaultStyleClass()); this.fieldStyleClass = defaultIfEmpty(this.fieldStyleClass, StringUtils.EMPTY); this.format = getDefaultFormat(); @@ -41,13 +41,13 @@ public DashboardColumnFormat getDefaultFormat() { } @Override - public String getDefaultStyle() { + protected int getDefaultColumnWidth() { return NORMAL_WIDTH; } @Override public String getDefaultStyleClass() { - return "dashboard-tasks__state u-text-align-center"; + return "dashboard-tasks__state u-text-align-center widget-column"; } @Override diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/ChatbotCandidateQuestion.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/ChatbotCandidateQuestion.java new file mode 100644 index 00000000000..38985ca0c3b --- /dev/null +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/ChatbotCandidateQuestion.java @@ -0,0 +1,32 @@ +package ch.ivy.addon.portalkit.enums; + +import ch.ivyteam.ivy.environment.Ivy; + +public enum ChatbotCandidateQuestion { + + EXPLORE("si-bulb"), + TUTORIAL("si-touch-finger_1"), + INTERACT("si-cog"); + + private String icon; + + ChatbotCandidateQuestion(String icon) { + this.setIcon(icon); + } + + public String getHeaderText() { + return Ivy.cms().co("/Labels/Enums/ChatbotCandidateQuestion/" + name() + "/header"); + } + + public String getQuestion() { + return Ivy.cms().co("/Labels/Enums/ChatbotCandidateQuestion/" + name() + "/question"); + } + + public String getIcon() { + return icon; + } + + public void setIcon(String icon) { + this.icon = icon; + } +} diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/DashboardStandardCaseColumn.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/DashboardStandardCaseColumn.java index e07738d46d3..c51a331d8ea 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/DashboardStandardCaseColumn.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/DashboardStandardCaseColumn.java @@ -1,9 +1,12 @@ package ch.ivy.addon.portalkit.enums; import java.util.Arrays; +import java.util.Collections; +import java.util.EnumSet; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Set; import ch.ivyteam.ivy.environment.Ivy; @@ -49,4 +52,7 @@ public static List getFilterableFields() { public String getLabel() { return Ivy.cms().co(String.format("/Labels/Enums/DashboardStandardCaseColumn/%s", this.name())); } + + public static final Set AI_RESULT_COLUMNS = Collections + .unmodifiableSet(EnumSet.of(ID, NAME, OWNER, STATE, ACTIONS)); } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/DashboardStandardProcessColumn.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/DashboardStandardProcessColumn.java index f57b6081680..b9c5df15070 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/DashboardStandardProcessColumn.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/DashboardStandardProcessColumn.java @@ -4,7 +4,8 @@ import java.util.Map; public enum DashboardStandardProcessColumn { - ID("id"), NAME("name"), TYPE("type"), CATEGORY("category"), APPLICATION("application"); + ID("id"), NAME("name"), TYPE("type"), CATEGORY("category"), + APPLICATION("application"), DESCRIPTION("description"); private final String field; diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/DashboardStandardTaskColumn.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/DashboardStandardTaskColumn.java index 09e7677ed73..7247381c46e 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/DashboardStandardTaskColumn.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/DashboardStandardTaskColumn.java @@ -1,7 +1,10 @@ package ch.ivy.addon.portalkit.enums; +import java.util.Collections; +import java.util.EnumSet; import java.util.HashMap; import java.util.Map; +import java.util.Set; import ch.ivyteam.ivy.environment.Ivy; @@ -44,4 +47,8 @@ public static DashboardStandardTaskColumn findBy(String field) { public String getLabel() { return Ivy.cms().co(String.format("/Labels/Enums/DashboardStandardTaskColumn/%s", this.name())); } + + public static final Set AI_RESULT_COLUMNS = Collections + .unmodifiableSet( + EnumSet.of(ID, NAME, RESPONSIBLE, STATE, PRIORITY, EXPIRY, ACTIONS)); } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/GlobalVariable.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/GlobalVariable.java index 946dd5b9550..421a6216dbe 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/GlobalVariable.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/GlobalVariable.java @@ -17,7 +17,6 @@ import com.axonivy.portal.enums.ThemeMode; import ch.addon.portal.generic.userprofile.homepage.HomepageType; -import ch.ivy.addon.portalkit.bean.TaskWidgetBean; import ch.ivy.addon.portalkit.document.DocumentExtensionConstants; import ch.ivyteam.ivy.environment.Ivy; @@ -40,9 +39,6 @@ public enum GlobalVariable { CHAT_RESPONSE_TIMEOUT("Portal.Chat.ResponseTimeout", GlobalVariableType.NUMBER, "0", "chatResponseTimeout"), CHAT_MAX_CONNECTION("Portal.Chat.MaxConnection", GlobalVariableType.SELECTION, "3", "chatMaxConnection", new Object[] { 1, 2, 3, 4, 5}), ENABLE_CASE_OWNER("Portal.Cases.EnableOwner", GlobalVariableType.SELECTION, Option.FALSE.toString(), "enableCaseOwner"), - DISABLE_CASE_COUNT("Portal.Cases.DisableCount", GlobalVariableType.SELECTION, Option.FALSE.toString(), "disableCaseCount"), - REFRESH_TASK_LIST_INTERVAL("Portal.Tasks.RefreshInterval", GlobalVariableType.NUMBER, String.valueOf(TaskWidgetBean.DEFAULT_TASK_LIST_REFRESH_INTERVAL), "refreshTaskListIntervalNote"), - DISABLE_TASK_COUNT("Portal.Tasks.DisableCount", GlobalVariableType.SELECTION, Option.FALSE.toString(), "disableTaskCount"), SHOW_TASK_DURATION_TIME("Portal.TaskDetails.ShowDurationTime", GlobalVariableType.SELECTION, Option.TRUE.toString(), "showTaskDurationTime"), HIDE_TASK_DOCUMENT("Portal.TaskDetails.HideDocument", GlobalVariableType.SELECTION, Option.FALSE.toString(), "hideTaskDocument"), HIDE_CASE_DOCUMENT("Portal.CaseDetails.HideDocument", GlobalVariableType.SELECTION, Option.FALSE.toString(), "hideCaseDocument"), @@ -56,13 +52,9 @@ public enum GlobalVariable { DISPLAY_USERS_OF_ROLE("Portal.DisplayUsersOfRole", GlobalVariableType.SELECTION, Option.FALSE.toString(), "displayAllUsersOfTaskActivator"), SHOW_PROCESS_INFORMATION("Portal.Processes.ShowInformation", GlobalVariableType.SELECTION, Option.TRUE.toString(), "showProcessInformation"), LOGGED_IN_USER_FORMAT("Portal.LoggedInUserFormat", GlobalVariableType.SELECTION, Option.DISPLAY_NAME.name(), "loggedInUserFormat", getLoggedInUserFormatOptions()), - DEFAULT_SORT_FIELD_OF_CASE_LIST("Portal.Cases.SortField", GlobalVariableType.EXTERNAL_SELECTION, CaseSortField.ID.name(), "defaultSortFieldOfCaseList", getCaseListSortFields()), - DEFAULT_SORT_DIRECTION_OF_CASE_LIST("Portal.Cases.SortDirection", GlobalVariableType.EXTERNAL_SELECTION, SortDirection.DESC.name(), "defaultSortDirectionOfCaseList", getSortDirections()), DEFAULT_PROCESS_MODE("Portal.Processes.Mode", GlobalVariableType.EXTERNAL_SELECTION, ProcessMode.IMAGE.name(), "defaultProcessMode", getProcessMode()), DEFAULT_PROCESS_IMAGE("Portal.Processes.DefaultImage", GlobalVariableType.EXTERNAL_SELECTION, DefaultImage.DEFAULT.name(), "defaultProcessImage", getDefaultProcessImage()), DEFAULT_HOMEPAGE("Portal.Homepage", GlobalVariableType.EXTERNAL_SELECTION, StringUtils.capitalize(HomepageType.DASHBOARD.name().toLowerCase()), "defaultHomepage"), - DEFAULT_SORT_DIRECTION_OF_TASK_LIST("Portal.Tasks.SortDirection", GlobalVariableType.EXTERNAL_SELECTION, SortDirection.DESC.name(), "defaultSortDirectionOfTaskList", getSortDirections()), - DEFAULT_SORT_FIELD_OF_TASK_LIST("Portal.Tasks.SortField", GlobalVariableType.EXTERNAL_SELECTION, TaskSortField.ID.name(), "defaultSortFieldOfTaskList", getTaskListSortFields()), DEFAULT_BEHAVIOUR_WHEN_CLICKING_ON_LINE_IN_TASK_LIST("Portal.Tasks.BehaviourWhenClickingOnLineInTaskList", GlobalVariableType.EXTERNAL_SELECTION, BehaviourWhenClickingOnLineInTaskList.RUN_TASK.name(), "behaviourWhenClickingOnLineInTaskList", getBehavioursWhenClickingOnLineInTaskList()), ENABLE_PROCESS_VIEWER("Portal.ProcessViewer", GlobalVariableType.SELECTION, Option.TRUE.toString(), "enableProcessViewer"), @@ -90,7 +82,7 @@ public enum GlobalVariable { "googlePlayURL"), APPLICATION_NAME("Portal.ApplicationName", GlobalVariableType.TEXT, "Axon Ivy", "ApplicationName"), HIDE_CASE_CREATOR( "Portal.Cases.HideCaseCreator", GlobalVariableType.SELECTION, Option.FALSE.toString(), "hideCaseCreator"); -; + private String key; @@ -213,36 +205,6 @@ private static Option[] getLoggedInUserFormatOptions() { return new Option[] {Option.USERNAME, Option.DISPLAY_NAME, Option.DISPLAY_NAME_USERNAME, Option.USERNAME_DISPLAY_NAME}; } - private static Map getTaskListSortFields() { - Map result = new HashMap<>(); - for (TaskSortField sortField : TaskSortField.values()) { - // Task sort field not available - if (StringUtils.isNotBlank(sortField.getLabel()) && sortField != TaskSortField.CATEGORY) { - result.put(sortField.name(), sortField); - } - } - return result; - } - - private static Map getCaseListSortFields() { - Map result = new HashMap<>(); - for (CaseSortField sortField : CaseSortField.values()) { - // Case sort field not available - if (StringUtils.isNotBlank(sortField.getLabel()) && sortField != CaseSortField.CATEGORY) { - result.put(sortField.name(), sortField); - } - } - return result; - } - - private static Map getSortDirections() { - Map result = new HashMap<>(); - for (SortDirection direction : SortDirection.values()) { - result.put(direction.name(), direction); - } - return result; - } - private static Map getProcessMode() { Map result = new HashMap<>(); for (ProcessMode mode : ProcessMode.values()) { diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/MenuKind.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/MenuKind.java index 4b0a5a2dfa3..36179c6d845 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/MenuKind.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/MenuKind.java @@ -1,7 +1,7 @@ package ch.ivy.addon.portalkit.enums; public enum MenuKind { - DASHBOARD, PROCESS, TASK, CASE, CUSTOM, EXTERNAL_LINK, THIRD_PARTY; + DASHBOARD, PROCESS, CUSTOM, EXTERNAL_LINK, THIRD_PARTY, MAIN_DASHBOARD; @Override public String toString() { diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/PortalVariable.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/PortalVariable.java index 0b3e466272f..ffa7ce54312 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/PortalVariable.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/PortalVariable.java @@ -14,6 +14,7 @@ public enum PortalVariable { USER_MENU("Portal.UserMenu"), CUSTOM_MENU_ITEMS("Portal.CustomMenuItems"), STATISTIC_DATA("Portal.StatisticData"), + CHATBOT_ENDPOINT("PortalAiUrl"), DASHBOARD_MAIN_MENU_ENTRY("Portal.Dashboard.MainMenuEntry"), CLIENT_STATISTIC("Portal.ClientStatistic"); diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/SessionAttribute.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/SessionAttribute.java index 0ba751a0f94..d9c2e27ec8d 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/SessionAttribute.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/enums/SessionAttribute.java @@ -10,5 +10,7 @@ public enum SessionAttribute { HELP_URL_LINK, PORTAL_IN_TEAMS, DEFAULT_PAGE_IN_TEAMS, - SELECTED_DASHBOARD_ID; + SELECTED_SUB_DASHBOARD_ID, + SELECTED_DASHBOARD_ID, + ; } \ No newline at end of file diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/exporter/CaseDashboardExporter.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/exporter/CaseDashboardExporter.java index 6c08e971197..1211fbec002 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/exporter/CaseDashboardExporter.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/exporter/CaseDashboardExporter.java @@ -86,9 +86,7 @@ private Object getCommonColumnValue(DashboardStandardCaseColumn sortField, ICase : SecurityMemberDisplayNameUtils.generateBriefDisplayNameForSecurityMember(caseItem.getCreatorUser(), caseItem.getCreatorUserName()); case CREATED -> caseItem.getStartTimestamp(); case FINISHED -> caseItem.getEndTimestamp(); - case OWNER -> caseItem.getOwnerName() == null - ? Ivy.cms().co("/ch.ivy.addon.portalkit.ui.jsf/common/notAvailable") - : SecurityMemberDisplayNameUtils.generateBriefDisplayNameForSecurityMember(caseItem.getOwner(), caseItem.getOwnerName()); + case OWNER -> SecurityMemberDisplayNameUtils.generateBriefDisplayNameForCaseOwners(caseItem.owners()); case CATEGORY-> caseItem.getCategory().getPath(); case APPLICATION -> caseItem.getApplication().getName(); default -> ""; @@ -115,18 +113,13 @@ private Object getCustomColumnValue(String column, ICase caseItem) { return ""; } - switch (fieldFormat) { - case NUMBER: - return caseItem.customFields().numberField(fieldName).getOrNull(); - case STRING: - return caseItem.customFields().stringField(fieldName).getOrNull(); - case TEXT: - return caseItem.customFields().textField(fieldName).getOrNull(); - case TIMESTAMP: - return caseItem.customFields().timestampField(fieldName).getOrNull(); - default: - return ""; - } + return switch (fieldFormat) { + case NUMBER -> caseItem.customFields().numberField(fieldName).getOrNull(); + case STRING -> caseItem.customFields().stringField(fieldName).getOrNull(); + case TEXT -> caseItem.customFields().textField(fieldName).getOrNull(); + case TIMESTAMP -> caseItem.customFields().timestampField(fieldName).getOrNull(); + default -> ""; + }; } /** diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/exporter/CaseExporter.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/exporter/CaseExporter.java index 036f0782505..ce5ccc18c22 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/exporter/CaseExporter.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/exporter/CaseExporter.java @@ -97,34 +97,23 @@ protected Object getCommonColumnValue(String column, ICase caseItem) { } CaseSortField sortField = CaseSortField.valueOf(column); - switch (sortField) { - case NAME: - return StringUtils.isEmpty(caseItem.names().current()) ? Ivy.cms().co("/Dialogs/ch/ivy/addon/portalkit/component/CaseWidget/caseNameNotAvailable") : caseItem.names().current(); - case ID: - return String.valueOf(caseItem.getId()); - case CREATOR: + return switch (sortField) { + case NAME -> StringUtils.isEmpty(caseItem.names().current()) ? Ivy.cms().co("/Dialogs/ch/ivy/addon/portalkit/component/CaseWidget/caseNameNotAvailable") : caseItem.names().current(); + case ID -> String.valueOf(caseItem.getId()); + case CREATOR -> { if (caseItem.getCreatorUserName() == null) { - return Ivy.cms().co("/ch.ivy.addon.portalkit.ui.jsf/common/notAvailable"); + yield Ivy.cms().co("/ch.ivy.addon.portalkit.ui.jsf/common/notAvailable"); } - return SecurityMemberDisplayNameUtils.generateBriefDisplayNameForSecurityMember(caseItem.getCreatorUser(), caseItem.getCreatorUserName()); - case OWNER: - if (caseItem.getOwnerName() == null) { - return Ivy.cms().co("/ch.ivy.addon.portalkit.ui.jsf/common/notAvailable"); - } - return SecurityMemberDisplayNameUtils.generateBriefDisplayNameForSecurityMember(caseItem.getOwner(), caseItem.getOwnerName()); - case CREATION_TIME: - return caseItem.getStartTimestamp(); - case FINISHED_TIME: - return caseItem.getEndTimestamp(); - case STATE: - return CaseUtils.convertToUserFriendlyCaseState(caseItem.getBusinessState()); - case CATEGORY: - return caseItem.getCategory().getPath(); - case APPLICATION: - return caseItem.getApplication().getName(); - default: - return ""; - } + yield SecurityMemberDisplayNameUtils.generateBriefDisplayNameForSecurityMember(caseItem.getCreatorUser(), caseItem.getCreatorUserName()); + } + case OWNER -> SecurityMemberDisplayNameUtils.generateBriefDisplayNameForCaseOwners(caseItem.owners()); + case CREATION_TIME -> caseItem.getStartTimestamp(); + case FINISHED_TIME -> caseItem.getEndTimestamp(); + case STATE -> CaseUtils.convertToUserFriendlyCaseState(caseItem.getBusinessState()); + case CATEGORY -> caseItem.getCategory().getPath(); + case APPLICATION -> caseItem.getApplication().getName(); + default -> ""; + }; } /** diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/exporter/internal/NoteHistoryExporter.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/exporter/internal/NoteHistoryExporter.java index dd223354db2..360d65a239e 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/exporter/internal/NoteHistoryExporter.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/exporter/internal/NoteHistoryExporter.java @@ -19,11 +19,11 @@ import ch.ivy.addon.portalkit.util.SecurityMemberDisplayNameUtils; import ch.ivyteam.ivy.environment.Ivy; import ch.ivyteam.ivy.workflow.ICase; -import ch.ivyteam.ivy.workflow.INote; +import ch.ivyteam.ivy.workflow.note.Note; public class NoteHistoryExporter { - public StreamedContent getStreamedContentOfTaskNoteHistory(List taskNoteHistory, String fileName) { + public StreamedContent getStreamedContentOfTaskNoteHistory(List taskNoteHistory, String fileName) { List> rows = generateDataForTaskNoteHistory(taskNoteHistory); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); @@ -88,13 +88,13 @@ private List generateHeaders(boolean isBusinessCase) { return headers; } - private List> generateDataForTaskNoteHistory(List taskNoteHistory) { + private List> generateDataForTaskNoteHistory(List taskNoteHistory) { List> rows = new ArrayList<>(); - for (INote taskNote : taskNoteHistory) { + for (Note taskNote : taskNoteHistory) { List row = new ArrayList<>(); - row.add(taskNote.getMessage()); - row.add(SecurityMemberDisplayNameUtils.generateBriefDisplayNameForUser(taskNote.getWritter(), taskNote.getWritter().getName())); - row.add(formatDate(taskNote.getCreationTimestamp())); + row.add(taskNote.content()); + row.add(SecurityMemberDisplayNameUtils.generateBriefDisplayNameForUser(taskNote.author(), taskNote.authorName())); + row.add(formatDate(taskNote.createdAt())); rows.add(row); } return rows; diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/searchcriteria/CaseSearchCriteria.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/searchcriteria/CaseSearchCriteria.java index c70aea8629c..c10254dedb4 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/searchcriteria/CaseSearchCriteria.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/searchcriteria/CaseSearchCriteria.java @@ -163,7 +163,6 @@ public CaseSortingQueryAppender appendSorting(CaseSearchCriteria criteria) { appendSortByStartTimeIfSet(criteria); appendSortByEndTimeIfSet(criteria); appendSortByCreatorIfSet(criteria); - appendSortByOwnerIfSet(criteria); appendSortByStateIfSet(criteria); return this; } @@ -222,16 +221,6 @@ private void appendSortByCreatorIfSet(CaseSearchCriteria criteria) { } } - private void appendSortByOwnerIfSet(CaseSearchCriteria criteria) { - if (!CaseSortField.OWNER.toString().equalsIgnoreCase(criteria.getSortField())) { - return; - } - OrderByColumnQuery orderByName = query.orderBy().ownerDisplayName(); - if (criteria.isSortDescending()) { - orderByName.descending(); - } - } - private void appendSortByStateIfSet(CaseSearchCriteria criteria) { if (!CaseSortField.STATE.toString().equalsIgnoreCase(criteria.getSortField())) { return; diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/searchcriteria/DashboardCaseSearchCriteria.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/searchcriteria/DashboardCaseSearchCriteria.java index 65577909027..d4080d46991 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/searchcriteria/DashboardCaseSearchCriteria.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/searchcriteria/DashboardCaseSearchCriteria.java @@ -172,7 +172,6 @@ public CaseSortingQueryAppender appendSorting(DashboardCaseSearchCriteria criter appendSortByIdIfSet(criteria); appendSortByCreationDateIfSet(criteria); appendSortByStateIfSet(criteria); - appendSortByOwnerIfSet(criteria); appendSortByEndDateIfSet(criteria); appendSortByCustomFieldIfSet(criteria); if (criteria.isSortDescending()) { @@ -188,14 +187,6 @@ private void appendSortByEndDateIfSet(DashboardCaseSearchCriteria criteria) { } } - private void appendSortByOwnerIfSet(DashboardCaseSearchCriteria criteria) { - if (DashboardStandardCaseColumn.OWNER.getField().equalsIgnoreCase(criteria.getSortField()) - && GlobalSettingService.getInstance().isCaseOwnerEnabled()) { - order = query.orderBy().ownerDisplayName(); - sortStandardColumn = true; - } - } - private void appendSortByNameIfSet(DashboardCaseSearchCriteria criteria) { if (DashboardStandardCaseColumn.NAME.getField().equalsIgnoreCase(criteria.getSortField())) { order = query.orderBy().name(); diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/searchcriteria/DashboardProcessCaseSearchCriteria.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/searchcriteria/DashboardProcessCaseSearchCriteria.java index 6377773a96f..087b4150005 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/searchcriteria/DashboardProcessCaseSearchCriteria.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/searchcriteria/DashboardProcessCaseSearchCriteria.java @@ -87,7 +87,6 @@ public CaseSortingQueryAppender appendSorting(DashboardProcessCaseSearchCriteria appendSortByIdIfSet(criteria); appendSortByCreationDateIfSet(criteria); appendSortByStateIfSet(criteria); - appendSortByOwnerIfSet(criteria); appendSortByEndDateIfSet(criteria); if (criteria.isSortDescending()) { order.descending(); @@ -101,12 +100,6 @@ private void appendSortByEndDateIfSet(DashboardProcessCaseSearchCriteria criteri } } - private void appendSortByOwnerIfSet(DashboardProcessCaseSearchCriteria criteria) { - if (DashboardStandardCaseColumn.OWNER.getField().equalsIgnoreCase(criteria.getSortField())) { - order = query.orderBy().ownerDisplayName(); - } - } - private void appendSortByNameIfSet(DashboardProcessCaseSearchCriteria criteria) { if (DashboardStandardCaseColumn.NAME.getField().equalsIgnoreCase(criteria.getSortField())) { order = query.orderBy().name(); diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/searchcriteria/DashboardProcessSearchCriteria.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/searchcriteria/DashboardProcessSearchCriteria.java index 70c32a42dec..7e3d87899e9 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/searchcriteria/DashboardProcessSearchCriteria.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/searchcriteria/DashboardProcessSearchCriteria.java @@ -2,6 +2,7 @@ import static ch.ivy.addon.portalkit.enums.DashboardStandardProcessColumn.APPLICATION; import static ch.ivy.addon.portalkit.enums.DashboardStandardProcessColumn.CATEGORY; +import static ch.ivy.addon.portalkit.enums.DashboardStandardProcessColumn.DESCRIPTION; import static ch.ivy.addon.portalkit.enums.DashboardStandardProcessColumn.NAME; import static ch.ivy.addon.portalkit.enums.DashboardStandardProcessColumn.TYPE; import static ch.ivy.addon.portalkit.enums.ProcessWidgetMode.COMPACT_MODE; @@ -63,6 +64,11 @@ public List searchProcessesByFilters(CompactProcessDashboardWi final List apps = applications; displayProcesses = ListUtilities.filterList(displayProcesses, process -> apps.contains(process.getApplication())); } + } else if (DESCRIPTION.getField().equalsIgnoreCase(column.getField()) + && StringUtils.isNotEmpty(column.getUserFilter())) { + displayProcesses = ListUtilities.filterList(displayProcesses, + process -> StringUtils.containsIgnoreCase(process.getDescription(), + column.getUserFilter())); } } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/searchcriteria/DashboardTaskSearchCriteria.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/searchcriteria/DashboardTaskSearchCriteria.java index 093aad06569..a9d5e450944 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/searchcriteria/DashboardTaskSearchCriteria.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/searchcriteria/DashboardTaskSearchCriteria.java @@ -16,10 +16,12 @@ import ch.ivy.addon.portalkit.dto.dashboard.ColumnModel; import ch.ivy.addon.portalkit.dto.dashboard.taskcolumn.TaskColumnModel; +import ch.ivy.addon.portalkit.enums.DashboardColumnFormat; import ch.ivy.addon.portalkit.enums.DashboardColumnType; import ch.ivy.addon.portalkit.enums.DashboardStandardTaskColumn; import ch.ivyteam.ivy.workflow.query.CaseQuery; import ch.ivyteam.ivy.workflow.query.TaskQuery; +import ch.ivyteam.ivy.workflow.query.TaskQuery.ICustomFieldOrderBy; import ch.ivyteam.ivy.workflow.query.TaskQuery.OrderByColumnQuery; public class DashboardTaskSearchCriteria { @@ -198,6 +200,7 @@ public TaskSortingQueryAppender appendSorting(DashboardTaskSearchCriteria criter appendSortByExpiryDateIfSet(criteria); appendSortByStateIfSet(criteria); appendSortByPriorityIfSet(criteria); + appendSortByCustomFieldIfSet(criteria); if (criteria.isSortDescending() && order != null) { order.descending(); } @@ -252,6 +255,25 @@ private void appendSortByCreatedDateIfSet(DashboardTaskSearchCriteria criteria) sortStandardColumn = true; } } + + private void appendSortByCustomFieldIfSet(DashboardTaskSearchCriteria criteria) { + if (!sortStandardColumn) { + String sortField = criteria.getSortField(); + if (StringUtils.isNotBlank(sortField)) { + DashboardColumnFormat format = + columns.stream().filter(c -> StringUtils.equalsIgnoreCase(sortField, c.getField())) + .map(ColumnModel::getFormat).findFirst().orElse(DashboardColumnFormat.STRING); + final ICustomFieldOrderBy customField = query.orderBy().customField(); + if (format == DashboardColumnFormat.NUMBER) { + order = customField.numberField(sortField); + } else if (format == DashboardColumnFormat.TIMESTAMP) { + order = customField.timestampField(sortField); + } else { + order = customField.stringField(sortField); + } + } + } + } } public boolean getCanWorkOn() { diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/searchcriteria/TaskSearchCriteria.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/searchcriteria/TaskSearchCriteria.java index 2e9f3f5aef4..fba8c3cdc03 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/searchcriteria/TaskSearchCriteria.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/searchcriteria/TaskSearchCriteria.java @@ -62,6 +62,7 @@ public class TaskSearchCriteria { private boolean isGlobalSearch; private boolean isGlobalSearchScope; + @SuppressWarnings("deprecation") public TaskQuery createQueryToFindLatestTasks(TaskQuery taskQuery, Date timeStamp) { if (isAdminQuery) { taskQuery.where().and(TaskQuery.create().where().startTimestamp().isGreaterThan(timeStamp)); diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/service/impl/DashboardCaseService.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/service/impl/DashboardCaseService.java index 1a963dbd63c..c2aca855887 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/service/impl/DashboardCaseService.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/service/impl/DashboardCaseService.java @@ -23,14 +23,17 @@ public static DashboardCaseService getInstance() { public List findByCaseQuery(CaseQuery query, int startIndex, int count) { return Sudo.get(() -> { var subQuery = CaseQuery.businessCases(); + boolean hasSubQueryChanged = false; if (!PermissionUtils.checkReadAllCasesPermission()) { subQuery.where().and(queryForCurrentUser(false)); + hasSubQueryChanged = true; } if (isHiddenTasksCasesExcluded()) { subQuery.where().and(queryExcludeHiddenCases()); + hasSubQueryChanged = true; } - var finalQuery = query.where().and(subQuery); + var finalQuery = hasSubQueryChanged ? query.where().and(subQuery) : query; return executeCaseQuery(finalQuery, startIndex, count); }); } @@ -38,14 +41,17 @@ public List findByCaseQuery(CaseQuery query, int startIndex, int count) { public Long countByCaseQuery(CaseQuery query) { return Sudo.get(() -> { var subQuery = CaseQuery.businessCases(); + boolean hasSubQueryChanged = false; if (!PermissionUtils.checkReadAllCasesPermission()) { subQuery.where().and(queryForCurrentUser(false)); + hasSubQueryChanged = true; } if (isHiddenTasksCasesExcluded()) { subQuery.where().and(queryExcludeHiddenCases()); + hasSubQueryChanged = true; } - var finalQuery = query.where().and(subQuery); + var finalQuery = hasSubQueryChanged ? query.where().and(subQuery) : query; return countCases(finalQuery); }); } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/service/impl/DashboardTaskService.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/service/impl/DashboardTaskService.java index 6017bf6850c..aa6b045109c 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/service/impl/DashboardTaskService.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/service/impl/DashboardTaskService.java @@ -25,16 +25,20 @@ public static DashboardTaskService getInstance() { public List findByTaskQuery(TaskQuery query, int startIndex, int count) { return Sudo.get(() -> { var subQuery = TaskQuery.create(); + boolean hasSubQueryChanged = false; if (!PermissionUtils.checkReadAllTasksPermission()) { subQuery.where().and(queryInvolvedTasks()); + hasSubQueryChanged = true; } if (isHiddenTasksCasesExcluded()) { subQuery.where().and(queryExcludeHiddenTasks()); + hasSubQueryChanged = true; } if (!PermissionUtils.hasSystemTaskReadAllPermission()) { subQuery.where().and(queryExcludeSystemTasks()); + hasSubQueryChanged = true; } - var finalQuery = query.where().and(subQuery); + var finalQuery = hasSubQueryChanged ? query.where().and(subQuery) : query; return executeTaskQuery(finalQuery, startIndex, count); }); } @@ -42,16 +46,20 @@ public List findByTaskQuery(TaskQuery query, int startIndex, int count) { public Long countByTaskQuery(TaskQuery query) { return Sudo.get(() ->{ TaskQuery subQuery = TaskQuery.create(); + boolean hasSubQueryChanged = false; if(!PermissionUtils.checkReadAllTasksPermission()) { subQuery.where().and(queryInvolvedTasks()); + hasSubQueryChanged = true; } if (isHiddenTasksCasesExcluded()) { subQuery.where().and(queryExcludeHiddenTasks()); + hasSubQueryChanged = true; } if (!PermissionUtils.hasSystemTaskReadAllPermission()) { subQuery.where().and(queryExcludeSystemTasks()); + hasSubQueryChanged = true; } - var finalQuery = query.where().and(subQuery); + var finalQuery = hasSubQueryChanged ? query.where().and(subQuery) : query; return countTasks(finalQuery); }); diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/service/impl/LanguageService.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/service/impl/LanguageService.java index 8216abd1bf1..59971afe664 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/service/impl/LanguageService.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/service/impl/LanguageService.java @@ -109,8 +109,8 @@ public void saveUserLanguage(IvyLanguage language) { /** * From IVYPORTAL-16987 * We use session cache to reduce loading time in new dashboard template + * @return content locales * - * @return */ @SuppressWarnings("unchecked") public List getContentLocales() { @@ -130,8 +130,8 @@ public List getContentLocales() { /** * From IVYPORTAL-16987 * We use session cache to reduce loading time in new dashboard template + * @return formatting locales * - * @return */ @SuppressWarnings("unchecked") public List getFormattingLocales() { diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/service/impl/LibraryService.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/service/impl/LibraryService.java index 534129012bc..0bcba6ef6a9 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/service/impl/LibraryService.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/service/impl/LibraryService.java @@ -21,7 +21,7 @@ public class LibraryService{ public Map> collectLibraries() { Map> libraries = new HashMap<>(); - List applicationsInSecurityContext = IApplicationRepository.instance().allOf(ISecurityContext.current()); + List applicationsInSecurityContext = IApplicationRepository.of(ISecurityContext.current()).all(); List displayStates = Arrays.asList(ReleaseState.RELEASED, ReleaseState.DEPRECATED); for (IApplication currentApp : applicationsInSecurityContext) { diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/service/impl/TaskService.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/service/impl/TaskService.java index 686db44a46b..118525d4ef8 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/service/impl/TaskService.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/service/impl/TaskService.java @@ -38,9 +38,7 @@ import ch.ivyteam.ivy.persistence.query.IPagedResult; import ch.ivyteam.ivy.scripting.objects.Record; import ch.ivyteam.ivy.scripting.objects.Recordset; -import ch.ivyteam.ivy.security.IRole; import ch.ivyteam.ivy.security.ISecurityContext; -import ch.ivyteam.ivy.security.IUser; import ch.ivyteam.ivy.security.exec.Sudo; import ch.ivyteam.ivy.workflow.ITask; import ch.ivyteam.ivy.workflow.TaskState; diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/service/impl/UserSettingService.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/service/impl/UserSettingService.java index 73d3516275d..9885d8eabdb 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/service/impl/UserSettingService.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/ivydata/service/impl/UserSettingService.java @@ -3,7 +3,6 @@ import org.apache.commons.lang3.StringUtils; import ch.ivy.addon.portalkit.constant.UserProperty; -import ch.ivy.addon.portalkit.util.UserUtils; import ch.ivyteam.ivy.environment.Ivy; import ch.ivyteam.ivy.security.IUser; @@ -25,30 +24,6 @@ public static UserSettingService getInstance() { return instance; } - public void saveDefaultSortFieldOfTaskList(String fieldName, String sortDirection) { - IUser user = getSessionUser(); - user.setProperty(UserProperty.DEFAULT_SORT_FIELD_OF_TASK_LIST, fieldName); - user.setProperty(UserProperty.DEFAULT_SORT_DIRECTION_OF_TASK_LIST, sortDirection); - - UserUtils.setSessionTaskSortAttribute(null); - } - - public String getDefaultSortFieldOfTaskList() { - return getUserProperty(UserProperty.DEFAULT_SORT_FIELD_OF_TASK_LIST); - } - - public String getDefaultSortDirectionOfTaskList() { - return getUserProperty(UserProperty.DEFAULT_SORT_DIRECTION_OF_TASK_LIST); - } - - public void saveDefaultSortFieldOfCaseList(String fieldName, String sortDirection) { - IUser user = getSessionUser(); - user.setProperty(UserProperty.DEFAULT_SORT_FIELD_OF_CASE_LIST, fieldName); - user.setProperty(UserProperty.DEFAULT_SORT_DIRECTION_OF_CASE_LIST, sortDirection); - - UserUtils.setSessionCaseSortAttribute(null); - } - public void saveDefaultTaskBehaviourWhenClickingOnLineInTaskList(String taskBehaviour) { IUser user = getSessionUser(); user.setProperty(UserProperty.DEFAULT_TASK_BEHAVIOUR_WHEN_CLICKING_ON_LINE_IN_TASK_LIST, taskBehaviour); @@ -68,14 +43,6 @@ public boolean isDefaultProcessModeOption(String processMode) { Ivy.cms().co("/ch.ivy.addon.portalkit.ui.jsf/MyProfile/defaultOption").replace("({0})", "")); } - public String getDefaultSortFieldOfCaseList() { - return getUserProperty(UserProperty.DEFAULT_SORT_FIELD_OF_CASE_LIST); - } - - public String getDefaultSortDirectionOfCaseList() { - return getUserProperty(UserProperty.DEFAULT_SORT_DIRECTION_OF_CASE_LIST); - } - public String getDateFormat() { return getUserProperty(UserProperty.DATE_FORMAT); } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/persistence/converter/BusinessEntityConverter.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/persistence/converter/BusinessEntityConverter.java index 2c1917cb585..12107271cd1 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/persistence/converter/BusinessEntityConverter.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/persistence/converter/BusinessEntityConverter.java @@ -20,7 +20,9 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.json.JsonMapper; +import ch.ivy.addon.portalkit.dto.dashboard.Dashboard; import ch.ivy.addon.portalkit.service.exception.PortalException; +import ch.ivy.addon.portalkit.util.DashboardUtils; /** * This class provides method to convert Business entity object into JSON value and reverse @@ -126,4 +128,14 @@ public static List convertJsonToListString(String value) return new ArrayList<>(); } + + public static String entityToJsonValue(List dashboards) { + DashboardUtils.updatePropertiesToNullIfCurrentValueIsDefaultValue(dashboards); + try { + return getObjectMapper().writeValueAsString(dashboards); + } catch (JsonProcessingException e) { + throw new PortalException(e); + } + } + } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/service/AiProcessService.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/service/AiProcessService.java new file mode 100644 index 00000000000..9d679c542a8 --- /dev/null +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/service/AiProcessService.java @@ -0,0 +1,24 @@ +package ch.ivy.addon.portalkit.service; + +import com.axonivy.portal.components.util.ProcessStartUtils; + +import ch.ivyteam.ivy.workflow.IProcessStart; + +public class AiProcessService { + + private static final String AI_DASHBOARD_FRIENDLY_REQUEST_PATH = "Start Processes/AiStart/AssistantDashboard.ivp"; + + private static AiProcessService instance; + + public static AiProcessService getInstance() { + if (instance == null) { + instance = new AiProcessService(); + } + return instance; + } + + public IProcessStart findAssistantDashboardProcess() { + return ProcessStartUtils.findProcessStartByUserFriendlyRequestPath( + AI_DASHBOARD_FRIENDLY_REQUEST_PATH); + } +} diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/service/DashboardService.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/service/DashboardService.java index 90ab5cb9406..03d4a752cde 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/service/DashboardService.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/service/DashboardService.java @@ -1,4 +1,9 @@ package ch.ivy.addon.portalkit.service; + +import java.util.List; + +import com.axonivy.portal.bo.jsonversion.DashboardFilterJsonVersion; + import ch.ivy.addon.portalkit.dto.dashboard.Dashboard; import ch.ivy.addon.portalkit.enums.PortalVariable; @@ -23,4 +28,12 @@ public String getConfigKey() { return PortalVariable.DASHBOARD.key; } + public Dashboard saveDefaultDashboardAsFirstDashboard(Dashboard defaultDashboard) { + List entities = getPublicConfig(); + defaultDashboard.setVersion(DashboardFilterJsonVersion.LATEST_VERSION.getValue()); + entities.addFirst(defaultDashboard); + savePublicConfig(entities); + return defaultDashboard; + } + } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/service/HistoryService.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/service/HistoryService.java index e3890f0b413..3c843fd327b 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/service/HistoryService.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/service/HistoryService.java @@ -20,20 +20,14 @@ import ch.ivyteam.ivy.security.ISecurityConstants; import ch.ivyteam.ivy.security.exec.Sudo; import ch.ivyteam.ivy.workflow.ICase; -import ch.ivyteam.ivy.workflow.INote; import ch.ivyteam.ivy.workflow.ITask; import ch.ivyteam.ivy.workflow.IWorkflowEvent; +import ch.ivyteam.ivy.workflow.note.Note; public class HistoryService { private static final String CASE_NAME_FORMAT = "#%d %s"; - public List getHistories(List tasks, List notes, boolean excludeSystemTasks, boolean excludeSystemNotes) { - List historiesRelatedToTasks = createHistoriesFromITasks(tasks, excludeSystemTasks); - List historiesRelatedToNotes = createHistoriesFromINotes(notes, excludeSystemNotes); - return sortHistoriesByTimeStampDescending(Arrays.asList(historiesRelatedToTasks, historiesRelatedToNotes)); - } - public List getCaseHistories(Long selectedCaseId, List tasks, List cases, boolean excludeSystemTasks, boolean excludeSystemNotes) { var historiesRelatedToTasks = createHistoriesFromITasks(tasks, excludeSystemTasks, selectedCaseId); @@ -46,7 +40,7 @@ public List getCaseHistories(Long selectedCaseId, List tasks, Li private List createCaseHistories(boolean excludeSystemNotes, ICase caseHistory, Long selectedCaseId) { var histories = new ArrayList(); - for (var note : caseHistory.getNotes()) { + for (var note : caseHistory.notes().all()) { if(excludeSystemNotes && !isNotSystemNote(note)) { continue; } @@ -89,14 +83,7 @@ private List sortHistoriesByTimeStampDescending(List> lis return allHistories; } - private List createHistoriesFromITasks(List tasks, boolean excludeSystemTasks) { - if (excludeSystemTasks) { - return tasks.stream().filter(isNotSystemTaskNote()).map(this::createHistoryFrom).collect(Collectors.toList()); - } - return tasks.stream().map(this::createHistoryFrom).collect(Collectors.toList()); - } - - public List createHistoriesFromINotes(List notes, boolean excludeSystemNotes) { + public List createHistoriesFromINotes(List notes, boolean excludeSystemNotes) { if(excludeSystemNotes) { return notes.stream().filter(note -> isNotSystemNote(note)) .map(this::createHistoryFrom).collect(Collectors.toList()); @@ -108,8 +95,8 @@ private Predicate isNotSystemTaskNote() { return task -> !StringUtils.equals(task.getWorkerUserName(), ISecurityConstants.SYSTEM_USER_NAME); } - private boolean isNotSystemNote(INote note) { - return !StringUtils.equals(note.getWritterName(), ISecurityConstants.SYSTEM_USER_NAME); + private boolean isNotSystemNote(Note note) { + return !StringUtils.equals(note.authorName(), ISecurityConstants.SYSTEM_USER_NAME); } public History createHistoryFrom(ITask task) { @@ -164,13 +151,13 @@ private List getTaskWorkflowEvents(ITask task) { }); } - public History createHistoryFrom(INote note) { + public History createHistoryFrom(Note note) { History history = new History(); - history.setId(note.getId()); - history.setContent(note.getMessage()); - history.setInvolvedUser(note.getWritter()); - history.setInvolvedUsername(note.getWritterName()); - history.setTimestamp(new Timestamp(note.getCreationTimestamp().getTime())); + history.setId(note.id()); + history.setContent(note.content()); + history.setInvolvedUser(note.author()); + history.setInvolvedUsername(note.authorName()); + history.setTimestamp(new Timestamp(note.createdAt().getTime())); history.setType(HistoryType.NOTE); return history; } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/service/JsonConfigurationService.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/service/JsonConfigurationService.java index 1f81e74176f..15b1ccacc53 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/service/JsonConfigurationService.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/service/JsonConfigurationService.java @@ -10,11 +10,15 @@ import org.apache.commons.lang3.StringUtils; import com.axonivy.portal.bo.jsonversion.DashboardFilterJsonVersion; +import com.axonivy.portal.migration.dashboard.migrator.JsonDashboardMigrator; import com.axonivy.portal.migration.dashboardfilter.migrator.JsonDashboardFilterMigrator; +import com.axonivy.portal.migration.dashboardtemplate.migrator.JsonDashboardTemplateMigrator; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import ch.ivy.addon.portalkit.configuration.AbstractConfiguration; +import ch.ivy.addon.portalkit.dto.dashboard.Dashboard; +import ch.ivy.addon.portalkit.dto.dashboard.DashboardTemplate; import ch.ivy.addon.portalkit.dto.dashboard.WidgetFilterModel; import ch.ivy.addon.portalkit.persistence.converter.BusinessEntityConverter; import ch.ivyteam.ivy.environment.Ivy; @@ -59,7 +63,8 @@ public List getPublicConfig() { if (StringUtils.isBlank(jsonValue)) { return new ArrayList<>(); } - List entities = BusinessEntityConverter.jsonValueToEntities(jsonValue, getType()); + List entities = Optional.ofNullable(convertToLatestVersion(jsonValue)) + .orElseGet(() -> BusinessEntityConverter.jsonValueToEntities(jsonValue, getType())); entities.forEach(e -> e.setIsPublic(true)); return entities; } @@ -74,14 +79,22 @@ public List getPrivateConfig() { } private List convertToLatestVersion(String jsonValue) { - if (getType() == WidgetFilterModel.class) { - try { - ObjectMapper mapper = new ObjectMapper(); + ObjectMapper mapper = new ObjectMapper(); + try { + if (getType() == WidgetFilterModel.class) { JsonDashboardFilterMigrator migrator = new JsonDashboardFilterMigrator(mapper.readTree(jsonValue)); return BusinessEntityConverter.convertJsonNodeToList(migrator.migrate(), getType()); - } catch (JsonProcessingException ex) { - Ivy.log().error("Failed to read dashboard template from JSON {0}", ex, jsonValue); } + if (getType() == Dashboard.class) { + JsonDashboardMigrator migrator = new JsonDashboardMigrator(mapper.readTree(jsonValue)); + return BusinessEntityConverter.convertJsonNodeToList(migrator.migrate(), getType()); + } + if (getType() == DashboardTemplate.class) { + JsonDashboardTemplateMigrator migrator = new JsonDashboardTemplateMigrator(mapper.readTree(jsonValue)); + return BusinessEntityConverter.convertJsonNodeToList(migrator.migrate(), getType()); + } + } catch (JsonProcessingException ex) { + Ivy.log().error("Failed to read dashboard template from JSON {0}", ex, jsonValue); } return null; } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/service/RegisteredApplicationService.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/service/RegisteredApplicationService.java index 94eb30dc2e1..16c2cb5d57f 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/service/RegisteredApplicationService.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/service/RegisteredApplicationService.java @@ -35,7 +35,7 @@ public List getPublicConfig() { @Override public List saveAllPublicConfig(List application) { - return super.saveAllPublicConfig(getPublicConfig()); + return super.saveAllPublicConfig(application); } @Override diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/service/WidgetFilterService.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/service/WidgetFilterService.java index 9acf4b1cf77..67773e66be9 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/service/WidgetFilterService.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/service/WidgetFilterService.java @@ -155,7 +155,7 @@ public void updateFilterOptionsData(DashboardWidget widget, WidgetFilterModel us case PROCESS: var processWidget = (ProcessDashboardWidget) widget; if (ProcessWidgetMode.COMPACT_MODE == processWidget.getDisplayMode()) { - widgetFilterableColumns.addAll(((CompactProcessDashboardWidget) processWidget).getFilterableColumns()); + widgetFilterableColumns.addAll(processWidget.getFilterableColumns()); } break; default: @@ -174,6 +174,7 @@ public void updateFilterOptionsData(DashboardWidget widget, WidgetFilterModel us private void mergeUserFilterInput(WidgetFilterModel userFilterOptions, ColumnModel column) { userFilterOptions.getFilterableColumns().stream() + .filter(userSelected -> userSelected.getField() != null) .filter(userSelected -> userSelected.getField().equals(column.getField()) && userSelected.getType( )== column.getType()).findFirst() .ifPresent(selectedColumn -> { @@ -203,7 +204,7 @@ public void buildFilterOptions(DashboardWidget widget, List filtera for (var selected : widget.getUserFilterCollection().getSelectedWidgetFilters()) { var selectedColumn = selected.getFilterableColumns().stream() - .filter(compare -> compare.getField().equals(widgetColumn.getField()) + .filter(compare -> compare.getField() != null && compare.getField().equals(widgetColumn.getField()) && compare.getType() == widgetColumn.getType()).findFirst().orElse(null); if (selectedColumn != null) { if (StringUtils.isNotEmpty(selectedColumn.getUserFilter())) { diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/taskfilter/impl/TaskApplicationFilter.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/taskfilter/impl/TaskApplicationFilter.java index ceddb7f86e2..fbb34a3bb7b 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/taskfilter/impl/TaskApplicationFilter.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/taskfilter/impl/TaskApplicationFilter.java @@ -24,7 +24,7 @@ public class TaskApplicationFilter extends TaskFilter { private boolean isSelectedAll; public TaskApplicationFilter() { - this.filteredApplications = IApplicationRepository.instance().allOf(ISecurityContext.current()).stream().map(IApplication::getName).collect(Collectors.toList()); + this.filteredApplications = IApplicationRepository.of(ISecurityContext.current()).all().stream().map(IApplication::getName).collect(Collectors.toList()); this.selectedFilteredApplications = new ArrayList<>(); } @@ -60,7 +60,7 @@ public TaskQuery buildQuery() { TaskQuery query = TaskQuery.create(); IFilterQuery filterQuery = query.where(); selectedFilteredApplications.forEach(applicationName -> { - final List allApps = IApplicationRepository.instance().allOf(ISecurityContext.current()); + final List allApps = IApplicationRepository.of(ISecurityContext.current()).all(); for (IApplication app : allApps) { if (app.getName().equals(applicationName)) { filterQuery.or().applicationId().isEqual(app.getId()); diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/CaseTreeUtils.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/CaseTreeUtils.java index ae841f5ea52..c2637de7754 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/CaseTreeUtils.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/CaseTreeUtils.java @@ -39,7 +39,7 @@ public static CheckboxTreeNode buildCaseCategoryCheckboxTreeRoot() public static CheckboxTreeNode buildCaseCategoryCheckboxTreeRootWithoutAllCategoriesNode() { CheckboxTreeNode root = buildRootWithoutAllCategoriesNode(); CategoryTree allCaseCategories = findAllCategories(); - convertToCheckboxTreeNode((CheckboxTreeNode) root, allCaseCategories); + convertToCheckboxTreeNode(root, allCaseCategories); sortNode(root); return root; } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/CaseUtils.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/CaseUtils.java index 5d2b9ff6332..a475e19bc45 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/CaseUtils.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/CaseUtils.java @@ -16,8 +16,8 @@ import ch.ivyteam.ivy.security.exec.Sudo; import ch.ivyteam.ivy.workflow.CaseState; import ch.ivyteam.ivy.workflow.ICase; -import ch.ivyteam.ivy.workflow.INote; import ch.ivyteam.ivy.workflow.caze.CaseBusinessState; +import ch.ivyteam.ivy.workflow.note.Note; import ch.ivyteam.ivy.workflow.query.CaseQuery; public final class CaseUtils { @@ -39,12 +39,12 @@ public static List findSubCasesByBusinessCaseId(long caseId) { }); } - public static List findNotes(ICase iCase, boolean excludeSystemNotes) { + public static List findNotes(ICase iCase, boolean excludeSystemNotes) { Objects.requireNonNull(iCase, "Case must not be null"); - List notes = iCase.getNotes(); + List notes = iCase.notes().all(); if (excludeSystemNotes) { notes = notes.stream() - .filter(n -> !StringUtils.equals(n.getWritterName(), ISecurityConstants.SYSTEM_USER_NAME)) + .filter(n -> !StringUtils.equals(n.authorName(), ISecurityConstants.SYSTEM_USER_NAME)) .collect(Collectors.toList()); } return new ArrayList<>(notes); diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/CronByGlobalVariableTriggerStartEventBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/CronByGlobalVariableTriggerStartEventBean.java index c1aa8e91fe6..a4a30c6cfd1 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/CronByGlobalVariableTriggerStartEventBean.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/CronByGlobalVariableTriggerStartEventBean.java @@ -7,8 +7,6 @@ import ch.ivyteam.ivy.process.eventstart.AbstractProcessStartEventBean; import ch.ivyteam.ivy.process.eventstart.IProcessStartEventBeanRuntime; import ch.ivyteam.ivy.process.extension.ProgramConfig; -import ch.ivyteam.ivy.process.extension.ui.ExtensionUiBuilder; -import ch.ivyteam.ivy.process.extension.ui.UiEditorExtension; import ch.ivyteam.ivy.request.RequestException; import ch.ivyteam.ivy.vars.Variable; import ch.ivyteam.ivy.vars.Variables; @@ -54,12 +52,4 @@ public void poll() { throw new IvyRuntimeException("Cannot start process", ex); } } - - public static class Editor extends UiEditorExtension { - - @Override - public void initUiFields(ExtensionUiBuilder ui) { - ui.textField(VARIABLE).create(); - } - } } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/DashboardUtils.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/DashboardUtils.java index e7d2c10ff29..ede15c3e5e6 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/DashboardUtils.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/DashboardUtils.java @@ -4,8 +4,14 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; -import java.util.*; +import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; +import java.util.UUID; import java.util.function.Consumer; + import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang3.StringUtils; import org.primefaces.PrimeFaces; @@ -15,12 +21,15 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import ch.addon.portal.generic.menu.MenuView.PortalDashboardItemWrapper; +import ch.ivy.addon.portalkit.constant.IvyCacheIdentifier; import ch.ivy.addon.portalkit.dto.dashboard.Dashboard; import ch.ivy.addon.portalkit.dto.dashboard.DashboardOrder; import ch.ivy.addon.portalkit.dto.dashboard.DashboardTemplate; import ch.ivy.addon.portalkit.enums.PortalVariable; import ch.ivy.addon.portalkit.enums.SessionAttribute; import ch.ivy.addon.portalkit.persistence.converter.BusinessEntityConverter; +import ch.ivy.addon.portalkit.service.IvyCacheService; import ch.ivy.addon.portalkit.service.exception.PortalException; import ch.ivyteam.ivy.environment.Ivy; import ch.ivyteam.ivy.security.ISecurityConstants; @@ -29,13 +38,18 @@ public class DashboardUtils { public final static String DASHBOARD_MENU_PREFIX = "_js__"; - public final static String DASHBOARD_MENU_POSTFIX = "-main-dashboard"; - public final static String DASHBOARD_MENU_ITEM_POSTFIX = "-sub-dashboard"; - public final static String DASHBOARD_MENU_PATTERN = DASHBOARD_MENU_PREFIX + "%s" + DASHBOARD_MENU_POSTFIX; - public final static String DASHBOARD_MENU_ITEM_PATTERN = DASHBOARD_MENU_PREFIX + "%s" + DASHBOARD_MENU_ITEM_POSTFIX; - public final static String DASHBOARD_PAGE_URL = "/ch.ivy.addon.portal.generic.dashboard.PortalDashboard/PortalDashboard.xhtml"; + public final static String PARENT_DASHBOARD_MENU_POSTFIX = "-parent-dashboard"; + public final static String MAIN_DASHBOARD_MENU_POSTFIX = "-main-dashboard"; + public final static String SUB_DASHBOARD_MENU_POSTFIX = "-sub-dashboard"; + public final static String PARENT_DASHBOARD_MENU_PATTERN = DASHBOARD_MENU_PREFIX + "%s" + PARENT_DASHBOARD_MENU_POSTFIX; + public final static String MAIN_DASHBOARD_MENU_PATTERN = DASHBOARD_MENU_PREFIX + "%s" + MAIN_DASHBOARD_MENU_POSTFIX; + public final static String SUB_DASHBOARD_MENU_PATTERN = DASHBOARD_MENU_PREFIX + "%s" + SUB_DASHBOARD_MENU_POSTFIX; + public final static String DASHBOARD_PAGE_URL = + "/ch.ivy.addon.portal.generic.dashboard.PortalDashboard/PortalDashboard.xhtml"; public final static String DASHBOARD_MENU_JS_CLASS = "js-dashboard-group"; public final static String HIGHLIGHT_DASHBOARD_ITEM_METHOD_PATTERN = "highlightDashboardItem('%s')"; + public final static String DEFAULT_TASK_LIST_DASHBOARD = "default-task-list-dashboard"; + public final static String DEFAULT_CASE_LIST_DASHBOARD = "default-case-list-dashboard"; public static List getVisibleDashboards(String dashboardJson) { List dashboards = jsonToDashboards(dashboardJson); @@ -64,6 +78,24 @@ public static List jsonToDashboards(String dashboardJSON) { return mappingDashboards; } + public static Dashboard jsonToDashboard(String dashboardJson) { + if (StringUtils.isBlank(dashboardJson)) { + return null; + } + + ObjectMapper objectMapper = new ObjectMapper(); + Dashboard dashboard = null; + + try { + dashboard = objectMapper.readValue(dashboardJson, Dashboard.class); + initDefaultPermission(); + } catch (IOException e) { + Ivy.log().error("Failed to read dashboard from JSON {0}", e, dashboardJson); + } + + return dashboard; + } + private static Consumer initDefaultPermission() { return dashboard -> { if (CollectionUtils.isEmpty(dashboard.getPermissions())) { @@ -101,10 +133,24 @@ public static List getVisiblePublicDashboards() { public static List getPublicDashboards() { String dashboardJson = Ivy.var().get(PortalVariable.DASHBOARD.key); List visibleDashboards = jsonToDashboards(dashboardJson); + addDefaultTaskCaseListDashboardsIfMissing(visibleDashboards); setDashboardAsPublic(visibleDashboards); return visibleDashboards; } + public static void addDefaultTaskCaseListDashboardsIfMissing(List dashboards) { + if (!hasDashboardWithId(dashboards, DEFAULT_CASE_LIST_DASHBOARD)) { + dashboards.add(0, DefaultDashboardUtils.getDefaultCaseListDashboard()); + } + if (!hasDashboardWithId(dashboards, DEFAULT_TASK_LIST_DASHBOARD)) { + dashboards.add(0, DefaultDashboardUtils.getDefaultTaskListDashboard()); + } + } + + private static boolean hasDashboardWithId(List dashboards, String id) { + return dashboards.stream().map(Dashboard::getId).anyMatch(dashboardId -> id.equals(dashboardId)); + } + public static List getDashboardTemplates() { String dashboardTemplatesJson = Ivy.var().get(PortalVariable.DASHBOARD_TEMPLATES.key); return convertDashboardTemplatesToLatestVersion(dashboardTemplatesJson); @@ -151,25 +197,38 @@ public static List collectDashboards() { } } collectedDashboards.addAll(idToDashboard.values()); + addDefaultTaskCaseListDashboardsIfMissing(collectedDashboards); + return collectedDashboards; + } + public static List collectMainDashboards() { + List collectedDashboards = + new ArrayList<>(getPublicDashboards().stream().filter(dashboard -> dashboard.getIsTopMenu()).toList()); return collectedDashboards; } + public static void highlightDashboardMenuItem(String selectedDashboardId) { PrimeFaces.current().executeScript(String.format(HIGHLIGHT_DASHBOARD_ITEM_METHOD_PATTERN, selectedDashboardId)); } public static void updateSelectedDashboardToSession(String selectedMenuItemId) { - if (StringUtils.endsWithAny(selectedMenuItemId, DASHBOARD_MENU_POSTFIX, DASHBOARD_MENU_ITEM_POSTFIX)) { + if (selectedMenuItemId != null && (selectedMenuItemId.contains(PARENT_DASHBOARD_MENU_POSTFIX) + || selectedMenuItemId.contains(SUB_DASHBOARD_MENU_POSTFIX) + || selectedMenuItemId.contains(MAIN_DASHBOARD_MENU_POSTFIX))) { + String[] menuIds = selectedMenuItemId.split(":"); + String[] dashboardIds = menuIds[menuIds.length - 1].split(DASHBOARD_MENU_PREFIX); - String dashboardId = dashboardIds[dashboardIds.length - 1] - .replace(DASHBOARD_MENU_POSTFIX, "") - .replace(DASHBOARD_MENU_ITEM_POSTFIX, ""); - Ivy.session().setAttribute(SessionAttribute.SELECTED_DASHBOARD_ID.toString(), dashboardId); + + String dashboardId = dashboardIds[dashboardIds.length - 1].replace(PARENT_DASHBOARD_MENU_POSTFIX, "") + .replace(SUB_DASHBOARD_MENU_POSTFIX, "").replace(MAIN_DASHBOARD_MENU_POSTFIX, ""); + + DashboardUtils.storeDashboardInSession(dashboardId); } } + public static List convertDashboardsToLatestVersion(String json) { try { ObjectMapper mapper = new ObjectMapper(); @@ -181,7 +240,8 @@ public static List convertDashboardsToLatestVersion(String json) { return null; } - public static List convertDashboardsFromUploadFileToLatestVersion(InputStream inputStream) throws IOException { + public static List convertDashboardsFromUploadFileToLatestVersion(InputStream inputStream) + throws IOException { try (InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8)) { ObjectMapper mapper = new ObjectMapper(); JsonDashboardMigrator migrator = new JsonDashboardMigrator(mapper.readTree(reader)); @@ -213,9 +273,57 @@ private static List convertDashboardTemplatesToLatestVersion( } return null; } - - + public static void storeDashboardInSession(String id) { + storeDashboardInSession(id, isMainDashboard(id, true)); + } + + public static void storeDashboardInSession(String id, boolean isMainDashboard) { Ivy.session().setAttribute(SessionAttribute.SELECTED_DASHBOARD_ID.toString(), id); + if (!isMainDashboard) { + Ivy.session().setAttribute(SessionAttribute.SELECTED_SUB_DASHBOARD_ID.toString(), id); + } + } + + public static List getDashboardsWithoutMenuItem() { + var dashboards = collectDashboards(); + return dashboards.stream().filter(dashboard -> !dashboard.getIsTopMenu()).toList(); + } + + public static String getSelectedMainDashboardIdFromSession() { + return (String) Ivy.session().getAttribute(SessionAttribute.SELECTED_DASHBOARD_ID.toString()); + } + + private static PortalDashboardItemWrapper getPortalDashboardItemWrapper() { + String sessionUserId = UserUtils.getSessionIdentifierAttribteWithInitIfEmpty(); + return (PortalDashboardItemWrapper) IvyCacheService.getInstance() + .getSessionCacheValue(IvyCacheIdentifier.PORTAL_DASHBOARDS, sessionUserId).orElse(null); } + + public static boolean isMainDashboard(String dashboardId, boolean defaultValue) { + if (StringUtils.isEmpty(dashboardId)) { + return false; + } + boolean isMainDashboard = Optional.ofNullable(getPortalDashboardItemWrapper()) + .map(wrapper -> wrapper.dashboards()).orElse(new ArrayList<>()).stream() + .filter(dashboard -> dashboardId.equals(dashboard.getId())).map(dashboard -> dashboard.getIsTopMenu()) + .findFirst().orElse(defaultValue); + return isMainDashboard; + } + + + /** + * Uses this method before saving a dashboard to simplify generated json from the dashboard + */ + public static void updatePropertiesToNullIfCurrentValueIsDefaultValue(List dashboards) { + if (CollectionUtils.isEmpty(dashboards)) { + return; + } + for (Dashboard dashboard : dashboards) { + if (!dashboard.getIsTopMenu()) { + dashboard.setIsTopMenu(null); + } + } + } + } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/DashboardWidgetUtils.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/DashboardWidgetUtils.java index b9d6e4f2a4a..cae74c02430 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/DashboardWidgetUtils.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/DashboardWidgetUtils.java @@ -165,7 +165,6 @@ public static void buildCustomColumn(Set customFieldMetas, Abs column.setDescription(fieldMeta.get().description()); if (column.getIsCustomAction()) { column.setSortable(false); - column.setStyle(AbstractColumn.EXTRA_WIDTH); } } else if (StringUtils.isBlank(column.getHeader())) { column.setHeader(field); @@ -296,7 +295,7 @@ private static void simplifyColumnData(AbstractColumn column, Set initProcessFilterableColumns() { case CATEGORY -> { columnModel = new ch.ivy.addon.portalkit.dto.dashboard.process.CategoryColumnModel(); } + case DESCRIPTION -> { + columnModel = new ch.ivy.addon.portalkit.dto.dashboard.process.DescriptionColumnModel(); + } default -> { } } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/DefaultDashboardUtils.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/DefaultDashboardUtils.java new file mode 100644 index 00000000000..f092c03fb23 --- /dev/null +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/DefaultDashboardUtils.java @@ -0,0 +1,236 @@ +package ch.ivy.addon.portalkit.util; + +import ch.ivy.addon.portalkit.dto.dashboard.Dashboard; + +public class DefaultDashboardUtils { + + private static String DEFAULT_TASK_LIST_DASHBOARD_JSON = """ + { + "id": "default-task-list-dashboard", + "version": "12.0.0", + "templateId": "create-from-scratch", + "titles": [ + { + "locale": "en", + "value": "Tasks" + }, + { + "locale": "fr", + "value": "Tâches" + }, + { + "locale": "de", + "value": "Aufgaben" + }, + { + "locale": "es", + "value": "Tareas" + } + ], + "icon": "si-task-list-edit", + "description": "Default Task List Dashboard", + "widgets": [ + { + "type": "task", + "id": "default_task_list_dashboard_task_1", + "names": [ + { + "locale": "en", + "value": "Your Tasks" + }, + { + "locale": "de", + "value": "Ihre Aufgaben" + }, + { + "locale": "fr", + "value": "Vos tâches" + }, + { + "locale": "es", + "value": "Sus tareas" + } + ], + "layout": { + "w": 12, + "h": 8, + "x": 0, + "y": 0 + }, + "enableQuickSearch": true, + "columns": [ + { + "field": "start", + "width": "75" + }, + { + "field": "priority", + "width": "70" + }, + { + "field": "id", + "quickSearch": true, + "width": "90" + }, + { + "field": "name", + "quickSearch": true, + "width": "280" + }, + { + "field": "description", + "quickSearch": true, + "width": "280" + }, + { + "field": "activator", + "width": "120" + }, + { + "field": "state", + "width": "80" + }, + { + "field": "startTimestamp", + "width": "95" + }, + { + "field": "expiryTimestamp", + "width": "95" + }, + { + "field": "category", + "width": "105" + }, + { + "field": "actions", + "width": "95" + } + ], + "canWorkOn": false, + "sortField": "id", + "sortDescending": true + } + ], + "permissions": [ + "Everybody" + ], + "isTopMenu": true + } + """; + + private static String DEFAULT_CASE_LIST_DASHBOARD_JSON = """ + { + "id": "default-case-list-dashboard", + "version": "12.0.0", + "templateId": "create-from-scratch", + "titles": [ + { + "locale": "en", + "value": "Cases" + }, + { + "locale": "fr", + "value": "Dossiers" + }, + { + "locale": "de", + "value": "Vorgänge" + }, + { + "locale": "es", + "value": "Casos" + } + ], + "icon": "si-layout-bullets", + "description": "Default Case List Dashboard", + "widgets": [ + { + "type": "case", + "id": "default_case_list_dashboard_case_1", + "names": [ + { + "locale": "en", + "value": "Your Cases" + }, + { + "locale": "de", + "value": "Ihre Vorgänge" + }, + { + "locale": "fr", + "value": "Vos affaires" + }, + { + "locale": "es", + "value": "Sus casos" + } + ], + "layout": { + "w": 12, + "h": 8, + "x": 0, + "y": 0 + }, + "sortDescending": true, + "sortField": "id", + "enableQuickSearch": true, + "columns": [ + { + "field": "id", + "quickSearch": true, + "width": "80" + }, + { + "field": "name", + "quickSearch": true, + "width": "300" + }, + { + "field": "description", + "quickSearch": true, + "width": "300" + }, + { + "field": "creator", + "width": "120" + }, + { + "field": "startTimestamp", + "width": "95" + }, + { + "field": "endTimestamp", + "width": "95" + }, + { + "field": "state", + "width": "80" + }, + { + "field": "category", + "width": "105" + }, + { + "field": "actions", + "width": "95" + } + ] + } + ], + "permissions": [ + "Everybody" + ], + "isTopMenu": true + } + """; + + public static Dashboard getDefaultTaskListDashboard() { + return DashboardUtils.jsonToDashboard(DEFAULT_TASK_LIST_DASHBOARD_JSON); + } + + public static Dashboard getDefaultCaseListDashboard() { + return DashboardUtils.jsonToDashboard(DEFAULT_CASE_LIST_DASHBOARD_JSON); + } + +} diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/LanguageUtils.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/LanguageUtils.java index 250e7d39964..37fd510f52d 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/LanguageUtils.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/LanguageUtils.java @@ -14,7 +14,6 @@ import ch.ivyteam.ivy.environment.Ivy; import ch.ivyteam.ivy.language.LanguageManager; import ch.ivyteam.ivy.security.ISecurityContext; -import ch.ivyteam.ivy.security.ISessionInternal; public final class LanguageUtils { @@ -58,7 +57,7 @@ public static String getUserLanguage() { } public static Locale getUserLocale() { - return ((ISessionInternal) Ivy.session()).getContentLocale(); + return Ivy.session().getContentLocale(); } public static NameResult collectMultilingualNames(List names, String name) { diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/SecurityMemberDisplayNameUtils.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/SecurityMemberDisplayNameUtils.java index 523e266b2ff..84f3bd5f573 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/SecurityMemberDisplayNameUtils.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/SecurityMemberDisplayNameUtils.java @@ -2,6 +2,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; import org.apache.commons.collections4.CollectionUtils; import org.apache.commons.lang.StringUtils; @@ -12,6 +13,7 @@ import ch.ivyteam.ivy.environment.Ivy; import ch.ivyteam.ivy.security.ISecurityMember; import ch.ivyteam.ivy.security.IUser; +import ch.ivyteam.ivy.workflow.caze.owner.CaseOwners; public class SecurityMemberDisplayNameUtils { @@ -22,7 +24,17 @@ public class SecurityMemberDisplayNameUtils { private static final String FORMAT_WITHOUT_DISPLAY_NAME = "<%s> (%s)"; private static final String FORMAT_DISABLED_USER = "%s %s"; - + public static String generateBriefDisplayNameForCaseOwners(CaseOwners owners) { + if (owners == null) { + return ""; + } + return CollectionUtils.emptyIfNull(owners.all()) + .stream() + .map(item -> generateBriefDisplayNameForSecurityMember(item.member(), item.memberName())) + .collect(Collectors.joining(", ")); + } + + public static String generateBriefDisplayNameForSecurityMember(ISecurityMember securityMember, String securityMemberName) { if(StringUtils.isBlank(securityMemberName)) { return Ivy.cms().co(NOT_AVAILABLE_CMS); diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/TaskTreeUtils.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/TaskTreeUtils.java index f8f180aebf9..4fa124ad136 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/TaskTreeUtils.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/TaskTreeUtils.java @@ -43,7 +43,7 @@ public static CheckboxTreeNode buildTaskCategoryCheckboxTreeRoot() public static CheckboxTreeNode buildTaskCategoryCheckboxTreeRootWithoutAllCategoriesNode(){ CheckboxTreeNode root = buildRootWithoutAllCategoriesNode(); CategoryTree allTaskCategories = findAllCategories(); - convertToCheckboxTreeNode((CheckboxTreeNode) root, allTaskCategories); + convertToCheckboxTreeNode(root, allTaskCategories); sortNode(root); return root; } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/TaskUtils.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/TaskUtils.java index ddc85d5a69a..191926fce6a 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/TaskUtils.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/TaskUtils.java @@ -6,6 +6,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Date; +import java.util.EnumSet; import java.util.List; import java.util.stream.Collectors; @@ -21,14 +22,17 @@ import ch.ivy.addon.portalkit.datamodel.internal.RelatedTaskLazyDataModel; import ch.ivy.addon.portalkit.dto.TaskEndInfo; import ch.ivy.addon.portalkit.enums.PortalPage; +import ch.ivy.addon.portalkit.enums.PortalPermission; import ch.ivy.addon.portalkit.enums.SessionAttribute; import ch.ivy.addon.portalkit.ivydata.searchcriteria.TaskSearchCriteria; import ch.ivy.addon.portalkit.service.StickyTaskListService; import ch.ivy.addon.portalkit.service.TaskInforActionService; import ch.ivyteam.ivy.environment.Ivy; +import ch.ivyteam.ivy.security.IPermission; import ch.ivyteam.ivy.security.ISecurityMember; import ch.ivyteam.ivy.security.IUser; import ch.ivyteam.ivy.security.exec.Sudo; +import ch.ivyteam.ivy.security.restricted.permission.IPermissionRepository; import ch.ivyteam.ivy.workflow.ICase; import ch.ivyteam.ivy.workflow.ITask; import ch.ivyteam.ivy.workflow.IWorkflowSession; @@ -120,6 +124,7 @@ public static List getFinishedTasksByCase(ICase iCase) { * @param iTask task need to delegate * @param iSecurityMember */ + @SuppressWarnings("deprecation") public static void delegateTask(final ITask iTask, final ISecurityMember iSecurityMember) { Sudo.get(() -> { iTask.setActivator(iSecurityMember); @@ -233,7 +238,16 @@ public static void handleStartTask(ITask task, PortalPage portalpage, String dia if (task.getBusinessState() == TaskBusinessState.IN_PROGRESS) { handleStartResumedTask(task, dialog); } else { - startTask(task, portalpage); + startTask(task, portalpage, null); + } + } + + public static void handleStartTask(ITask task, PortalPage portalpage, String dialog, String dashboardId) + throws IOException { + if (task.getBusinessState() == TaskBusinessState.IN_PROGRESS) { + handleStartResumedTask(task, dialog); + } else { + startTask(task, portalpage, dashboardId); } } @@ -253,10 +267,10 @@ public static boolean canResume(ITask task) { return sessionUser != null ? task.canUserResumeTask(sessionUser.getUserToken()).wasSuccessful() : false; } - private static void startTask(ITask task, PortalPage currentPortalPage) throws IOException { + private static void startTask(ITask task, PortalPage currentPortalPage, String dashboardId) throws IOException { if (isStartableTask(task)) { if (currentPortalPage != null) { - storeEndInfo(task, null, currentPortalPage); + storeEndInfo(task, null, currentPortalPage, dashboardId); } FacesContext.getCurrentInstance().getExternalContext().redirect(task.getStartLinkEmbedded().getRelative()); } @@ -299,10 +313,14 @@ private static String getNotificationWhenStartTask(ITask task) { return notification; } - private static void storeEndInfo(ITask task, RelatedTaskLazyDataModel dataModel, PortalPage currentPortalPage) { + private static void storeEndInfo(ITask task, RelatedTaskLazyDataModel dataModel, PortalPage currentPortalPage, + String dashboardId) { TaskEndInfo taskEndInfo = new TaskEndInfo(); taskEndInfo.setDataModel(dataModel); taskEndInfo.setPortalPage(currentPortalPage); + if (StringUtils.isNotBlank(dashboardId)) { + taskEndInfo.setDashboardId(dashboardId); + } String taskEndInfoSessionAttributeKey = StickyTaskListService.service().getTaskEndInfoSessionAttributeKey(task.getId()); SecurityServiceUtils.setSessionAttribute(taskEndInfoSessionAttributeKey, taskEndInfo); @@ -351,4 +369,33 @@ public static String convertToUserFriendlyTaskPriority(WorkflowPriority priority return Ivy.cms().co(PRIORITY_CMS_PATH + priority); } + + public static boolean canReset(ITask task) { + if (task == null) { + return false; + } + + EnumSet taskStates = EnumSet.of(TaskState.RESUMED, TaskState.PARKED, TaskState.READY_FOR_JOIN, + TaskState.FAILED); + if (!taskStates.contains(task.getState())) { + return false; + } + + if (task.getState() == TaskState.READY_FOR_JOIN) { + IPermission resetTaskReadyForJoin = IPermissionRepository.instance().findByName(PortalPermission.TASK_RESET_READY_FOR_JOIN.getValue()); + return hasPermission(task, resetTaskReadyForJoin); + } + + + return (hasPermission(task, IPermission.TASK_RESET_OWN_WORKING_TASK) && canResume(task)) + || hasPermission(task, IPermission.TASK_RESET); + } + + private static boolean hasPermission(ITask task, IPermission permission) { + if (task == null || permission == null) { + return false; + } + return PermissionUtils.hasPermission(permission); + } + } diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/UserUtils.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/UserUtils.java index a163649fb83..e05cc7da602 100644 --- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/UserUtils.java +++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/UserUtils.java @@ -6,6 +6,7 @@ import java.util.Date; import java.util.List; import java.util.Locale; +import java.util.UUID; import java.util.stream.Collectors; import org.apache.commons.collections4.CollectionUtils; @@ -17,6 +18,7 @@ import ch.ivy.addon.portalkit.casefilter.impl.CaseFilterData; import ch.ivy.addon.portalkit.constant.PortalConstants; import ch.ivy.addon.portalkit.constant.UserProperty; +import ch.ivy.addon.portalkit.enums.SessionAttribute; import ch.ivy.addon.portalkit.ivydata.service.impl.LanguageService; import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivy.addon.portalkit.taskfilter.TaskFilter; @@ -289,4 +291,12 @@ public static String getUserLanguage() { String systemLanguage = LanguageManager.instance().configurator(ISecurityContext.current()).content().toString(); return StringUtils.defaultIfBlank(userLanguage, systemLanguage); } + + public static String getSessionIdentifierAttribteWithInitIfEmpty() { + String sessionIdAttribute = SessionAttribute.SESSION_IDENTIFIER.toString(); + if (Ivy.session().getAttribute(sessionIdAttribute) == null) { + Ivy.session().setAttribute(sessionIdAttribute, UUID.randomUUID().toString()); + } + return (String) Ivy.session().getAttribute(sessionIdAttribute); + } } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/bean/NotificationBean.java b/AxonIvyPortal/portal/src/com/axonivy/portal/bean/NotificationBean.java index 9463e2596f2..13fea63e014 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/bean/NotificationBean.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/bean/NotificationBean.java @@ -137,20 +137,23 @@ private boolean isWebChannelEnableByUser() { return false; } + public void startTask(NotificationDto dto) { + markAsRead(dto); + PortalNavigator.redirect(dto.getRunAction().getLink().getRelative()); + } + public void startTaskFromNotification(NotificationDto dto, boolean isWorkingTask, ITask task) { if (isWorkingTask && task.getState() != TaskState.DONE) { PrimeFaces.current().executeScript(String.format("checkWarningLogForTaskStart('%s', '%s')", dto.getId(), task.getId())); return; } - markAsRead(dto); - PortalNavigator.redirect(dto.getRunAction().getLink().getRelative()); + startTask(dto); } public void startTaskFromNotiId() { String notificationId = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("notificationId"); NotificationDto dto = dataModel.findById(notificationId); - markAsRead(dto); - PortalNavigator.redirect(dto.getRunAction().getLink().getRelative()); + startTask(dto); } public void goToNotificationDetail(NotificationDto dto, boolean isWorkingTask, ITask task) { @@ -158,8 +161,7 @@ public void goToNotificationDetail(NotificationDto dto, boolean isWorkingTask, I PrimeFaces.current().executeScript(String.format("checkWarningLogForTaskDetail('%s', '%s')", dto.getId(), task.getId())); return; } - markAsRead(dto); - PortalNavigator.redirect(dto.getInfoAction().getLink().getRelative()); + goToTaskDetail(dto); } public void goToTaskDetail(NotificationDto dto) { diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/bean/ai/AssistantResultBean.java b/AxonIvyPortal/portal/src/com/axonivy/portal/bean/ai/AssistantResultBean.java new file mode 100644 index 00000000000..895990e452b --- /dev/null +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/bean/ai/AssistantResultBean.java @@ -0,0 +1,36 @@ +package com.axonivy.portal.bean.ai; + +import java.io.Serializable; + +import javax.faces.bean.ManagedBean; +import javax.faces.bean.ViewScoped; + +import com.axonivy.portal.components.publicapi.PortalNavigatorAPI; + +import ch.ivy.addon.portal.generic.navigation.PortalNavigator; +import ch.ivyteam.ivy.workflow.ICase; +import ch.ivyteam.ivy.workflow.ITask; + +@ManagedBean +@ViewScoped +public class AssistantResultBean implements Serializable { + + private static final long serialVersionUID = -4342231612239885871L; + + public String generateLinkToTaskDetails(ITask workingTask) { + if (workingTask == null) { + return PortalNavigator.getDashboardLink(); + } + + return PortalNavigatorAPI + .buildUrlToPortalTaskDetailsPageByUUID(workingTask.uuid()); + } + + public String generateLinkToCaseDetails(ICase workingCase) { + if (workingCase == null) { + return PortalNavigator.getDashboardLink(); + } + return PortalNavigatorAPI + .buildUrlToPortalCaseDetailsPageByUUID(workingCase.uuid()); + } +} diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/DashboardImportBean.java b/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/DashboardImportBean.java index 465ab92dac1..bd29e132aa7 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/DashboardImportBean.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/DashboardImportBean.java @@ -91,6 +91,9 @@ public void loadImportedFile(FileUploadEvent event) { selectedDashboard.setId(DashboardUtils.generateId()); selectedDashboard.setPermissionDTOs(new ArrayList<>()); findAndSetPermissions(); + if (!isPublicDashboard) { + selectedDashboard.setIsTopMenu(false); + } }); diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/WidgetApplicationFilterBean.java b/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/WidgetApplicationFilterBean.java index 5087b39826a..bb27ff38afa 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/WidgetApplicationFilterBean.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/WidgetApplicationFilterBean.java @@ -29,7 +29,7 @@ public class WidgetApplicationFilterBean implements Serializable { @SuppressWarnings("unchecked") public void init(DashboardFilter filter) { - this.applications = ListUtilities.transformList(IApplicationRepository.instance().allOf(ISecurityContext.current()), + this.applications = ListUtilities.transformList(IApplicationRepository.of(ISecurityContext.current()).all(), IApplication::getName); this.applicationString = String.join(", ", diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/WidgetIdFilterBean.java b/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/WidgetIdFilterBean.java index 0c259dc39e5..2f954a7f6f1 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/WidgetIdFilterBean.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/WidgetIdFilterBean.java @@ -21,6 +21,6 @@ public List getOperators() { return operators; } - public void onChangeOperator(DashboardFilter filter) { + public void onChangeOperator(@SuppressWarnings("unused") DashboardFilter filter) { } } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/WidgetTextFilterBean.java b/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/WidgetTextFilterBean.java index 38ed203b33c..ae339f49a11 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/WidgetTextFilterBean.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/WidgetTextFilterBean.java @@ -21,7 +21,7 @@ public List getOperators() { return operators; } - public void onChangeOperator(DashboardFilter filter) { + public void onChangeOperator(@SuppressWarnings("unused") DashboardFilter filter) { } public boolean isShowTextListPanel(DashboardFilter filter) { diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/filter/AbstractCaseWidgetFilterBean.java b/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/filter/AbstractCaseWidgetFilterBean.java index 105e89815f4..9ff498bb202 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/filter/AbstractCaseWidgetFilterBean.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/filter/AbstractCaseWidgetFilterBean.java @@ -73,7 +73,6 @@ private void initFilters() { * Check if the filter is existing in the filter list or not * * @param filter - * @return */ private boolean isFilterAvaliable(DashboardFilter filter) { return Optional.ofNullable(filter).map(DashboardFilter::getField).isPresent() && filterFields.stream() diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/filter/AbstractTaskWidgetFilterBean.java b/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/filter/AbstractTaskWidgetFilterBean.java index d8be61c1bf0..56c642e657e 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/filter/AbstractTaskWidgetFilterBean.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/filter/AbstractTaskWidgetFilterBean.java @@ -73,7 +73,6 @@ private void initFilters() { * Check if the filter is existing in the filter list or not * * @param filter - * @return */ private boolean isFilterAvaliable(DashboardFilter filter) { return Optional.ofNullable(filter).map(DashboardFilter::getField).isPresent() && filterFields.stream() diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/filter/TaskWidgetUserFilterBean.java b/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/filter/TaskWidgetUserFilterBean.java index d34287c2616..899a8379bc0 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/filter/TaskWidgetUserFilterBean.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/bean/dashboard/filter/TaskWidgetUserFilterBean.java @@ -28,11 +28,11 @@ public class TaskWidgetUserFilterBean extends AbstractTaskWidgetFilterBean imple @Override public void preRender(TaskDashboardWidget widget) { super.preRender(widget); - initUSerFilters(); + initUserFilters(); originalUserFilters = widget.getUserFilters(); } - private void initUSerFilters() { + private void initUserFilters() { if (CollectionUtils.isEmpty(Optional.ofNullable(this.widget).map(TaskDashboardWidget::getUserFilters).get())) { return; } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/bo/jsonversion/AbstractJsonVersion.java b/AxonIvyPortal/portal/src/com/axonivy/portal/bo/jsonversion/AbstractJsonVersion.java index 02cd885de64..0f5d0e370a7 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/bo/jsonversion/AbstractJsonVersion.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/bo/jsonversion/AbstractJsonVersion.java @@ -7,7 +7,7 @@ public abstract class AbstractJsonVersion implements Comparable { public static final String VERSION_FIELD_NAME = "version"; - public static final String LATEST = "11.4.0"; + public static final String LATEST = "12.0.0"; public static final String OLDEST = "10.0.0"; private String value; diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/dto/IvyToolParameter.java b/AxonIvyPortal/portal/src/com/axonivy/portal/dto/IvyToolParameter.java new file mode 100644 index 00000000000..46dcbedf6d5 --- /dev/null +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/dto/IvyToolParameter.java @@ -0,0 +1,22 @@ +package com.axonivy.portal.dto; + +public class IvyToolParameter { + private String name; + private String value; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } +} diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/dto/dashboard/filter/DashboardFilter.java b/AxonIvyPortal/portal/src/com/axonivy/portal/dto/dashboard/filter/DashboardFilter.java index 4acf31754b1..c0134bbcacc 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/dto/dashboard/filter/DashboardFilter.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/dto/dashboard/filter/DashboardFilter.java @@ -46,11 +46,17 @@ public class DashboardFilter implements Serializable { public static final String CREATED_DATE = "startTimestamp"; @JsonIgnore - public static final String DATE_FORMAT = "MM/dd/yyyy"; + public static final String DATE_FORMAT = "MM/dd/yyyy HH:mm"; @JsonIgnore - public static final String DMY_DATE_FORMAT = "dd.MM.yyyy"; - + public static final String DATE_FORMAT_WITHOUT_TIME = "MM/dd/yyyy"; + + @JsonIgnore + public static final String DMY_DATE_FORMAT = "dd.MM.yyyy HH:mm"; + + @JsonIgnore + public static final String DMY_DATE_FORMAT_WITHOUT_TIME = "dd.MM.yyyy"; + @JsonIgnore private static final String DEFAULT = "default"; @@ -230,7 +236,7 @@ public void setTemp(boolean isTemp) { public Date getFromDate() { if (fromDate == null && StringUtils.isNotBlank(from)) { try { - fromDate = DateUtils.parseDate(from, DATE_FORMAT, DMY_DATE_FORMAT); + fromDate = DateUtils.parseDate(from, DATE_FORMAT, DMY_DATE_FORMAT, DATE_FORMAT_WITHOUT_TIME, DMY_DATE_FORMAT_WITHOUT_TIME); } catch (ParseException e) { throw new PortalException("Cannot parse date " + from, e); } @@ -247,7 +253,7 @@ public void setFromDate(Date fromDate) { public Date getToDate() { if (toDate == null && StringUtils.isNotBlank(to)) { try { - toDate = DateUtils.parseDate(to, DATE_FORMAT, DMY_DATE_FORMAT); + toDate = DateUtils.parseDate(to, DATE_FORMAT, DMY_DATE_FORMAT, DATE_FORMAT_WITHOUT_TIME, DMY_DATE_FORMAT_WITHOUT_TIME); } catch (ParseException e) { throw new PortalException("Cannot parse date " + to, e); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboard/converter/JsonDashboardConverterFactory.java b/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboard/converter/JsonDashboardConverterFactory.java index bf0d69b9e90..fb0b1f06dbe 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboard/converter/JsonDashboardConverterFactory.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboard/converter/JsonDashboardConverterFactory.java @@ -17,21 +17,23 @@ public static List getConverters(AbstractJsonVersion version) { private static final List LE112 = List.of( new com.axonivy.portal.migration.dashboard.converter.v112.DashboardCaseWidgetConverter(), - new com.axonivy.portal.migration.dashboard.converter.v112.DashboardTaskWidgetConverter() - ); + new com.axonivy.portal.migration.dashboard.converter.v112.DashboardTaskWidgetConverter()); private static final List LE113 = List.of( new com.axonivy.portal.migration.dashboard.converter.v113.DashboardCaseWidgetConverter(), - new com.axonivy.portal.migration.dashboard.converter.v113.DashboardTaskWidgetConverter() - ); + new com.axonivy.portal.migration.dashboard.converter.v113.DashboardTaskWidgetConverter()); - private static final List LE114 = List.of( - new com.axonivy.portal.migration.dashboard.converter.v114.DashboardProcessWidgetConverter() - ); + private static final List LE114 = List + .of(new com.axonivy.portal.migration.dashboard.converter.v114.DashboardProcessWidgetConverter()); + + private static final List LE120 = List + .of(new com.axonivy.portal.migration.dashboard.converter.v120.DashboardStatisticWidgetConverter()); + static { CONVERTERS.addAll(LE112); CONVERTERS.addAll(LE113); CONVERTERS.addAll(LE114); + CONVERTERS.addAll(LE120); } } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboard/converter/v113/DashboardCaseWidgetConverter.java b/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboard/converter/v113/DashboardCaseWidgetConverter.java index 1fd1b47a409..b569c34fb12 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboard/converter/v113/DashboardCaseWidgetConverter.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboard/converter/v113/DashboardCaseWidgetConverter.java @@ -175,11 +175,11 @@ private void convertDateFilters(ArrayNode filters, JsonNode filterFrom, JsonNode newFilterNode.set("operator", new TextNode(FilterOperator.BETWEEN.getOperator())); if (!isEmptyFilterFrom) { - newFilterNode.set("from", new TextNode(filterFrom.asText())); + newFilterNode.set("from", new TextNode(filterFrom == null ? "" : filterFrom.asText())); } if (!isEmptyFilterTo) { - newFilterNode.set("to", new TextNode(filterTo.asText())); + newFilterNode.set("to", new TextNode(filterTo == null ? "" : filterTo.asText())); } } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboard/converter/v113/DashboardTaskWidgetConverter.java b/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboard/converter/v113/DashboardTaskWidgetConverter.java index 7c305bbc671..d22272e8178 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboard/converter/v113/DashboardTaskWidgetConverter.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboard/converter/v113/DashboardTaskWidgetConverter.java @@ -192,11 +192,11 @@ private void convertDateFilters(ArrayNode filters, JsonNode filterFrom, JsonNode newFilterNode.set("operator", new TextNode(FilterOperator.BETWEEN.getOperator())); if (!isEmptyFilterFrom) { - newFilterNode.set("from", new TextNode(filterFrom.asText())); + newFilterNode.set("from", new TextNode(filterFrom == null ? "" : filterFrom.asText())); } if (!isEmptyFilterTo) { - newFilterNode.set("to", new TextNode(filterTo.asText())); + newFilterNode.set("to", new TextNode(filterTo == null ? "" : filterTo.asText())); } } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboard/converter/v120/DashboardStatisticWidgetConverter.java b/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboard/converter/v120/DashboardStatisticWidgetConverter.java new file mode 100644 index 00000000000..121770dd867 --- /dev/null +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboard/converter/v120/DashboardStatisticWidgetConverter.java @@ -0,0 +1,39 @@ +package com.axonivy.portal.migration.dashboard.converter.v120; + +import java.util.Iterator; + +import com.axonivy.portal.bo.jsonversion.AbstractJsonVersion; +import com.axonivy.portal.bo.jsonversion.DashboardJsonVersion; +import com.axonivy.portal.migration.common.IJsonConverter; +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; + +public class DashboardStatisticWidgetConverter implements IJsonConverter { + + @Override + public AbstractJsonVersion version() { + return new DashboardJsonVersion("12.0.0"); + } + + // widget type "statistic" is deprecated and replaced by "client-statistic" + // the Converter will find and remove all "statistic widgets" in the dashboards. + @Override + public void convert(JsonNode jsonNode) { + ArrayNode widgetsArray = (ArrayNode) jsonNode.get("widgets"); + + if (widgetsArray == null) { + return; + } + + // Remove widgets of type "statistic" + Iterator iterator = widgetsArray.iterator(); + while (iterator.hasNext()) { + JsonNode widget = iterator.next(); + if (widget.has("type") && "statistic".equals(widget.get("type").asText())) { + iterator.remove(); // Remove widget of type "statistic" + } + } + + } + +} diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboard/migrator/JsonDashboardMigrator.java b/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboard/migrator/JsonDashboardMigrator.java index 016cfd46c9a..178fb6a7773 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboard/migrator/JsonDashboardMigrator.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboard/migrator/JsonDashboardMigrator.java @@ -63,8 +63,8 @@ private void migrate(JsonNode dashboard) { } private void run(IJsonConverter converter, JsonNode dashboard) { - Ivy.log().info("Converting Portal dashboard " + dashboard.get("id") + " to version "+converter.version().getValue() - +" using "+converter.getClass().getSimpleName()); + Ivy.log().info("Converting Portal dashboard " + dashboard.get("id") + " to version " + + converter.version().getValue() + " using " + converter.getClass().getSimpleName()); converter.convert(dashboard); updateVersion(dashboard); diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboardfilter/converter/v113/DashboardCaseWidgetFilterConverter.java b/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboardfilter/converter/v113/DashboardCaseWidgetFilterConverter.java index 0c4b617d59a..29e1035cf2a 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboardfilter/converter/v113/DashboardCaseWidgetFilterConverter.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboardfilter/converter/v113/DashboardCaseWidgetFilterConverter.java @@ -171,11 +171,11 @@ private void convertDateFilters(ArrayNode filters, JsonNode filterFrom, JsonNode newFilterNode.set("operator", new TextNode(FilterOperator.BETWEEN.getOperator())); if (!isEmptyFilterFrom) { - newFilterNode.set("from", new TextNode(filterFrom.asText())); + newFilterNode.set("from", new TextNode(filterFrom == null ? "" : filterFrom.asText())); } if (!isEmptyFilterTo) { - newFilterNode.set("to", new TextNode(filterTo.asText())); + newFilterNode.set("to", new TextNode(filterTo == null ? "" : filterTo.asText())); } } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboardfilter/converter/v113/DashboardTaskWidgetFilterConverter.java b/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboardfilter/converter/v113/DashboardTaskWidgetFilterConverter.java index d0ced13a3ed..5e429f91378 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboardfilter/converter/v113/DashboardTaskWidgetFilterConverter.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboardfilter/converter/v113/DashboardTaskWidgetFilterConverter.java @@ -160,11 +160,11 @@ private void convertDateFilters(ArrayNode filters, JsonNode filterFrom, JsonNode newFilterNode.set("operator", new TextNode(FilterOperator.BETWEEN.getOperator())); if (!isEmptyFilterFrom) { - newFilterNode.set("from", new TextNode(filterFrom.asText())); + newFilterNode.set("from", new TextNode(filterFrom == null ? "" : filterFrom.asText())); } if (!isEmptyFilterTo) { - newFilterNode.set("to", new TextNode(filterTo.asText())); + newFilterNode.set("to", new TextNode(filterTo == null ? "" : filterTo.asText())); } } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboardtemplate/converter/v113/DashboardTemplateCaseWidgetConverter.java b/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboardtemplate/converter/v113/DashboardTemplateCaseWidgetConverter.java index f7152484e93..698e5792b5b 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboardtemplate/converter/v113/DashboardTemplateCaseWidgetConverter.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboardtemplate/converter/v113/DashboardTemplateCaseWidgetConverter.java @@ -174,11 +174,11 @@ private void convertDateFilters(ArrayNode filters, JsonNode filterFrom, JsonNode newFilterNode.set("operator", new TextNode(FilterOperator.BETWEEN.getOperator())); if (!isEmptyFilterFrom) { - newFilterNode.set("from", new TextNode(filterFrom.asText())); + newFilterNode.set("from", new TextNode(filterFrom == null ? "" : filterFrom.asText())); } if (!isEmptyFilterTo) { - newFilterNode.set("to", new TextNode(filterTo.asText())); + newFilterNode.set("to", new TextNode(filterTo == null ? "" : filterTo.asText())); } } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboardtemplate/converter/v113/DashboardTemplateTaskWidgetConverter.java b/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboardtemplate/converter/v113/DashboardTemplateTaskWidgetConverter.java index bd4b92d70a9..351ffb8819d 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboardtemplate/converter/v113/DashboardTemplateTaskWidgetConverter.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboardtemplate/converter/v113/DashboardTemplateTaskWidgetConverter.java @@ -162,11 +162,11 @@ private void convertDateFilters(ArrayNode filters, JsonNode filterFrom, JsonNode newFilterNode.set("operator", new TextNode(FilterOperator.BETWEEN.getOperator())); if (!isEmptyFilterFrom) { - newFilterNode.set("from", new TextNode(filterFrom.asText())); + newFilterNode.set("from", new TextNode(filterFrom == null ? "" : filterFrom.asText())); } if (!isEmptyFilterTo) { - newFilterNode.set("to", new TextNode(filterTo.asText())); + newFilterNode.set("to", new TextNode(filterTo == null ? "" : filterTo.asText())); } } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboardtemplate/migrator/JsonDashboardTemplateMigrator.java b/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboardtemplate/migrator/JsonDashboardTemplateMigrator.java index 7243775da1d..903e1af95bf 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboardtemplate/migrator/JsonDashboardTemplateMigrator.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/migration/dashboardtemplate/migrator/JsonDashboardTemplateMigrator.java @@ -59,8 +59,8 @@ private void migrate(JsonNode template) { } private void run(IJsonConverter converter, JsonNode template) { - Ivy.log().info("Converting Portal dashboard template " + template.get("id") + " to version "+converter.version().getValue() - +" using "+converter.getClass().getSimpleName()); + Ivy.log().info("Converting Portal dashboard template " + template.get("id") + " to version "+ converter.version().getValue() + + " using "+ converter.getClass().getSimpleName()); Optional.ofNullable(template).map(t -> t.get("dashboard")).ifPresent(dashboard -> { converter.convert(dashboard); diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/payload/ChatbotPayload.java b/AxonIvyPortal/portal/src/com/axonivy/portal/payload/ChatbotPayload.java new file mode 100644 index 00000000000..4ff26d95116 --- /dev/null +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/payload/ChatbotPayload.java @@ -0,0 +1,13 @@ +package com.axonivy.portal.payload; + +public class ChatbotPayload { + private String message; + + public String getMessage() { + return message; + } + + public void setMessage(String message) { + this.message = message; + } +} diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/payload/IvyToolPayload.java b/AxonIvyPortal/portal/src/com/axonivy/portal/payload/IvyToolPayload.java new file mode 100644 index 00000000000..53dd9c54f68 --- /dev/null +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/payload/IvyToolPayload.java @@ -0,0 +1,13 @@ +package com.axonivy.portal.payload; + +public class IvyToolPayload { + private String toolJson; + + public String getToolJson() { + return toolJson; + } + + public void setToolJson(String toolJson) { + this.toolJson = toolJson; + } +} diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/response/ChatBotResponse.java b/AxonIvyPortal/portal/src/com/axonivy/portal/response/ChatBotResponse.java new file mode 100644 index 00000000000..4e6d0a9f293 --- /dev/null +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/response/ChatBotResponse.java @@ -0,0 +1,14 @@ +package com.axonivy.portal.response; + +public class ChatBotResponse { + private String chatResult; + + public String getChatResult() { + return chatResult; + } + + public void setChatResult(String chatResult) { + this.chatResult = chatResult; + } + +} diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/rest/ChatBotRestService.java b/AxonIvyPortal/portal/src/com/axonivy/portal/rest/ChatBotRestService.java new file mode 100644 index 00000000000..d38106741b3 --- /dev/null +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/rest/ChatBotRestService.java @@ -0,0 +1,152 @@ +package com.axonivy.portal.rest; + +import java.util.Date; + +import javax.annotation.security.RolesAllowed; +import javax.ws.rs.NotFoundException; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +import com.axonivy.portal.payload.ChatbotPayload; +import com.google.gson.GsonBuilder; + +import ch.ivy.addon.portal.chat.ChatMessage; +import ch.ivy.addon.portal.chat.GsonUTCDateAdapter; +import ch.ivy.addon.portal.generic.navigation.PortalNavigator; +import ch.ivy.addon.portalkit.bean.SecurityMemberDisplayNameFormatBean; +import ch.ivyteam.ivy.environment.Ivy; +import ch.ivyteam.ivy.security.ISecurityConstants; +import ch.ivyteam.ivy.workflow.CaseState; +import ch.ivyteam.ivy.workflow.ICase; +import ch.ivyteam.ivy.workflow.query.CaseQuery; +import io.swagger.v3.oas.annotations.media.Content; +import io.swagger.v3.oas.annotations.responses.ApiResponse; +import io.swagger.v3.oas.annotations.responses.ApiResponses; + +@Path(value = "chatbot") +@RolesAllowed(value = { ISecurityConstants.TOP_LEVEL_ROLE_NAME }) +public class ChatBotRestService { + + private String userDisplayName; + + @POST + @Path(value = "{clientId}") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", content = { @Content(mediaType = MediaType.APPLICATION_JSON) }) }) + public Response processes(@PathParam("clientId") String clientId, ChatbotPayload payload) { + if (userDisplayName == null) { + SecurityMemberDisplayNameFormatBean nameBean = new SecurityMemberDisplayNameFormatBean(); + userDisplayName = nameBean.generateFullDisplayNameForSecurityMember(Ivy.session().getSessionUser(), + Ivy.session().getSessionUserName()); + } + try { + ChatMessage response = new ChatMessage(); + String content = payload.getMessage(); + if (content.contentEquals("link")) { + mockLinkResponse(response); + } else if (content.contentEquals("frame")) { + mockFrameResponse(response); + } else if (content.contentEquals("json")) { + mockJsonResponse(response); + } else if (content.contentEquals("image")) { + mockImageResponse(response); + } else { + mockDefaultResponse(response); + } + + response.setSentDate(new Date()); + response.setSender(userDisplayName); + + return Response.ok(toJson(response)).build(); + } catch (NotFoundException e) { + return Response.status(Status.NOT_FOUND).entity(e.getMessage()).build(); + } + } + + private void mockImageResponse(ChatMessage response) { + response.setMessage("This is an image of My Profile section\n\nhttps://market.axonivy.com/market-cache/portal/portal-guide/11.1.0/_images/my-profile.png"); + } + + private void mockFrameResponse(ChatMessage response) { + CaseQuery query = CaseQuery.create(); + ICase caze = query.where().state().isEqual(CaseState.DONE).executor().firstResult(); + + if (caze == null) { + response.setMessage("Cannot find case!"); + return; + } + + var link = PortalNavigator.buildPortalCaseDetailInFrameUrl(caze.uuid()); + response.setMessage("Below is the details of most recently done case\n\n"); + } + + private void mockLinkResponse(ChatMessage response) { + response.setMessage("This is a link to Axon ivy website\n\nhttps://www.axonivy.com/"); + } + + private void mockJsonResponse(ChatMessage response) { + response.setMessage(""" + This is an JSON example of Portal Dashboard + + + ```json + [ + { + "id" : "axon-ivy", + "title" : "Axon Ivy", + "permissions": ["#demo"], + "url" : "https://www.axonivy.com/" + }, + { + "id" : "express", + "title" : "Portal Express process", + "permissions": ["Everybody"], + "url" : "Portal Express process" + }, + { + "id" : "re-order-dashboard", + "titles": [ + { + "locale": "en", + "value": "Reorder your dashboards" + }, + { + "locale": "de", + "value": "Dashboards neu anordnen" + } + ], + "permissions": ["Employee", "AXONIVY_PORTAL_ADMIN", "#daniel"], + "url": "Start Processes/ExamplePortalStart/DashboardReorder.ivp", + "params": { + "isPublicDashboard":"false" + } + } + ] + ```"""); + } + + private void mockDefaultResponse(ChatMessage response) { + response.setMessage(""" + Please type 'link', 'json', 'image', or 'frame' to see special elements + + Below is long text example: + + Axon Ivy is a Process Automation Platform that simplifies and automates the interaction of humans with their digital systems. The platform is typically responsible for the most precious business cases where companies produce value. Here is how we do it: + + Visualize + Our platform allows you to document business processes fast and intuitive. A shared view of users, roles, departments and technical systems involved in a business process improves your work. HR recruitment profiles become clearer, bottlenecks become obvious, ideas for effective improvements arise from anyone involved in the process. + + Automate + Documented processes are good. But what you really want is to drive your highly valuable processes automatically. Employees are often interrupted by searching and filtering data from various tools and feeding this data into other technical systems. Even though value is produced in a well-known business case, there is a lack of a straightforward interface that guides the involved users through the process. Valuable data is often segregated and stored in various dedicated technical systems. With Axon Ivy, you can drive your process automatically. Our platform can easily orchestrate people, data and technical systems. You can generate an initial application that leads users through the process without hiring a software engineer. People can contribute to the process by using their favorite devices such as smartphones or workstations. + """); + } + + private String toJson(Object object) { + return new GsonBuilder().registerTypeAdapter(Date.class, new GsonUTCDateAdapter()).setPrettyPrinting() + .disableHtmlEscaping().create().toJson(object); + } +} diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/service/AiService.java b/AxonIvyPortal/portal/src/com/axonivy/portal/service/AiService.java new file mode 100644 index 00000000000..99a440ceada --- /dev/null +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/service/AiService.java @@ -0,0 +1,391 @@ +package com.axonivy.portal.service; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.Optional; + +import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.math.NumberUtils; + +import com.axonivy.portal.components.dto.AiResultDTO; +import com.axonivy.portal.components.dto.UserDTO; +import com.axonivy.portal.components.enums.AIState; +import com.axonivy.portal.components.persistence.converter.BusinessEntityConverter; +import com.axonivy.portal.components.publicapi.AiAssistantAPI; +import com.axonivy.portal.components.service.impl.ProcessService; +import com.axonivy.portal.components.util.UserUtils; +import com.axonivy.portal.dto.IvyToolParameter; +import com.axonivy.portal.util.AiToolUtils; + +import ch.ivy.addon.portalkit.dto.dashboard.CaseDashboardWidget; +import ch.ivy.addon.portalkit.dto.dashboard.CompactProcessDashboardWidget; +import ch.ivy.addon.portalkit.dto.dashboard.TaskDashboardWidget; +import ch.ivy.addon.portalkit.dto.dashboard.process.DashboardProcess; +import ch.ivy.addon.portalkit.ivydata.service.impl.DashboardCaseService; +import ch.ivy.addon.portalkit.ivydata.service.impl.DashboardTaskService; +import ch.ivy.addon.portalkit.util.UrlUtils; +import ch.ivyteam.ivy.application.IApplication; +import ch.ivyteam.ivy.environment.Ivy; +import ch.ivyteam.ivy.workflow.ICase; +import ch.ivyteam.ivy.workflow.ITask; +import ch.ivyteam.ivy.workflow.query.TaskQuery; +import ch.ivyteam.ivy.workflow.start.IWebStartable; + +public class AiService { + private static final String START_PROCESS_SUCCESSFULLY_FORMAT = "Process **%s** is started successfully"; + private static final String START_TASK_SUCCESSFULLY_FORMAT = "Task **%s(#%s)** is started successfully"; + + private static final String TASK_PROCESS_PATH = "/portal/AI Tool Processes/PortalTools/findTasksTool.ivp"; + private static final String CASE_PROCESS_PATH = "/portal/AI Tool Processes/PortalTools/findCasesTool.ivp"; + private static final String PROCESS_PROCESS_PATH = "/portal/AI Tool Processes/PortalTools/findProcessesTool.ivp"; + + private static AiService instance; + + public static AiService getInstance() { + if (instance == null) { + instance = new AiService(); + } + return instance; + } + + public AiResultDTO generateFindTasksAiResult(String taskName, + String taskDescription, String taskState, String taskPriority, + String taskExpiryDateFrom, String taskExpiryDateTo, String onlyMyTask) { + AiResultDTO result = new AiResultDTO(); + + Map params = new HashMap<>(); + params.put("taskName", taskName); + params.put("taskDescription", taskDescription); + params.put("taskState", taskState); + params.put("taskPriority", taskPriority); + params.put("taskExpiryDateFrom", taskExpiryDateFrom); + params.put("taskExpiryDateTo", taskExpiryDateTo); + params.put("onlyMyTask", onlyMyTask); + + String processPath = IApplication.current().getName() + .concat(TASK_PROCESS_PATH); + AiAssistantAPI.addIframeIvyProcessLinkToAiResult(processPath, params, + result); + + if (result.getState() == AIState.ERROR) { + return result; + } + + TaskDashboardWidget taskWidget = AiToolUtils + .convertIvyToolToTaskDashboardWidget(taskName, taskDescription, + taskPriority, taskState, taskExpiryDateFrom, taskExpiryDateTo, + onlyMyTask); + + // we only show 10 first matched results + List foundTasks = DashboardTaskService.getInstance().findByTaskQuery( + taskWidget.getDataModel().getCriteria().buildQuery(), 0, 10); + + if (CollectionUtils.isEmpty(foundTasks)) { + return AiAssistantAPI.generateErrorAiResult( + Ivy.cms().co("/Labels/AI/Error/NoMatchingTask")); + } + + // Create result for AI based on found tasks + String foundTasksStr = Ivy.cms().co("/Labels/AI/FoundTaskHeader") + .concat(System.lineSeparator()); + for (ITask task : foundTasks) { + foundTasksStr = foundTasksStr + .concat(Ivy.cms().co("/Labels/AI/FindTaskAIResult", + Arrays.asList(Long.valueOf(task.getId()).toString(), + task.getName(), task.getDescription(), + task.getBusinessState().name(), task.getPriority().name()))) + .concat(System.lineSeparator()); + } + + result.setResultForAI(foundTasksStr); + result.setState(AIState.DONE); + return result; + } + + public AiResultDTO generateFindCasesAiResult(String caseName, + String caseDescription, String caseState) { + AiResultDTO result = new AiResultDTO(); + + Map params = new HashMap<>(); + params.put("caseName", caseName); + params.put("caseDescription", caseDescription); + params.put("caseState", caseState); + + String processPath = IApplication.current().getName() + .concat(CASE_PROCESS_PATH); + AiAssistantAPI.addIframeIvyProcessLinkToAiResult(processPath, params, + result); + + if (result.getState() == AIState.ERROR) { + return result; + } + + CaseDashboardWidget caseWidget = AiToolUtils + .convertIvyToolToCaseDashboardWidget(caseName, caseDescription, + caseState); + + // we only show 10 first matched results + List foundCases = DashboardCaseService.getInstance().findByCaseQuery( + caseWidget.getDataModel().getCriteria().buildQuery(), 0, 10); + + if (CollectionUtils.isEmpty(foundCases)) { + return AiAssistantAPI.generateErrorAiResult( + Ivy.cms().co("/Labels/AI/Error/NoMatchingCase")); + } + + // Create result for AI based on found tasks + String foundCasesStr = Ivy.cms().co("/Labels/AI/FoundCaseHeader") + .concat(System.lineSeparator()); + + for (ICase caze : foundCases) { + foundCasesStr = foundCasesStr + .concat(Ivy.cms().co("/Labels/AI/FindCaseAIResult", + Arrays.asList(Long.valueOf(caze.getId()).toString(), + caze.getName(), caze.getDescription(), + caze.getBusinessState().name()))) + .concat(System.lineSeparator()); + } + + result.setResultForAI(foundCasesStr); + result.setState(AIState.DONE); + return result; + } + + public AiResultDTO generateFindProcessesAiResult(String processName, + String processDescription) { + AiResultDTO result = new AiResultDTO(); + Map params = new HashMap<>(); + params.put("processName", processName); + params.put("processDescription", processDescription); + + String processPath = IApplication.current().getName() + .concat(PROCESS_PROCESS_PATH); + AiAssistantAPI.addIframeIvyProcessLinkToAiResult(processPath, params, + result); + + CompactProcessDashboardWidget resultWidget = (CompactProcessDashboardWidget) AiToolUtils + .convertIvyToolToProcessDashboardWidget(processName, + processDescription); + resultWidget.filterProcessesByUser(); + List processes = resultWidget.getDisplayProcesses(); + if (CollectionUtils.isEmpty(processes)) { + return AiAssistantAPI.generateErrorAiResult( + Ivy.cms().co("/Labels/AI/Error/NoMatchingProcesses")); + } + String foundProcessStr = Ivy.cms().co("/Labels/AI/FoundProcessesHeader") + .concat(Integer.toString(processes.size())) + .concat(System.lineSeparator()); + for (var process : processes) { + foundProcessStr = foundProcessStr + .concat( + Ivy.cms().co("/Labels/AI/FindProcessAIResult", + Arrays.asList(process.getId(), process.getName(), + process.getDescription()))) + .concat(System.lineSeparator()); + } + result.setResultForAI(foundProcessStr); + result.setState(AIState.DONE); + return result; + } + + public AiResultDTO generateFindUsersAiResult(String username, String role) { + List roleList = StringUtils.isNotBlank(role) ? Arrays.asList(role) + : null; + List foundUsers = UserUtils.findUsers(username, 0, 101, roleList, + Arrays.asList(Ivy.session().getSessionUserName())); + + if (CollectionUtils.isNotEmpty(foundUsers)) { + // Create result for AI based on found users + String foundUsersStr = Ivy.cms().co("/Labels/AI/FoundUsersHeader") + .concat(System.lineSeparator()); + + for (UserDTO user : foundUsers) { + String userState = user.isEnabled() + ? Ivy.cms().coLocale("/ch.ivy.addon.portalkit.ui.jsf/common/active", + Locale.ENGLISH) + : Ivy.cms().coLocale( + "/ch.ivy.addon.portalkit.ui.jsf/common/inactive", + Locale.ENGLISH); + + foundUsersStr = foundUsersStr + .concat(Ivy.cms().co("/Labels/AI/FindUserAIResult", + Arrays.asList(user.getName(), user.getDisplayName(), + user.getEmail(), userState))) + .concat(System.lineSeparator()); + } + + AiResultDTO result = new AiResultDTO(); + result.setResultForAI(foundUsersStr); + result.setResult(foundUsersStr); + result.setState(AIState.DONE); + return result; + + } else { + return AiAssistantAPI.generateErrorAiResult( + Ivy.cms().co("/Labels/AI/Error/CannotFindUser")); + } + } + + public AiResultDTO generateStartTasksAiResult(String taskId) { + if (!NumberUtils.isDigits(taskId)) { + return AiAssistantAPI.generateErrorAiResult( + Ivy.cms().co("/Labels/AI/Error/CannotStartTask")); + } + TaskQuery query = TaskQuery.create(); + query.where().taskId().isEqual(Long.valueOf(taskId)); + + ITask foundTask = Optional.ofNullable( + DashboardTaskService.getInstance().findByTaskQuery(query, 0, 1).get(0)) + .orElse(null); + + if (foundTask == null || !foundTask + .canUserResumeTask(Ivy.session().getSessionUser().getUserToken()) + .wasSuccessful()) { + return AiAssistantAPI.generateErrorAiResult( + Ivy.cms().co("/Labels/AI/Error/CannotStartTask", + Arrays.asList(Long.toString(foundTask.getId())))); + } + + AiResultDTO result = new AiResultDTO(); + + result.setResultForAI( + AiAssistantAPI.generateExecutableResult( + foundTask.getStartLinkEmbedded().getRelative())); + + result.setResult(String.format(START_TASK_SUCCESSFULLY_FORMAT, + foundTask.getName(), Long.toString(foundTask.getId()))); + + result.setState(AIState.DONE); + return result; + + } + + public AiResultDTO generateFindTaskDetailsAiResult(String taskId) { + if (!NumberUtils.isDigits(taskId)) { + return AiAssistantAPI.generateErrorAiResult( + Ivy.cms().co("/Labels/AI/Error/NoMatchingTask")); + } + TaskQuery query = TaskQuery.create(); + query.where().taskId().isEqual(Long.valueOf(taskId)); + + ITask foundTask = Optional.ofNullable( + DashboardTaskService.getInstance().findByTaskQuery(query, 0, 1).get(0)) + .orElse(null); + + + if (foundTask == null) { + return AiAssistantAPI.generateErrorAiResult( + Ivy.cms().co("/Labels/AI/Error/NoMatchingTask")); + } + + AiResultDTO result = new AiResultDTO(); + + result.setResultForAI(Ivy.cms().co("/Labels/AI/TaskDetailsResult", + Arrays.asList(foundTask.getName(), Long.toString(foundTask.getId()), + foundTask.getDetailLink().getAbsolute()))); + + result.setResult(result.getResultForAI()); + result.setState(AIState.DONE); + + return result; + + } + + public AiResultDTO generateAIResultForWebstartableInfoById(String processId) { + Optional foundProcessOptional = ProcessService.getInstance() + .findAllProcesses().stream() + .filter(process -> process.getId().contentEquals(processId)) + .findFirst(); + + // If cannot find process with the given ID, return error + if (foundProcessOptional.isEmpty()) { + return AiAssistantAPI.createSomethingWentWrongError(); + } + + AiResultDTO result = new AiResultDTO(); + updateResultForWebstartableInfo(result, foundProcessOptional.get()); + result.setState(AIState.DONE); + return result; + } + + private void updateResultForWebstartableInfo(AiResultDTO resultDTO, + IWebStartable process) { + List params = new ArrayList<>(); + params.addAll( + Arrays.asList(process.getDisplayName(), process.getDescription())); + + if (CollectionUtils.isEmpty(process.parameters())) { + String resultStr = Ivy.cms().co("/Labels/AI/ProcessInfoHeader", params); + resultDTO.setResult(resultStr); + resultDTO.setResultForAI(resultStr); + return; + } else { + params.add(Integer.toString(process.parameters().size())); + String resultStr = Ivy.cms() + .co("/Labels/AI/ProcessInfoHeaderWithParameters", params) + .concat(System.lineSeparator()); + + String resultForAIStr = Ivy.cms() + .co("/Labels/AI/ProcessInfoHeaderWithParameters", params) + .concat(System.lineSeparator()); + + for (var param : process.parameters()) { + List subParams = Arrays.asList(param.name(), + param.description()); + + resultForAIStr = resultForAIStr.concat( + Ivy.cms().co("/Labels/AI/ProcessParameterInfoWithValue", subParams)) + .concat(System.lineSeparator()); + + resultStr = resultStr + .concat(Ivy.cms().co("/Labels/AI/ProcessParameterInfo", subParams)) + .concat(System.lineSeparator()); + + resultDTO.setResult(resultStr); + resultDTO.setResultForAI(resultForAIStr); + } + } + } + + public static AiResultDTO generateAiResultForStartProcess(String processId, + String parameters) throws IOException { + if (StringUtils.isBlank(processId)) { + return AiAssistantAPI.createSomethingWentWrongError(); + } + + List params = new ArrayList<>(); + if (StringUtils.isNotBlank(parameters)) { + params = BusinessEntityConverter.jsonValueToEntities(parameters, + IvyToolParameter.class); + } + + IWebStartable startable = ProcessService.getInstance().findAllProcesses() + .stream().filter(process -> process.getId().contentEquals(processId)) + .findFirst().get(); + AiResultDTO result = new AiResultDTO(); + result.setState(AIState.DONE); + result.setResult(String.format(START_PROCESS_SUCCESSFULLY_FORMAT, + startable.getDisplayName())); + + String startLink = startable.getLink().getAbsolute(); + if (!startLink.contains("?")) { + startLink = startLink.concat("?"); + } + + Map paramsMap = new HashMap<>(); + for (var param : params) { + paramsMap.put(param.getName(), param.getValue()); + } + startLink = startLink.concat(UrlUtils.buildUrlQueryString(paramsMap)); + + result.setResultForAI(AiAssistantAPI + .generateExecutableResult(startLink)); + return result; + } +} diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/AiToolUtils.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/AiToolUtils.java new file mode 100644 index 00000000000..f6a946de122 --- /dev/null +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/AiToolUtils.java @@ -0,0 +1,442 @@ +package com.axonivy.portal.util; + +import java.text.ParseException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Date; +import java.util.List; +import java.util.Optional; + +import org.apache.commons.lang3.BooleanUtils; +import org.apache.commons.lang3.StringUtils; + +import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; +import com.axonivy.portal.enums.dashboard.filter.FilterOperator; +import com.axonivy.portal.util.filter.field.FilterField; +import com.axonivy.portal.util.filter.field.FilterFieldFactory; +import com.axonivy.portal.util.filter.field.TaskFilterFieldFactory; + +import ch.ivy.addon.portalkit.bean.DashboardProcessBean; +import ch.ivy.addon.portalkit.dto.dashboard.CaseDashboardWidget; +import ch.ivy.addon.portalkit.dto.dashboard.CompactProcessDashboardWidget; +import ch.ivy.addon.portalkit.dto.dashboard.ProcessDashboardWidget; +import ch.ivy.addon.portalkit.dto.dashboard.TaskDashboardWidget; +import ch.ivy.addon.portalkit.dto.dashboard.casecolumn.CaseColumnModel; +import ch.ivy.addon.portalkit.dto.dashboard.process.DescriptionColumnModel; +import ch.ivy.addon.portalkit.dto.dashboard.process.NameColumnModel; +import ch.ivy.addon.portalkit.dto.dashboard.process.ProcessColumnModel; +import ch.ivy.addon.portalkit.dto.dashboard.taskcolumn.TaskColumnModel; +import ch.ivy.addon.portalkit.enums.DashboardColumnType; +import ch.ivy.addon.portalkit.enums.DashboardStandardCaseColumn; +import ch.ivy.addon.portalkit.enums.DashboardStandardProcessColumn; +import ch.ivy.addon.portalkit.enums.DashboardStandardTaskColumn; +import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; +import ch.ivy.addon.portalkit.util.DashboardWidgetUtils; +import ch.ivyteam.ivy.environment.Ivy; +import ch.ivyteam.ivy.workflow.WorkflowPriority; +import ch.ivyteam.ivy.workflow.caze.CaseBusinessState; +import ch.ivyteam.ivy.workflow.task.TaskBusinessState; + +public class AiToolUtils { + + private static final String DEFAULT_AI_WIDGET_ID = "ai-result"; + private static final String DEFAULT_MAX_WIDTH_STYLE = "max-width: 150px;"; + private static final String DEFAULT_NAME_MIN_WITH_STYLE = "min-width: 200px;"; + + public static TaskDashboardWidget convertIvyToolToTaskDashboardWidget( + String name, String description, String priority, String state, + String taskExpiryDateFrom, String taskExpiryDateTo, String onlyMyTask) { + + TaskDashboardWidget result = DashboardWidgetUtils + .buildDefaultTaskWidget(DEFAULT_AI_WIDGET_ID, DEFAULT_AI_WIDGET_ID); + List columns = new ArrayList<>(); + + result.setFilters(new ArrayList<>()); + + + for (TaskColumnModel col : result.getColumns()) { + DashboardStandardTaskColumn colEnum = DashboardStandardTaskColumn + .findBy(col.getField()); + if (!DashboardStandardTaskColumn.AI_RESULT_COLUMNS.contains(colEnum)) { + col.setVisible(false); + } + + switch (colEnum) { + case ID, ACTIONS -> col.setStyle(DEFAULT_MAX_WIDTH_STYLE); + case NAME -> { + if (StringUtils.isNotBlank(name)) { + result.getFilters().add(initTaskNameFilter(name)); + } + col.setStyle(DEFAULT_NAME_MIN_WITH_STYLE); + } + case DESCRIPTION -> { + if (StringUtils.isNotBlank(description)) { + result.getFilters().add(initTaskDescriptionFilter(description)); + } + } + case PRIORITY ->{ + if (StringUtils.isNotBlank(priority)) { + result.getFilters().add(initTaskPriorityFilter(priority)); + } + } + case STATE -> { + if (StringUtils.isNotBlank(state)) { + result.getFilters().add(initTaskStateFilter(state)); + } + } + case EXPIRY -> { + if (StringUtils.isNotBlank(taskExpiryDateFrom) + || StringUtils.isNotBlank(taskExpiryDateTo)) { + result.getFilters().add( + initTaskExpiryDateFilter(taskExpiryDateFrom, taskExpiryDateTo)); + } + } + default -> {} + } + } + + if (StringUtils.isNotBlank(onlyMyTask) + && BooleanUtils.toBoolean(onlyMyTask)) { + DashboardFilter filter = new DashboardFilter(); + filter.setField(DashboardStandardTaskColumn.RESPONSIBLE.getField()); + filter.setFilterType(DashboardColumnType.STANDARD); + + FilterField field = TaskFilterFieldFactory + .findBy(DashboardStandardTaskColumn.RESPONSIBLE.getField()); + filter.setFilterField(field); + field.addNewFilter(filter); + filter.setValues(Arrays.asList(Ivy.session().getSessionUserName())); + result.getFilters().add(filter); + } + + result.buildFilterableColumns(columns); + + return result; + } + + private static DashboardFilter initTaskNameFilter(String name) { + DashboardFilter filter = new DashboardFilter(); + filter.setField(DashboardStandardTaskColumn.NAME.getField()); + filter.setFilterType(DashboardColumnType.STANDARD); + + FilterField field = TaskFilterFieldFactory + .findBy(DashboardStandardTaskColumn.NAME.getField()); + filter.setFilterField(field); + field.addNewFilter(filter); + filter.setValues(Arrays.asList(name)); + return filter; + } + + private static DashboardFilter initTaskDescriptionFilter(String description) { + DashboardFilter filter = new DashboardFilter(); + filter.setField(DashboardStandardTaskColumn.DESCRIPTION.getField()); + filter.setFilterType(DashboardColumnType.STANDARD); + + FilterField field = TaskFilterFieldFactory + .findBy(DashboardStandardTaskColumn.DESCRIPTION.getField()); + filter.setFilterField(field); + field.addNewFilter(filter); + filter.setValues(Arrays.asList(description)); + return filter; + } + + private static DashboardFilter initTaskPriorityFilter(String priority) { + Optional> priorities = Optional + .ofNullable(Arrays.asList(priority.split(","))); + + if (priorities.isEmpty()) { + return null; + } + + DashboardFilter filter = new DashboardFilter(); + filter.setField(DashboardStandardTaskColumn.PRIORITY.getField()); + filter.setFilterType(DashboardColumnType.STANDARD); + + FilterField field = TaskFilterFieldFactory + .findBy(DashboardStandardTaskColumn.PRIORITY.getField()); + filter.setFilterField(field); + field.addNewFilter(filter); + filter.setValues(new ArrayList<>()); + + for (String priorityStr : priorities.get()) { + WorkflowPriority priorityEnum = initPriority(priorityStr); + if (priorityEnum != null) { + filter.getValues().add(priorityEnum.name()); + } + } + + return filter; + } + + private static DashboardFilter initTaskStateFilter(String state) { + Optional> states = Optional + .ofNullable(Arrays.asList(state.split(","))); + + if (states.isEmpty()) { + return null; + } + + DashboardFilter filter = new DashboardFilter(); + filter.setField(DashboardStandardTaskColumn.STATE.getField()); + filter.setFilterType(DashboardColumnType.STANDARD); + + FilterField field = TaskFilterFieldFactory + .findBy(DashboardStandardTaskColumn.STATE.getField()); + filter.setFilterField(field); + field.addNewFilter(filter); + filter.setValues(new ArrayList<>()); + + for (String stateStr : states.get()) { + TaskBusinessState stateEnum = initTaskState(stateStr); + if (stateEnum != null) { + filter.getValues().add(stateEnum.name()); + } + } + + return filter; + } + + private static DashboardFilter initTaskExpiryDateFilter(String expiryDateFrom, + String expiryDateTo) { + Date fromDate = null; + Date toDate = null; + try { + fromDate = DateTimeGlobalSettingService.getInstance() + .getDefaultDateFormatter().parse(expiryDateFrom); + toDate = DateTimeGlobalSettingService.getInstance() + .getDefaultDateFormatter().parse(expiryDateTo); + } catch (ParseException e) { + return null; + } + + DashboardFilter filter = new DashboardFilter(); + filter.setField(DashboardStandardTaskColumn.EXPIRY.getField()); + filter.setFilterType(DashboardColumnType.STANDARD); + + FilterField field = TaskFilterFieldFactory + .findBy(DashboardStandardTaskColumn.EXPIRY.getField()); + filter.setFilterField(field); + field.addNewFilter(filter); + + filter.setFrom(expiryDateFrom); + filter.setFromDate(fromDate); + filter.setTo(expiryDateTo); + filter.setToDate(toDate); + filter.setOperator(FilterOperator.BETWEEN); + return filter; + } + + public static CaseDashboardWidget convertIvyToolToCaseDashboardWidget( + String name, String description, String state) { + + CaseDashboardWidget result = DashboardWidgetUtils + .buildDefaultCaseWidget(DEFAULT_AI_WIDGET_ID, DEFAULT_AI_WIDGET_ID); + List columns = new ArrayList<>(); + + result.setFilters(new ArrayList<>()); + + for (CaseColumnModel col : result.getColumns()) { + DashboardStandardCaseColumn colEnum = DashboardStandardCaseColumn + .findBy(col.getField()); + + if (!DashboardStandardCaseColumn.AI_RESULT_COLUMNS.contains(colEnum)) { + col.setVisible(false); + } + + switch (colEnum) { + case ID, ACTIONS -> col.setStyle(DEFAULT_MAX_WIDTH_STYLE); + case NAME -> { + if (StringUtils.isNotBlank(name)) { + result.getFilters().add(initCaseNameFilter(name)); + } + } + case DESCRIPTION -> { + if (StringUtils.isNotBlank(description)) { + result.getFilters().add(initCaseDescriptionFilter(name)); + } + } + case STATE -> { + if (StringUtils.isNotBlank(state)) { + result.getFilters().add(initCaseStateFilter(state)); + } + } + default -> {} + } + } + + result.buildFilterableColumns(columns); + + return result; + } + + public static ProcessDashboardWidget convertIvyToolToProcessDashboardWidget( + String name, String description) { + CompactProcessDashboardWidget result = (CompactProcessDashboardWidget) DashboardWidgetUtils + .buildDefaultProcessWidget(DEFAULT_AI_WIDGET_ID, DEFAULT_AI_WIDGET_ID); + List columns = new ArrayList<>(); + + if (StringUtils.isNotBlank(name)) { + NameColumnModel nameCol = new NameColumnModel(); + nameCol.setUserFilter(name); + nameCol.setField(DashboardStandardProcessColumn.NAME.getField()); + columns.add(nameCol); + } + + if (StringUtils.isNotBlank(description)) { + DescriptionColumnModel descriptionCol = new DescriptionColumnModel(); + descriptionCol.setUserFilter(description); + descriptionCol + .setField(DashboardStandardProcessColumn.DESCRIPTION.getField()); + columns.add(descriptionCol); + } + + result.buildFilterableColumns(columns); + + // Init processes + DashboardProcessBean bean = new DashboardProcessBean(); + bean.init(); + result.setOriginalDisplayProcesses(bean.getPortalDashboardProcesses()); + return result; + } + + private static DashboardFilter initCaseNameFilter(String name) { + DashboardFilter filter = new DashboardFilter(); + filter.setField(DashboardStandardCaseColumn.NAME.getField()); + filter.setFilterType(DashboardColumnType.STANDARD); + + FilterField field = FilterFieldFactory + .findBy(DashboardStandardCaseColumn.NAME.getField()); + filter.setFilterField(field); + field.addNewFilter(filter); + filter.setValues(Arrays.asList(name)); + return filter; + } + + private static DashboardFilter initCaseDescriptionFilter(String description) { + DashboardFilter filter = new DashboardFilter(); + filter.setField(DashboardStandardCaseColumn.DESCRIPTION.getField()); + filter.setFilterType(DashboardColumnType.STANDARD); + + FilterField field = FilterFieldFactory + .findBy(DashboardStandardCaseColumn.DESCRIPTION.getField()); + filter.setFilterField(field); + field.addNewFilter(filter); + filter.setValues(Arrays.asList(description)); + return filter; + } + + private static DashboardFilter initCaseStateFilter(String state) { + Optional> states = Optional + .ofNullable(Arrays.asList(state.split(","))); + + if (states.isEmpty()) { + return null; + } + + DashboardFilter filter = new DashboardFilter(); + filter.setField(DashboardStandardCaseColumn.STATE.getField()); + filter.setFilterType(DashboardColumnType.STANDARD); + + FilterField field = FilterFieldFactory + .findBy(DashboardStandardCaseColumn.STATE.getField()); + filter.setFilterField(field); + field.addNewFilter(filter); + filter.setValues(new ArrayList<>()); + + for (String stateStr : states.get()) { + CaseBusinessState stateEnum = initCaseState(stateStr); + if (stateEnum != null) { + filter.getValues().add(stateEnum.name()); + } + } + + return filter; + } + + private static WorkflowPriority initPriority(String priority) { + for (var prioEnum : WorkflowPriority.values()) { + if (prioEnum.name().toLowerCase().contentEquals( + Optional.ofNullable(priority).orElse("").toLowerCase())) { + return prioEnum; + } + } + return null; + } + + private static TaskBusinessState initTaskState(String state) { + for (var stateEnum : TaskBusinessState.values()) { + if (stateEnum.name().toLowerCase() + .contentEquals(Optional.ofNullable(state).orElse("").toLowerCase())) { + return stateEnum; + } + } + return null; + } + + private static CaseBusinessState initCaseState(String state) { + for (var stateEnum : CaseBusinessState.values()) { + if (stateEnum.name().toLowerCase() + .contentEquals(Optional.ofNullable(state).orElse("").toLowerCase())) { + return stateEnum; + } + } + return null; + } + + public static String validateTaskState(String stateStr) { + if (StringUtils.isBlank(stateStr)) { + return null; + } + + List states = Optional + .ofNullable(Arrays.asList(stateStr.split(","))) + .orElse(Collections.emptyList()); + + for (String state : states) { + TaskBusinessState stateEnum = initTaskState(state); + if (stateEnum == null) { + return Ivy.cms().co("/Labels/AI/Error/InvalidTaskState"); + } + } + + return null; + } + + public static String validateTaskPriority(String priorityStr) { + if (StringUtils.isBlank(priorityStr)) { + return null; + } + + List priorities = Optional + .ofNullable(Arrays.asList(priorityStr.split(","))) + .orElse(Collections.emptyList()); + + for (String priority : priorities) { + WorkflowPriority priorityEnum = initPriority(priority); + if (priorityEnum == null) { + return Ivy.cms().co("/Labels/AI/Error/InvalidTaskPriority"); + } + } + + return null; + } + + public static String validateCaseState(String stateStr) { + if (StringUtils.isBlank(stateStr)) { + return null; + } + + List states = Optional + .ofNullable(Arrays.asList(stateStr.split(","))) + .orElse(Collections.emptyList()); + + for (String state : states) { + CaseBusinessState stateEnum = initCaseState(state); + if (stateEnum == null) { + return Ivy.cms().co("/Labels/AI/Error/InvalidTaskState"); + } + } + return null; + } +} diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/PortalDateUtils.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/PortalDateUtils.java index eb9b228bf18..79fee505ba6 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/PortalDateUtils.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/PortalDateUtils.java @@ -95,4 +95,20 @@ public static Date getDayByPeriod(Long period) { private static Date toDate(LocalDate localDate) { return Date.from(localDate.atStartOfDay(ZoneId.systemDefault()).toInstant()); } + + public static Date getEndOfMinute(Date date) { + if (date == null) { + return null; + } + + return DateUtils.addMilliseconds(DateUtils.ceiling(date, Calendar.MINUTE), -1); + } + + public static Date getStartOfMinute(Date date) { + if (date == null) { + return null; + } + + return DateUtils.truncate(date, Calendar.MINUTE); + } } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/FilterFieldDefault.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/FilterFieldDefault.java index fec76d30ba9..7e1024b8787 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/FilterFieldDefault.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/FilterFieldDefault.java @@ -12,6 +12,7 @@ public FilterFieldDefault() { super(FilterFieldFactory.DEFAULT_FILTER_FIELD); } + @Override public String getLabel() { return Ivy.cms() .co("/ch.ivy.addon.portalkit.ui.jsf/adminSettings/pleaseSelect"); diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldApplication.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldApplication.java index 2df0c2a1d31..04aa207f07c 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldApplication.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldApplication.java @@ -18,6 +18,7 @@ public CaseFilterFieldApplication() { super(DashboardStandardCaseColumn.APPLICATION.getField()); } + @Override public String getLabel() { return DashboardStandardCaseColumn.APPLICATION.getLabel(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldCategory.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldCategory.java index 078a05f7331..e21fce00b3c 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldCategory.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldCategory.java @@ -20,6 +20,7 @@ public CaseFilterFieldCategory() { super(DashboardStandardCaseColumn.CATEGORY.getField()); } + @Override public String getLabel() { return DashboardStandardCaseColumn.CATEGORY.getLabel(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldCreatedDate.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldCreatedDate.java index bcfab754ce6..7fc44b6ccfc 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldCreatedDate.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldCreatedDate.java @@ -24,6 +24,7 @@ public CaseFilterFieldCreatedDate() { super(DashboardStandardCaseColumn.CREATED.getField()); } + @Override public String getLabel() { return DashboardStandardCaseColumn.CREATED.getLabel(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldCreator.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldCreator.java index 9759872aa50..a376141d931 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldCreator.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldCreator.java @@ -19,6 +19,7 @@ public CaseFilterFieldCreator() { super(DashboardStandardCaseColumn.CREATOR.getField()); } + @Override public String getLabel() { return DashboardStandardCaseColumn.CREATOR.getLabel(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldDescription.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldDescription.java index 535f550fa15..83e002d381b 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldDescription.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldDescription.java @@ -3,8 +3,8 @@ import java.util.ArrayList; import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; -import com.axonivy.portal.enums.dashboard.filter.FilterOperator; import com.axonivy.portal.enums.dashboard.filter.FilterFormat; +import com.axonivy.portal.enums.dashboard.filter.FilterOperator; import com.axonivy.portal.util.filter.field.FilterField; import com.axonivy.portal.util.filter.operator.caze.description.DescriptionContainsOperatorHandler; import com.axonivy.portal.util.filter.operator.caze.description.DescriptionEndWithOperatorHandler; @@ -23,6 +23,7 @@ public CaseFilterFieldDescription() { super(DashboardStandardCaseColumn.DESCRIPTION.getField()); } + @Override public String getLabel() { return DashboardStandardCaseColumn.DESCRIPTION.getLabel(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldFinishedDate.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldFinishedDate.java index a87a4796803..23e925638c1 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldFinishedDate.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldFinishedDate.java @@ -25,6 +25,7 @@ public CaseFilterFieldFinishedDate() { super(DashboardStandardCaseColumn.FINISHED.getField()); } + @Override public String getLabel() { return DashboardStandardCaseColumn.FINISHED.getLabel(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldId.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldId.java index f11c86396b8..146dadae82d 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldId.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldId.java @@ -18,6 +18,7 @@ public CaseFilterFieldId() { super(DashboardStandardCaseColumn.ID.getField()); } + @Override public String getLabel() { return DashboardStandardCaseColumn.ID.getLabel(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldName.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldName.java index a1a9348511a..70391ac9c7b 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldName.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldName.java @@ -3,8 +3,8 @@ import java.util.ArrayList; import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; -import com.axonivy.portal.enums.dashboard.filter.FilterOperator; import com.axonivy.portal.enums.dashboard.filter.FilterFormat; +import com.axonivy.portal.enums.dashboard.filter.FilterOperator; import com.axonivy.portal.util.filter.field.FilterField; import com.axonivy.portal.util.filter.operator.caze.name.NameContainsOperatorHandler; import com.axonivy.portal.util.filter.operator.caze.name.NameEndWithOperatorHandler; @@ -23,6 +23,7 @@ public CaseFilterFieldName() { super(DashboardStandardCaseColumn.NAME.getField()); } + @Override public String getLabel() { return DashboardStandardCaseColumn.NAME.getLabel(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldState.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldState.java index 31c5d607674..96a9470bba7 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldState.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/CaseFilterFieldState.java @@ -18,6 +18,7 @@ public CaseFilterFieldState() { super(DashboardStandardCaseColumn.STATE.getField()); } + @Override public String getLabel() { return DashboardStandardCaseColumn.STATE.getLabel(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/custom/CaseFilterFieldCustomNumber.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/custom/CaseFilterFieldCustomNumber.java index 1444b1cbe1e..49e1855d9cc 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/custom/CaseFilterFieldCustomNumber.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/custom/CaseFilterFieldCustomNumber.java @@ -1,8 +1,8 @@ package com.axonivy.portal.util.filter.field.caze.custom; import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; -import com.axonivy.portal.enums.dashboard.filter.FilterOperator; import com.axonivy.portal.enums.dashboard.filter.FilterFormat; +import com.axonivy.portal.enums.dashboard.filter.FilterOperator; import com.axonivy.portal.util.filter.field.CustomFilterField; import com.axonivy.portal.util.filter.operator.caze.customfield.CustomNumberBetweenOperatorHandler; import com.axonivy.portal.util.filter.operator.caze.customfield.CustomNumberEmptyOperatorHandler; @@ -26,6 +26,7 @@ public CaseFilterFieldCustomNumber(ICustomFieldMeta customField) { this.customField = customField; } + @Override public String getLabel() { return customField.label(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/custom/CaseFilterFieldCustomString.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/custom/CaseFilterFieldCustomString.java index 73ef100d124..35633bce194 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/custom/CaseFilterFieldCustomString.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/custom/CaseFilterFieldCustomString.java @@ -3,8 +3,8 @@ import java.util.ArrayList; import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; -import com.axonivy.portal.enums.dashboard.filter.FilterOperator; import com.axonivy.portal.enums.dashboard.filter.FilterFormat; +import com.axonivy.portal.enums.dashboard.filter.FilterOperator; import com.axonivy.portal.util.filter.field.CustomFilterField; import com.axonivy.portal.util.filter.operator.caze.customfield.CustomStringContainsOperatorHandler; import com.axonivy.portal.util.filter.operator.caze.customfield.CustomStringEndWithOperatorHandler; @@ -28,6 +28,7 @@ public CaseFilterFieldCustomString(ICustomFieldMeta customField) { this.customField = customField; } + @Override public String getLabel() { return customField.label(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/custom/CaseFilterFieldCustomText.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/custom/CaseFilterFieldCustomText.java index be99f8682a2..1757b4519bc 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/custom/CaseFilterFieldCustomText.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/custom/CaseFilterFieldCustomText.java @@ -3,8 +3,8 @@ import java.util.ArrayList; import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; -import com.axonivy.portal.enums.dashboard.filter.FilterOperator; import com.axonivy.portal.enums.dashboard.filter.FilterFormat; +import com.axonivy.portal.enums.dashboard.filter.FilterOperator; import com.axonivy.portal.util.filter.field.CustomFilterField; import com.axonivy.portal.util.filter.operator.caze.customfield.CustomTextContainsOperatorHandler; import com.axonivy.portal.util.filter.operator.caze.customfield.CustomTextEndWithOperatorHandler; @@ -28,6 +28,7 @@ public CaseFilterFieldCustomText(ICustomFieldMeta customField) { this.customField = customField; } + @Override public String getLabel() { return customField.label(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/custom/CaseFilterFieldCustomTimestamp.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/custom/CaseFilterFieldCustomTimestamp.java index 9b81df045fd..6241acfc1b3 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/custom/CaseFilterFieldCustomTimestamp.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/caze/custom/CaseFilterFieldCustomTimestamp.java @@ -30,6 +30,7 @@ public CaseFilterFieldCustomTimestamp(ICustomFieldMeta customField) { this.customField = customField; } + @Override public String getLabel() { return customField.label(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldApplication.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldApplication.java index 21e2b48596c..bf553f78959 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldApplication.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldApplication.java @@ -18,6 +18,7 @@ public TaskFilterFieldApplication() { super(DashboardStandardTaskColumn.APPLICATION.getField()); } + @Override public String getLabel() { return DashboardStandardTaskColumn.APPLICATION.getLabel(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldCategory.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldCategory.java index 37f8d193783..8d8d5483f21 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldCategory.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldCategory.java @@ -20,6 +20,7 @@ public TaskFilterFieldCategory() { super(DashboardStandardTaskColumn.CATEGORY.getField()); } + @Override public String getLabel() { return DashboardStandardTaskColumn.CATEGORY.getLabel(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldCreatedDate.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldCreatedDate.java index e1b12430476..6a2b379a545 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldCreatedDate.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldCreatedDate.java @@ -24,6 +24,7 @@ public TaskFilterFieldCreatedDate() { super(DashboardStandardTaskColumn.CREATED.getField()); } + @Override public String getLabel() { return DashboardStandardTaskColumn.CREATED.getLabel(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldDescription.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldDescription.java index 66ce223e553..fae954fe7c5 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldDescription.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldDescription.java @@ -3,8 +3,8 @@ import java.util.ArrayList; import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; -import com.axonivy.portal.enums.dashboard.filter.FilterOperator; import com.axonivy.portal.enums.dashboard.filter.FilterFormat; +import com.axonivy.portal.enums.dashboard.filter.FilterOperator; import com.axonivy.portal.util.filter.field.FilterField; import com.axonivy.portal.util.filter.operator.task.description.DescriptionContainsOperatorHandler; import com.axonivy.portal.util.filter.operator.task.description.DescriptionEndWithOperatorHandler; @@ -23,6 +23,7 @@ public TaskFilterFieldDescription() { super(DashboardStandardTaskColumn.DESCRIPTION.getField()); } + @Override public String getLabel() { return DashboardStandardTaskColumn.DESCRIPTION.getLabel(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldExpiryDate.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldExpiryDate.java index de2e6157d47..85ce67e7143 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldExpiryDate.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldExpiryDate.java @@ -25,6 +25,7 @@ public TaskFilterFieldExpiryDate() { super(DashboardStandardTaskColumn.EXPIRY.getField()); } + @Override public String getLabel() { return DashboardStandardTaskColumn.EXPIRY.getLabel(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldId.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldId.java index 0b0f79ce6fe..454ecaab194 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldId.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldId.java @@ -18,6 +18,7 @@ public TaskFilterFieldId() { super(DashboardStandardTaskColumn.ID.getField()); } + @Override public String getLabel() { return DashboardStandardTaskColumn.ID.getLabel(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldName.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldName.java index 1cd9956603c..4cfa7a76f02 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldName.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldName.java @@ -3,8 +3,8 @@ import java.util.ArrayList; import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; -import com.axonivy.portal.enums.dashboard.filter.FilterOperator; import com.axonivy.portal.enums.dashboard.filter.FilterFormat; +import com.axonivy.portal.enums.dashboard.filter.FilterOperator; import com.axonivy.portal.util.filter.field.FilterField; import com.axonivy.portal.util.filter.operator.task.name.NameContainsOperatorHandler; import com.axonivy.portal.util.filter.operator.task.name.NameEndWithOperatorHandler; @@ -23,6 +23,7 @@ public TaskFilterFieldName() { super(DashboardStandardTaskColumn.NAME.getField()); } + @Override public String getLabel() { return DashboardStandardTaskColumn.NAME.getLabel(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldResponsible.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldResponsible.java index e4402179398..efdfd9dbc2f 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldResponsible.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldResponsible.java @@ -19,6 +19,7 @@ public TaskFilterFieldResponsible() { super(DashboardStandardTaskColumn.RESPONSIBLE.getField()); } + @Override public String getLabel() { return DashboardStandardTaskColumn.RESPONSIBLE.getLabel(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldState.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldState.java index 9fddbbb0c9f..93113dc4488 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldState.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/TaskFilterFieldState.java @@ -18,6 +18,7 @@ public TaskFilterFieldState() { super(DashboardStandardTaskColumn.STATE.getField()); } + @Override public String getLabel() { return DashboardStandardTaskColumn.STATE.getLabel(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/TaskFilterFieldCustomNumber.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/TaskFilterFieldCustomNumber.java index 0f70a921f5a..06848e941eb 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/TaskFilterFieldCustomNumber.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/TaskFilterFieldCustomNumber.java @@ -27,6 +27,7 @@ public TaskFilterFieldCustomNumber(ICustomFieldMeta customField) { this.customField = customField; } + @Override public String getLabel() { return customField.label(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/TaskFilterFieldCustomString.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/TaskFilterFieldCustomString.java index 7df1871dbe3..7c9c993721a 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/TaskFilterFieldCustomString.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/TaskFilterFieldCustomString.java @@ -29,6 +29,7 @@ public TaskFilterFieldCustomString(ICustomFieldMeta customField) { this.customField = customField; } + @Override public String getLabel() { return customField.label(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/TaskFilterFieldCustomText.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/TaskFilterFieldCustomText.java index 4aa2e929860..60f53122724 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/TaskFilterFieldCustomText.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/TaskFilterFieldCustomText.java @@ -29,6 +29,7 @@ public TaskFilterFieldCustomText(ICustomFieldMeta customField) { this.customField = customField; } + @Override public String getLabel() { return customField.label(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/TaskFilterFieldCustomTimestamp.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/TaskFilterFieldCustomTimestamp.java index b2d3c7e162d..09b3282c413 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/TaskFilterFieldCustomTimestamp.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/TaskFilterFieldCustomTimestamp.java @@ -31,6 +31,7 @@ public TaskFilterFieldCustomTimestamp(ICustomFieldMeta customField) { this.customField = customField; } + @Override public String getLabel() { return customField.label(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/caze/TaskFilterCaseFieldCustomNumber.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/caze/TaskFilterCaseFieldCustomNumber.java index ea297de703f..64620f86ded 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/caze/TaskFilterCaseFieldCustomNumber.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/caze/TaskFilterCaseFieldCustomNumber.java @@ -27,6 +27,7 @@ public TaskFilterCaseFieldCustomNumber(ICustomFieldMeta customField) { this.customField = customField; } + @Override public String getLabel() { return customField.label(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/caze/TaskFilterCaseFieldCustomString.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/caze/TaskFilterCaseFieldCustomString.java index 92a5b6133ed..47f06a00a52 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/caze/TaskFilterCaseFieldCustomString.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/caze/TaskFilterCaseFieldCustomString.java @@ -29,6 +29,7 @@ public TaskFilterCaseFieldCustomString(ICustomFieldMeta customField) { this.customField = customField; } + @Override public String getLabel() { return customField.label(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/caze/TaskFilterCaseFieldCustomText.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/caze/TaskFilterCaseFieldCustomText.java index 3278c24fda9..b91097c9439 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/caze/TaskFilterCaseFieldCustomText.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/caze/TaskFilterCaseFieldCustomText.java @@ -29,6 +29,7 @@ public TaskFilterCaseFieldCustomText(ICustomFieldMeta customField) { this.customField = customField; } + @Override public String getLabel() { return customField.label(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/caze/TaskFilterCaseFieldCustomTimestamp.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/caze/TaskFilterCaseFieldCustomTimestamp.java index 01aa63c67cb..b1c5f69788d 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/caze/TaskFilterCaseFieldCustomTimestamp.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/field/task/custom/caze/TaskFilterCaseFieldCustomTimestamp.java @@ -31,6 +31,7 @@ public TaskFilterCaseFieldCustomTimestamp(ICustomFieldMeta customField) { this.customField = customField; } + @Override public String getLabel() { return customField.label(); } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/createddate/CreatedDateAfterOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/createddate/CreatedDateAfterOperatorHandler.java index 37888b9221c..c7146836ae4 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/createddate/CreatedDateAfterOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/createddate/CreatedDateAfterOperatorHandler.java @@ -1,8 +1,11 @@ package com.axonivy.portal.util.filter.operator.caze.createddate; +import java.util.Date; + import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; import com.axonivy.portal.util.PortalDateUtils; +import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivyteam.ivy.workflow.query.CaseQuery; public class CreatedDateAfterOperatorHandler { @@ -21,7 +24,8 @@ public CaseQuery buildQuery(DashboardFilter filter) { } CaseQuery query = CaseQuery.create(); - query.where().startTimestamp().isGreaterThan(PortalDateUtils.getEndOfDate(filter.getToDate())); + Date endDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getToDate()) : PortalDateUtils.getEndOfDate(filter.getToDate()); + query.where().startTimestamp().isGreaterThan(endDate); return query; } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/createddate/CreatedDateBeforeOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/createddate/CreatedDateBeforeOperatorHandler.java index d30594b8c88..483815ac08c 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/createddate/CreatedDateBeforeOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/createddate/CreatedDateBeforeOperatorHandler.java @@ -1,8 +1,11 @@ package com.axonivy.portal.util.filter.operator.caze.createddate; +import java.util.Date; + import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; import com.axonivy.portal.util.PortalDateUtils; +import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivyteam.ivy.workflow.query.CaseQuery; public class CreatedDateBeforeOperatorHandler { @@ -22,7 +25,8 @@ public CaseQuery buildQuery(DashboardFilter filter) { } CaseQuery query = CaseQuery.create(); - query.where().startTimestamp().isLowerThan(PortalDateUtils.getStartOfDate(filter.getFromDate())); + Date fromDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); + query.where().startTimestamp().isLowerThan(fromDate); return query; } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/createddate/CreatedDateBetweenOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/createddate/CreatedDateBetweenOperatorHandler.java index 744b01bc26c..ce4f14c6546 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/createddate/CreatedDateBetweenOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/createddate/CreatedDateBetweenOperatorHandler.java @@ -5,6 +5,7 @@ import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; import com.axonivy.portal.util.PortalDateUtils; +import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivyteam.ivy.workflow.query.CaseQuery; public class CreatedDateBetweenOperatorHandler { @@ -19,8 +20,8 @@ public static CreatedDateBetweenOperatorHandler getInstance() { } public CaseQuery buildBetweenQuery(DashboardFilter filter) { - Date from = PortalDateUtils.getStartOfDate(filter.getFromDate()); - Date to = PortalDateUtils.getEndOfDate(filter.getToDate()); + Date from = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); + Date to = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getToDate()) : PortalDateUtils.getEndOfDate(filter.getToDate()); if (from == null && to == null) { return null; @@ -38,8 +39,8 @@ public CaseQuery buildBetweenQuery(DashboardFilter filter) { } public CaseQuery buildNotBetweenQuery(DashboardFilter filter) { - Date from = PortalDateUtils.getStartOfDate(filter.getFromDate()); - Date to = PortalDateUtils.getEndOfDate(filter.getToDate()); + Date from = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); + Date to = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getToDate()) : PortalDateUtils.getEndOfDate(filter.getToDate()); CaseQuery subQuery = CaseQuery.create(); if (from != null && to != null) { diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/createddate/CreatedDateIsOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/createddate/CreatedDateIsOperatorHandler.java index 5501d7f45cb..195c5dd9351 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/createddate/CreatedDateIsOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/createddate/CreatedDateIsOperatorHandler.java @@ -1,8 +1,11 @@ package com.axonivy.portal.util.filter.operator.caze.createddate; +import java.util.Date; + import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; import com.axonivy.portal.util.PortalDateUtils; +import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivyteam.ivy.workflow.query.CaseQuery; public class CreatedDateIsOperatorHandler { @@ -20,8 +23,11 @@ public CaseQuery buildIsQuery(DashboardFilter filter) { return null; } - return CaseQuery.create().where().startTimestamp().isGreaterOrEqualThan(PortalDateUtils.getStartOfDate(filter.getFromDate())) - .and().startTimestamp().isLowerOrEqualThan(PortalDateUtils.getEndOfDate(filter.getFromDate())); + Date fromDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); + Date endDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getFromDate()) : PortalDateUtils.getEndOfDate(filter.getFromDate()); + + return CaseQuery.create().where().startTimestamp().isGreaterOrEqualThan(fromDate) + .and().startTimestamp().isLowerOrEqualThan(endDate); } public CaseQuery buildIsNotQuery(DashboardFilter filter) { @@ -29,7 +35,10 @@ public CaseQuery buildIsNotQuery(DashboardFilter filter) { return null; } - return CaseQuery.create().where().startTimestamp().isGreaterThan(PortalDateUtils.getEndOfDate(filter.getFromDate())) - .or().startTimestamp().isLowerThan(PortalDateUtils.getStartOfDate(filter.getFromDate())); + Date fromDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); + Date endDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getFromDate()) : PortalDateUtils.getEndOfDate(filter.getFromDate()); + + return CaseQuery.create().where().startTimestamp().isGreaterThan(endDate) + .or().startTimestamp().isLowerThan(fromDate); } } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/customfield/CustomTimestampAfterOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/customfield/CustomTimestampAfterOperatorHandler.java index 47fc768f66e..cc5e8fef44d 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/customfield/CustomTimestampAfterOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/customfield/CustomTimestampAfterOperatorHandler.java @@ -1,8 +1,11 @@ package com.axonivy.portal.util.filter.operator.caze.customfield; +import java.util.Date; + import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; import com.axonivy.portal.util.PortalDateUtils; +import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivyteam.ivy.workflow.query.CaseQuery; public class CustomTimestampAfterOperatorHandler { @@ -21,8 +24,9 @@ public CaseQuery buildQuery(DashboardFilter filter) { } CaseQuery query = CaseQuery.create(); + Date endDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getToDate()) : PortalDateUtils.getEndOfDate(filter.getToDate()); query.where().customField().timestampField(filter.getField()) - .isGreaterThan(PortalDateUtils.getEndOfDate(filter.getToDate())); + .isGreaterThan(endDate); return query; } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/customfield/CustomTimestampBeforeOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/customfield/CustomTimestampBeforeOperatorHandler.java index e8dc464a2f0..fce223bf6ef 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/customfield/CustomTimestampBeforeOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/customfield/CustomTimestampBeforeOperatorHandler.java @@ -1,8 +1,11 @@ package com.axonivy.portal.util.filter.operator.caze.customfield; +import java.util.Date; + import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; import com.axonivy.portal.util.PortalDateUtils; +import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivyteam.ivy.workflow.query.CaseQuery; public class CustomTimestampBeforeOperatorHandler { @@ -22,8 +25,9 @@ public CaseQuery buildQuery(DashboardFilter filter) { } CaseQuery query = CaseQuery.create(); + Date fromDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); query.where().customField().timestampField(filter.getField()) - .isLowerThan(PortalDateUtils.getStartOfDate(filter.getFromDate())); + .isLowerThan(fromDate); return query; } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/customfield/CustomTimestampBetweenOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/customfield/CustomTimestampBetweenOperatorHandler.java index 34df15806f8..ba7c5844a3d 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/customfield/CustomTimestampBetweenOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/customfield/CustomTimestampBetweenOperatorHandler.java @@ -5,6 +5,7 @@ import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; import com.axonivy.portal.util.PortalDateUtils; +import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivyteam.ivy.workflow.query.CaseQuery; public class CustomTimestampBetweenOperatorHandler { @@ -20,8 +21,8 @@ public static CustomTimestampBetweenOperatorHandler getInstance() { public CaseQuery buildBetweenQuery(DashboardFilter filter) { - Date from = PortalDateUtils.getStartOfDate(filter.getFromDate()); - Date to = PortalDateUtils.getEndOfDate(filter.getToDate()); + Date from = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); + Date to = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getToDate()) : PortalDateUtils.getEndOfDate(filter.getToDate()); if (from == null && to == null) { return null; @@ -39,8 +40,8 @@ public CaseQuery buildBetweenQuery(DashboardFilter filter) { } public CaseQuery buildNotBetweenQuery(DashboardFilter filter) { - Date from = PortalDateUtils.getStartOfDate(filter.getFromDate()); - Date to = PortalDateUtils.getEndOfDate(filter.getToDate()); + Date from = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); + Date to = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getToDate()) : PortalDateUtils.getEndOfDate(filter.getToDate()); CaseQuery subQuery = CaseQuery.create(); if (from != null && to != null) { diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/customfield/CustomTimestampIsOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/customfield/CustomTimestampIsOperatorHandler.java index 0e15c8eec1a..1dbb05409cc 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/customfield/CustomTimestampIsOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/customfield/CustomTimestampIsOperatorHandler.java @@ -1,8 +1,11 @@ package com.axonivy.portal.util.filter.operator.caze.customfield; +import java.util.Date; + import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; import com.axonivy.portal.util.PortalDateUtils; +import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivyteam.ivy.workflow.query.CaseQuery; public class CustomTimestampIsOperatorHandler { @@ -20,9 +23,12 @@ public CaseQuery buildIsQuery(DashboardFilter filter) { return null; } + Date fromDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); + Date endDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getFromDate()) : PortalDateUtils.getEndOfDate(filter.getFromDate()); + return CaseQuery.create().where().customField().timestampField(filter.getField()) - .isGreaterOrEqualThan(PortalDateUtils.getStartOfDate(filter.getFromDate())) - .and().customField().timestampField(filter.getField()).isLowerOrEqualThan(PortalDateUtils.getEndOfDate(filter.getFromDate())); + .isGreaterOrEqualThan(fromDate) + .and().customField().timestampField(filter.getField()).isLowerOrEqualThan(endDate); } public CaseQuery buildIsNotQuery(DashboardFilter filter) { @@ -30,8 +36,11 @@ public CaseQuery buildIsNotQuery(DashboardFilter filter) { return null; } + Date fromDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); + Date endDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getFromDate()) : PortalDateUtils.getEndOfDate(filter.getFromDate()); + return CaseQuery.create().where().customField().timestampField(filter.getField()) - .isGreaterThan(PortalDateUtils.getEndOfDate(filter.getFromDate())) - .or().customField().timestampField(filter.getField()).isLowerThan(PortalDateUtils.getStartOfDate(filter.getFromDate())); + .isGreaterThan(endDate) + .or().customField().timestampField(filter.getField()).isLowerThan(fromDate); } } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/customfield/CustomTimestampTodayOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/customfield/CustomTimestampTodayOperatorHandler.java index 28b07ce977c..059d0b39e75 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/customfield/CustomTimestampTodayOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/customfield/CustomTimestampTodayOperatorHandler.java @@ -27,7 +27,6 @@ public CaseQuery buildQuery(DashboardFilter filter) { } private void buildQuery(CaseQuery query, Date from, Date to, DashboardFilter filter) { - ; CaseQuery subQuery = CaseQuery.create(); subQuery.where().customField().timestampField(filter.getField()).isGreaterOrEqualThan(from); subQuery.where().customField().timestampField(filter.getField()).isLowerOrEqualThan(to); diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/description/DescriptionIsEmptyOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/description/DescriptionIsEmptyOperatorHandler.java index 1bfaa58ed3a..db8da9d67f5 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/description/DescriptionIsEmptyOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/description/DescriptionIsEmptyOperatorHandler.java @@ -15,13 +15,13 @@ public static DescriptionIsEmptyOperatorHandler getInstance() { return instance; } - public CaseQuery buildIsEmptyQuery(DashboardFilter filter) { + public CaseQuery buildIsEmptyQuery(@SuppressWarnings("unused") DashboardFilter filter) { CaseQuery subQuery = CaseQuery.create(); subQuery.where().description().isNull().or().description().isLike(""); return subQuery; } - public CaseQuery buildNotEmptyQuery(DashboardFilter filter) { + public CaseQuery buildNotEmptyQuery(@SuppressWarnings("unused") DashboardFilter filter) { CaseQuery subQuery = CaseQuery.create(); subQuery.where().description().isNotNull().and().description().isNotLike(""); return subQuery; diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/finisheddate/FinishedDateAfterOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/finisheddate/FinishedDateAfterOperatorHandler.java index 5ade205349c..d9ab92b76ff 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/finisheddate/FinishedDateAfterOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/finisheddate/FinishedDateAfterOperatorHandler.java @@ -1,8 +1,11 @@ package com.axonivy.portal.util.filter.operator.caze.finisheddate; +import java.util.Date; + import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; import com.axonivy.portal.util.PortalDateUtils; +import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivyteam.ivy.workflow.query.CaseQuery; public class FinishedDateAfterOperatorHandler { @@ -21,7 +24,8 @@ public CaseQuery buildQuery(DashboardFilter filter) { } CaseQuery query = CaseQuery.create(); - query.where().endTimestamp().isGreaterThan(PortalDateUtils.getEndOfDate(filter.getToDate())); + Date endDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getToDate()) : PortalDateUtils.getEndOfDate(filter.getToDate()); + query.where().endTimestamp().isGreaterThan(endDate); return query; } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/finisheddate/FinishedDateBeforeOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/finisheddate/FinishedDateBeforeOperatorHandler.java index 84994816a72..ecb26944ed5 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/finisheddate/FinishedDateBeforeOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/finisheddate/FinishedDateBeforeOperatorHandler.java @@ -1,8 +1,11 @@ package com.axonivy.portal.util.filter.operator.caze.finisheddate; +import java.util.Date; + import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; import com.axonivy.portal.util.PortalDateUtils; +import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivyteam.ivy.workflow.query.CaseQuery; public class FinishedDateBeforeOperatorHandler { @@ -22,7 +25,8 @@ public CaseQuery buildQuery(DashboardFilter filter) { } CaseQuery query = CaseQuery.create(); - query.where().endTimestamp().isLowerThan(PortalDateUtils.getStartOfDate(filter.getFromDate())); + Date fromDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); + query.where().endTimestamp().isLowerThan(fromDate); return query; } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/finisheddate/FinishedDateBetweenOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/finisheddate/FinishedDateBetweenOperatorHandler.java index 15bb577ce97..f0dae77c346 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/finisheddate/FinishedDateBetweenOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/finisheddate/FinishedDateBetweenOperatorHandler.java @@ -5,6 +5,7 @@ import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; import com.axonivy.portal.util.PortalDateUtils; +import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivyteam.ivy.workflow.query.CaseQuery; public class FinishedDateBetweenOperatorHandler { @@ -20,8 +21,8 @@ public static FinishedDateBetweenOperatorHandler getInstance() { public CaseQuery buildBetweenQuery(DashboardFilter filter) { - Date from = PortalDateUtils.getStartOfDate(filter.getFromDate()); - Date to = PortalDateUtils.getEndOfDate(filter.getToDate()); + Date from = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); + Date to = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getToDate()) : PortalDateUtils.getEndOfDate(filter.getToDate()); if (from == null && to == null) { return null; @@ -39,8 +40,8 @@ public CaseQuery buildBetweenQuery(DashboardFilter filter) { } public CaseQuery buildNotBetweenQuery(DashboardFilter filter) { - Date from = PortalDateUtils.getStartOfDate(filter.getFromDate()); - Date to = PortalDateUtils.getEndOfDate(filter.getToDate()); + Date from = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); + Date to = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getToDate()) : PortalDateUtils.getEndOfDate(filter.getToDate()); CaseQuery subQuery = CaseQuery.create(); if (from != null && to != null) { diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/finisheddate/FinishedDateIsOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/finisheddate/FinishedDateIsOperatorHandler.java index 0133d9663e3..d2785394a5b 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/finisheddate/FinishedDateIsOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/finisheddate/FinishedDateIsOperatorHandler.java @@ -1,8 +1,11 @@ package com.axonivy.portal.util.filter.operator.caze.finisheddate; +import java.util.Date; + import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; import com.axonivy.portal.util.PortalDateUtils; +import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivyteam.ivy.workflow.query.CaseQuery; public class FinishedDateIsOperatorHandler { @@ -20,8 +23,11 @@ public CaseQuery buildIsQuery(DashboardFilter filter) { return null; } - return CaseQuery.create().where().endTimestamp().isGreaterOrEqualThan(PortalDateUtils.getStartOfDate(filter.getFromDate())) - .and().endTimestamp().isLowerOrEqualThan(PortalDateUtils.getEndOfDate(filter.getFromDate())); + Date fromDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); + Date endDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getFromDate()) : PortalDateUtils.getEndOfDate(filter.getFromDate()); + + return CaseQuery.create().where().endTimestamp().isGreaterOrEqualThan(fromDate) + .and().endTimestamp().isLowerOrEqualThan(endDate); } public CaseQuery buildIsNotQuery(DashboardFilter filter) { @@ -29,7 +35,10 @@ public CaseQuery buildIsNotQuery(DashboardFilter filter) { return null; } - return CaseQuery.create().where().endTimestamp().isGreaterThan(PortalDateUtils.getEndOfDate(filter.getFromDate())) - .or().endTimestamp().isLowerThan(PortalDateUtils.getStartOfDate(filter.getFromDate())); + Date fromDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); + Date endDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getFromDate()) : PortalDateUtils.getEndOfDate(filter.getFromDate()); + + return CaseQuery.create().where().endTimestamp().isGreaterThan(endDate) + .or().endTimestamp().isLowerThan(fromDate); } } \ No newline at end of file diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/name/NameIsEmptyOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/name/NameIsEmptyOperatorHandler.java index 42ab72ffafb..cc193cc9d1a 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/name/NameIsEmptyOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/caze/name/NameIsEmptyOperatorHandler.java @@ -15,13 +15,13 @@ public static NameIsEmptyOperatorHandler getInstance() { return instance; } - public CaseQuery buildIsEmptyQuery(DashboardFilter filter) { + public CaseQuery buildIsEmptyQuery(@SuppressWarnings("unused") DashboardFilter filter) { CaseQuery subQuery = CaseQuery.create(); subQuery.where().name().isNull().or().name().isLike(""); return subQuery; } - public CaseQuery buildNotEmptyQuery(DashboardFilter filter) { + public CaseQuery buildNotEmptyQuery(@SuppressWarnings("unused") DashboardFilter filter) { CaseQuery subQuery = CaseQuery.create(); subQuery.where().name().isNotNull().and().name().isNotLike(""); return subQuery; diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/createddate/CreatedDateAfterOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/createddate/CreatedDateAfterOperatorHandler.java index 8d70ea9e7bc..1e14d90e718 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/createddate/CreatedDateAfterOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/createddate/CreatedDateAfterOperatorHandler.java @@ -1,8 +1,11 @@ package com.axonivy.portal.util.filter.operator.task.createddate; +import java.util.Date; + import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; import com.axonivy.portal.util.PortalDateUtils; +import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivyteam.ivy.workflow.query.TaskQuery; public class CreatedDateAfterOperatorHandler { @@ -21,7 +24,8 @@ public TaskQuery buildQuery(DashboardFilter filter) { } TaskQuery query = TaskQuery.create(); - query.where().startTimestamp().isGreaterThan(PortalDateUtils.getEndOfDate(filter.getToDate())); + Date endDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getToDate()) : PortalDateUtils.getEndOfDate(filter.getToDate()); + query.where().startTimestamp().isGreaterThan(endDate); return query; } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/createddate/CreatedDateBeforeOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/createddate/CreatedDateBeforeOperatorHandler.java index ada43abcd3c..c073e452129 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/createddate/CreatedDateBeforeOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/createddate/CreatedDateBeforeOperatorHandler.java @@ -1,8 +1,11 @@ package com.axonivy.portal.util.filter.operator.task.createddate; +import java.util.Date; + import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; import com.axonivy.portal.util.PortalDateUtils; +import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivyteam.ivy.workflow.query.TaskQuery; public class CreatedDateBeforeOperatorHandler { @@ -22,7 +25,8 @@ public TaskQuery buildQuery(DashboardFilter filter) { } TaskQuery query = TaskQuery.create(); - query.where().startTimestamp().isLowerThan(PortalDateUtils.getStartOfDate(filter.getFromDate())); + Date fromDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); + query.where().startTimestamp().isLowerThan(fromDate); return query; } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/createddate/CreatedDateBetweenOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/createddate/CreatedDateBetweenOperatorHandler.java index aa4fb28b301..31f4890f882 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/createddate/CreatedDateBetweenOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/createddate/CreatedDateBetweenOperatorHandler.java @@ -5,6 +5,7 @@ import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; import com.axonivy.portal.util.PortalDateUtils; +import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivyteam.ivy.workflow.query.TaskQuery; public class CreatedDateBetweenOperatorHandler { @@ -19,8 +20,8 @@ public static CreatedDateBetweenOperatorHandler getInstance() { } public TaskQuery buildBetweenQuery(DashboardFilter filter) { - Date from = PortalDateUtils.getStartOfDate(filter.getFromDate()); - Date to = PortalDateUtils.getEndOfDate(filter.getToDate()); + Date from = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); + Date to = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getToDate()) : PortalDateUtils.getEndOfDate(filter.getToDate()); if (from == null && to == null) { return null; @@ -38,8 +39,8 @@ public TaskQuery buildBetweenQuery(DashboardFilter filter) { } public TaskQuery buildNotBetweenQuery(DashboardFilter filter) { - Date from = PortalDateUtils.getStartOfDate(filter.getFromDate()); - Date to = PortalDateUtils.getEndOfDate(filter.getToDate()); + Date from = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); + Date to = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getToDate()) : PortalDateUtils.getEndOfDate(filter.getToDate()); TaskQuery subQuery = TaskQuery.create(); if (from != null && to != null) { diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/createddate/CreatedDateIsOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/createddate/CreatedDateIsOperatorHandler.java index ca7bc2a5606..47d1468062d 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/createddate/CreatedDateIsOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/createddate/CreatedDateIsOperatorHandler.java @@ -1,8 +1,11 @@ package com.axonivy.portal.util.filter.operator.task.createddate; +import java.util.Date; + import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; import com.axonivy.portal.util.PortalDateUtils; +import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivyteam.ivy.workflow.query.TaskQuery; public class CreatedDateIsOperatorHandler { @@ -20,9 +23,12 @@ public TaskQuery buildIsQuery(DashboardFilter filter) { return null; } + Date fromDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); + Date endDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getFromDate()) : PortalDateUtils.getEndOfDate(filter.getFromDate()); + return TaskQuery.create().where().startTimestamp() - .isGreaterOrEqualThan(PortalDateUtils.getStartOfDate(filter.getFromDate())).and().startTimestamp() - .isLowerOrEqualThan(PortalDateUtils.getEndOfDate(filter.getFromDate())); + .isGreaterOrEqualThan(fromDate).and().startTimestamp() + .isLowerOrEqualThan(endDate); } public TaskQuery buildIsNotQuery(DashboardFilter filter) { @@ -30,7 +36,10 @@ public TaskQuery buildIsNotQuery(DashboardFilter filter) { return null; } - return TaskQuery.create().where().startTimestamp().isGreaterThan(PortalDateUtils.getEndOfDate(filter.getFromDate())) - .or().startTimestamp().isLowerThan(PortalDateUtils.getStartOfDate(filter.getFromDate())); + Date fromDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); + Date endDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getFromDate()) : PortalDateUtils.getEndOfDate(filter.getFromDate()); + + return TaskQuery.create().where().startTimestamp().isGreaterThan(endDate) + .or().startTimestamp().isLowerThan(fromDate); } } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/customfield/CustomTimestampAfterOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/customfield/CustomTimestampAfterOperatorHandler.java index 6014bd264b9..3d8c5b61f7b 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/customfield/CustomTimestampAfterOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/customfield/CustomTimestampAfterOperatorHandler.java @@ -1,10 +1,12 @@ package com.axonivy.portal.util.filter.operator.task.customfield; +import java.util.Date; + import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; import com.axonivy.portal.util.PortalDateUtils; +import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivyteam.ivy.workflow.query.CaseQuery; - import ch.ivyteam.ivy.workflow.query.TaskQuery; public class CustomTimestampAfterOperatorHandler { @@ -23,8 +25,9 @@ public TaskQuery buildQuery(DashboardFilter filter) { } TaskQuery query = TaskQuery.create(); + Date endDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getToDate()) : PortalDateUtils.getEndOfDate(filter.getToDate()); query.where().customField().timestampField(filter.getField()) - .isGreaterThan(PortalDateUtils.getEndOfDate(filter.getToDate())); + .isGreaterThan(endDate); return query; } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/customfield/CustomTimestampBeforeOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/customfield/CustomTimestampBeforeOperatorHandler.java index 3126f9fd96c..2b61db3915c 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/customfield/CustomTimestampBeforeOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/customfield/CustomTimestampBeforeOperatorHandler.java @@ -1,10 +1,12 @@ package com.axonivy.portal.util.filter.operator.task.customfield; +import java.util.Date; + import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; import com.axonivy.portal.util.PortalDateUtils; +import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivyteam.ivy.workflow.query.CaseQuery; - import ch.ivyteam.ivy.workflow.query.TaskQuery; public class CustomTimestampBeforeOperatorHandler { @@ -24,8 +26,9 @@ public TaskQuery buildQuery(DashboardFilter filter) { } TaskQuery query = TaskQuery.create(); + Date fromDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); query.where().customField().timestampField(filter.getField()) - .isLowerThan(PortalDateUtils.getStartOfDate(filter.getFromDate())); + .isLowerThan(fromDate); return query; } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/customfield/CustomTimestampBetweenOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/customfield/CustomTimestampBetweenOperatorHandler.java index 781e71be846..c94003c504a 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/customfield/CustomTimestampBetweenOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/customfield/CustomTimestampBetweenOperatorHandler.java @@ -5,8 +5,8 @@ import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; import com.axonivy.portal.util.PortalDateUtils; +import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivyteam.ivy.workflow.query.CaseQuery; - import ch.ivyteam.ivy.workflow.query.TaskQuery; public class CustomTimestampBetweenOperatorHandler { @@ -22,8 +22,8 @@ public static CustomTimestampBetweenOperatorHandler getInstance() { public TaskQuery buildBetweenQuery(DashboardFilter filter) { - Date from = PortalDateUtils.getStartOfDate(filter.getFromDate()); - Date to = PortalDateUtils.getEndOfDate(filter.getToDate()); + Date from = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); + Date to = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getToDate()) : PortalDateUtils.getEndOfDate(filter.getToDate()); if (from == null && to == null) { return null; @@ -41,8 +41,8 @@ public TaskQuery buildBetweenQuery(DashboardFilter filter) { } public TaskQuery buildNotBetweenQuery(DashboardFilter filter) { - Date from = PortalDateUtils.getStartOfDate(filter.getFromDate()); - Date to = PortalDateUtils.getEndOfDate(filter.getToDate()); + Date from = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) :PortalDateUtils.getStartOfDate(filter.getFromDate()); + Date to = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getToDate()) : PortalDateUtils.getEndOfDate(filter.getToDate()); TaskQuery subQuery = TaskQuery.create(); if (from != null && to != null) { diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/customfield/CustomTimestampIsOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/customfield/CustomTimestampIsOperatorHandler.java index 5c8ab5570e6..9515a838a86 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/customfield/CustomTimestampIsOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/customfield/CustomTimestampIsOperatorHandler.java @@ -1,7 +1,11 @@ package com.axonivy.portal.util.filter.operator.task.customfield; +import java.util.Date; + import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; import com.axonivy.portal.util.PortalDateUtils; + +import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivyteam.ivy.workflow.query.CaseQuery; import ch.ivyteam.ivy.workflow.query.TaskQuery; @@ -19,20 +23,24 @@ public TaskQuery buildIsQuery(DashboardFilter filter) { if (filter.getFromDate() == null) { return null; } + Date fromDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); + Date endDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getFromDate()) : PortalDateUtils.getEndOfDate(filter.getFromDate()); return TaskQuery.create().where().customField().timestampField(filter.getField()) - .isGreaterOrEqualThan(PortalDateUtils.getStartOfDate(filter.getFromDate())) - .and().customField().timestampField(filter.getField()).isLowerOrEqualThan(PortalDateUtils.getEndOfDate(filter.getFromDate())); + .isGreaterOrEqualThan(fromDate) + .and().customField().timestampField(filter.getField()).isLowerOrEqualThan(endDate); } public TaskQuery buildIsNotQuery(DashboardFilter filter) { if (filter.getFromDate() == null) { return null; } + Date fromDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); + Date endDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getFromDate()) : PortalDateUtils.getEndOfDate(filter.getFromDate()); return TaskQuery.create().where().customField().timestampField(filter.getField()) - .isGreaterThan(PortalDateUtils.getEndOfDate(filter.getFromDate())) - .or().customField().timestampField(filter.getField()).isLowerThan(PortalDateUtils.getStartOfDate(filter.getFromDate())); + .isGreaterThan(endDate) + .or().customField().timestampField(filter.getField()).isLowerThan(fromDate); } public TaskQuery buildIsQueryByCase(DashboardFilter filter) { diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/description/DescriptionIsEmptyOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/description/DescriptionIsEmptyOperatorHandler.java index dd4803cffa2..b72e5832ea3 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/description/DescriptionIsEmptyOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/description/DescriptionIsEmptyOperatorHandler.java @@ -15,13 +15,13 @@ public static DescriptionIsEmptyOperatorHandler getInstance() { return instance; } - public TaskQuery buildIsEmptyQuery(DashboardFilter filter) { + public TaskQuery buildIsEmptyQuery(@SuppressWarnings("unused") DashboardFilter filter) { TaskQuery subQuery = TaskQuery.create(); subQuery.where().description().isNull().or().description().isLike(""); return subQuery; } - public TaskQuery buildNotEmptyQuery(DashboardFilter filter) { + public TaskQuery buildNotEmptyQuery(@SuppressWarnings("unused") DashboardFilter filter) { TaskQuery subQuery = TaskQuery.create(); subQuery.where().description().isNotNull().and().description().isNotLike(""); return subQuery; diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/expirydate/ExpiryDateAfterOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/expirydate/ExpiryDateAfterOperatorHandler.java index b3cb5eb84ba..f4d85daf22b 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/expirydate/ExpiryDateAfterOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/expirydate/ExpiryDateAfterOperatorHandler.java @@ -1,8 +1,11 @@ package com.axonivy.portal.util.filter.operator.task.expirydate; +import java.util.Date; + import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; import com.axonivy.portal.util.PortalDateUtils; +import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivyteam.ivy.workflow.query.TaskQuery; public class ExpiryDateAfterOperatorHandler { @@ -21,7 +24,8 @@ public TaskQuery buildQuery(DashboardFilter filter) { } TaskQuery query = TaskQuery.create(); - query.where().expiryTimestamp().isGreaterThan(PortalDateUtils.getEndOfDate(filter.getToDate())); + Date endDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getToDate()) : PortalDateUtils.getEndOfDate(filter.getToDate()); + query.where().expiryTimestamp().isGreaterThan(endDate); return query; } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/expirydate/ExpiryDateBeforeOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/expirydate/ExpiryDateBeforeOperatorHandler.java index 07261a13593..713dadfa449 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/expirydate/ExpiryDateBeforeOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/expirydate/ExpiryDateBeforeOperatorHandler.java @@ -1,8 +1,11 @@ package com.axonivy.portal.util.filter.operator.task.expirydate; +import java.util.Date; + import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; import com.axonivy.portal.util.PortalDateUtils; +import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivyteam.ivy.workflow.query.TaskQuery; public class ExpiryDateBeforeOperatorHandler { @@ -22,7 +25,8 @@ public TaskQuery buildQuery(DashboardFilter filter) { } TaskQuery query = TaskQuery.create(); - query.where().expiryTimestamp().isLowerThan(PortalDateUtils.getStartOfDate(filter.getFromDate())); + Date fromDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); + query.where().expiryTimestamp().isLowerThan(fromDate); return query; } diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/expirydate/ExpiryDateBetweenOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/expirydate/ExpiryDateBetweenOperatorHandler.java index bea6e3ea122..f385f4e8100 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/expirydate/ExpiryDateBetweenOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/expirydate/ExpiryDateBetweenOperatorHandler.java @@ -5,6 +5,7 @@ import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; import com.axonivy.portal.util.PortalDateUtils; +import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivyteam.ivy.workflow.query.TaskQuery; public class ExpiryDateBetweenOperatorHandler { @@ -20,8 +21,8 @@ public static ExpiryDateBetweenOperatorHandler getInstance() { public TaskQuery buildBetweenQuery(DashboardFilter filter) { - Date from = PortalDateUtils.getStartOfDate(filter.getFromDate()); - Date to = PortalDateUtils.getEndOfDate(filter.getToDate()); + Date from = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); + Date to = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getToDate()) : PortalDateUtils.getEndOfDate(filter.getToDate()); if (from == null && to == null) { return null; @@ -39,8 +40,8 @@ public TaskQuery buildBetweenQuery(DashboardFilter filter) { } public TaskQuery buildNotBetweenQuery(DashboardFilter filter) { - Date from = PortalDateUtils.getStartOfDate(filter.getFromDate()); - Date to = PortalDateUtils.getEndOfDate(filter.getToDate()); + Date from = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) :PortalDateUtils.getStartOfDate(filter.getFromDate()); + Date to = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getToDate()) : PortalDateUtils.getEndOfDate(filter.getToDate()); TaskQuery subQuery = TaskQuery.create(); if (from != null && to != null) { diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/expirydate/ExpiryDateIsOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/expirydate/ExpiryDateIsOperatorHandler.java index 3471e861595..807cef13d00 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/expirydate/ExpiryDateIsOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/expirydate/ExpiryDateIsOperatorHandler.java @@ -1,8 +1,11 @@ package com.axonivy.portal.util.filter.operator.task.expirydate; +import java.util.Date; + import com.axonivy.portal.dto.dashboard.filter.DashboardFilter; import com.axonivy.portal.util.PortalDateUtils; +import ch.ivy.addon.portalkit.service.DateTimeGlobalSettingService; import ch.ivyteam.ivy.workflow.query.TaskQuery; public class ExpiryDateIsOperatorHandler { @@ -16,20 +19,27 @@ public static ExpiryDateIsOperatorHandler getInstance() { } public TaskQuery buildIsQuery(DashboardFilter filter) { + if (filter.getFromDate() == null) { return null; } - return TaskQuery.create().where().expiryTimestamp().isGreaterOrEqualThan(PortalDateUtils.getStartOfDate(filter.getFromDate())) - .and().expiryTimestamp().isLowerOrEqualThan(PortalDateUtils.getEndOfDate(filter.getFromDate())); + Date fromDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); + Date endDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getFromDate()) : PortalDateUtils.getEndOfDate(filter.getFromDate()); + + return TaskQuery.create().where().expiryTimestamp().isGreaterOrEqualThan(fromDate) + .and().expiryTimestamp().isLowerOrEqualThan(endDate); } public TaskQuery buildIsNotQuery(DashboardFilter filter) { if (filter.getFromDate() == null) { return null; } + + Date fromDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getStartOfMinute(filter.getFromDate()) : PortalDateUtils.getStartOfDate(filter.getFromDate()); + Date endDate = DateTimeGlobalSettingService.getInstance().isDateFilterWithTime() ? PortalDateUtils.getEndOfMinute(filter.getFromDate()) : PortalDateUtils.getEndOfDate(filter.getFromDate()); - return TaskQuery.create().where().expiryTimestamp().isGreaterThan(PortalDateUtils.getEndOfDate(filter.getFromDate())) - .or().expiryTimestamp().isLowerThan(PortalDateUtils.getStartOfDate(filter.getFromDate())); + return TaskQuery.create().where().expiryTimestamp().isGreaterThan(endDate) + .or().expiryTimestamp().isLowerThan(fromDate); } } \ No newline at end of file diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/name/NameIsEmptyOperatorHandler.java b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/name/NameIsEmptyOperatorHandler.java index 1bb743679a9..1393de58a81 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/name/NameIsEmptyOperatorHandler.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/util/filter/operator/task/name/NameIsEmptyOperatorHandler.java @@ -15,13 +15,13 @@ public static NameIsEmptyOperatorHandler getInstance() { return instance; } - public TaskQuery buildIsEmptyQuery(DashboardFilter filter) { + public TaskQuery buildIsEmptyQuery(@SuppressWarnings("unused") DashboardFilter filter) { TaskQuery subQuery = TaskQuery.create(); subQuery.where().name().isNull().or().name().isLike(""); return subQuery; } - public TaskQuery buildNotEmptyQuery(DashboardFilter filter) { + public TaskQuery buildNotEmptyQuery(@SuppressWarnings("unused") DashboardFilter filter) { TaskQuery subQuery = TaskQuery.create(); subQuery.where().name().isNotNull().and().name().isNotLike(""); return subQuery; diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/validator/filter/DashboardDateFilterValidator.java b/AxonIvyPortal/portal/src/com/axonivy/portal/validator/filter/DashboardDateFilterValidator.java index 15cec060f24..c4931638111 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/validator/filter/DashboardDateFilterValidator.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/validator/filter/DashboardDateFilterValidator.java @@ -23,6 +23,7 @@ public class DashboardDateFilterValidator implements Validator { private static final String MESSAGE_PREFIX_PATTERN = "%s(%d)"; private static final String EXPIRY_TIMESTAMP = "expiryTimestamp"; + @Override public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { DashboardFilter filter = (DashboardFilter) component.getAttributes().get("filter"); @@ -33,7 +34,7 @@ public void validate(FacesContext context, UIComponent component, Object value) case BETWEEN -> validateBetweenOperator((Date)value, filter, filterIndex, component, messageComponentId); case NOT_BETWEEN -> validateBetweenOperator((Date)value, filter, filterIndex, component, messageComponentId); default -> validateDefaultOperator((Date)value, filter, filterIndex, component, messageComponentId); - }; + } } private void validateBetweenOperator(Date value, DashboardFilter filter, int filterIndex, UIComponent component, String messageComponentId) { diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/validator/filter/DashboardDefaultListFilterValidator.java b/AxonIvyPortal/portal/src/com/axonivy/portal/validator/filter/DashboardDefaultListFilterValidator.java index 9e47d207c4b..8d9909723cb 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/validator/filter/DashboardDefaultListFilterValidator.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/validator/filter/DashboardDefaultListFilterValidator.java @@ -24,6 +24,7 @@ public class DashboardDefaultListFilterValidator implements Validator { private static final String MESSAGE_PREFIX_PATTERN = "%s(%d)"; + @Override @SuppressWarnings("unchecked") public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/validator/filter/DashboardNumberFilterValidator.java b/AxonIvyPortal/portal/src/com/axonivy/portal/validator/filter/DashboardNumberFilterValidator.java index ad296ba790a..26d4adc8cc4 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/validator/filter/DashboardNumberFilterValidator.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/validator/filter/DashboardNumberFilterValidator.java @@ -42,13 +42,13 @@ public void validate(FacesContext context, UIComponent component, Object value) default -> { } } - ; + } private void validateBetweenOperator(BigDecimal value, DashboardFilter filter, int filterIndex, UIComponent component, String messageComponentId) { if (component.getId().contentEquals("to-number")) { - BigDecimal fromNumber = BigDecimal.valueOf(NumberUtils.toDouble((String) filter.getFrom())); + BigDecimal fromNumber = BigDecimal.valueOf(NumberUtils.toDouble(filter.getFrom())); FacesMessage error = validateFromToValues(fromNumber, value, filter.getField(), filterIndex); if (error != null) { FacesContext.getCurrentInstance().addMessage(messageComponentId, error); diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/validator/filter/DashboardSelectableListFilterValidator.java b/AxonIvyPortal/portal/src/com/axonivy/portal/validator/filter/DashboardSelectableListFilterValidator.java index 6e4e370873e..be27eff381f 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/validator/filter/DashboardSelectableListFilterValidator.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/validator/filter/DashboardSelectableListFilterValidator.java @@ -24,6 +24,7 @@ public class DashboardSelectableListFilterValidator implements Validator { private static final String MESSAGE_PREFIX_PATTERN = "%s(%d)"; private static final String PRIORITY = "priority"; + @Override public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { DashboardFilter filter = (DashboardFilter) component.getAttributes().get("filter"); Integer filterIndex = Optional.ofNullable((Integer)component.getAttributes().get("filterIndex")).orElse(0); diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/validator/filter/DashboardTextFilterValidator.java b/AxonIvyPortal/portal/src/com/axonivy/portal/validator/filter/DashboardTextFilterValidator.java index 09997946055..adf64a8b9c4 100644 --- a/AxonIvyPortal/portal/src/com/axonivy/portal/validator/filter/DashboardTextFilterValidator.java +++ b/AxonIvyPortal/portal/src/com/axonivy/portal/validator/filter/DashboardTextFilterValidator.java @@ -22,6 +22,7 @@ public class DashboardTextFilterValidator implements Validator { private static final String MESSAGE_PREFIX_PATTERN = "%s(%d)"; + @Override public void validate(FacesContext context, UIComponent component, Object value) throws ValidatorException { DashboardFilter filter = (DashboardFilter) component.getAttributes().get("filter"); Integer filterIndex = Optional.ofNullable((Integer)component.getAttributes().get("filterIndex")).orElse(0); diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/CaseInformation/CaseInformationData.d.json b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/CaseInformation/CaseInformationData.d.json index bdccb5a0eef..1a55f95bdb6 100644 --- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/CaseInformation/CaseInformationData.d.json +++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/CaseInformation/CaseInformationData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "CaseInformationData", "namespace" : "ch.ivy.addon.portal.component.CaseInformation", "isBusinessCaseData" : false diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/CaseInformation/CaseInformationProcess.p.json b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/CaseInformation/CaseInformationProcess.p.json index 702715d43a4..82cb106572b 100644 --- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/CaseInformation/CaseInformationProcess.p.json +++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/CaseInformation/CaseInformationProcess.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "174A0E62AF58D689", "kind" : "HTML_DIALOG", "config" : { diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/ProcessInformation/ProcessInformationData.d.json b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/ProcessInformation/ProcessInformationData.d.json index 9ff1ae74fb6..f7e2daf5b89 100644 --- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/ProcessInformation/ProcessInformationData.d.json +++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/ProcessInformation/ProcessInformationData.d.json @@ -1,24 +1,21 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "ProcessInformationData", "namespace" : "ch.ivy.addon.portal.component.ProcessInformation", "isBusinessCaseData" : false, "fields" : [ { "name" : "processSteps", - "type" : "java.util.List", - "modifiers" : [ "PERSISTENT" ] + "type" : "java.util.List" }, { "name" : "processId", "type" : "String", "modifiers" : [ "PERSISTENT" ] }, { "name" : "userProcesses", - "type" : "java.util.List", - "modifiers" : [ "PERSISTENT" ] + "type" : "java.util.List" }, { "name" : "selectedProcess", - "type" : "ch.ivy.addon.portalkit.configuration.UserProcess", - "modifiers" : [ "PERSISTENT" ] + "type" : "ch.ivy.addon.portalkit.configuration.UserProcess" }, { "name" : "portalProcessInformation", "type" : "String", diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/ProcessInformation/ProcessInformationProcess.p.json b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/ProcessInformation/ProcessInformationProcess.p.json index 50ae282442b..3f0d8707df3 100644 --- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/ProcessInformation/ProcessInformationProcess.p.json +++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/ProcessInformation/ProcessInformationProcess.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "17982F86EF698C57", "kind" : "HTML_DIALOG", "config" : { diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/CaseInformationInIFrame/CaseInformationInIFrameData.d.json b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/CaseInformationInIFrame/CaseInformationInIFrameData.d.json index 4137ddb4d37..ec57d1a3df6 100644 --- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/CaseInformationInIFrame/CaseInformationInIFrameData.d.json +++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/CaseInformationInIFrame/CaseInformationInIFrameData.d.json @@ -1,12 +1,11 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "CaseInformationInIFrameData", "namespace" : "ch.ivy.addon.portal.component.iframe.CaseInformationInIFrame", "isBusinessCaseData" : false, "fields" : [ { "name" : "currentCase", - "type" : "ch.ivyteam.ivy.workflow.ICase", - "modifiers" : [ "PERSISTENT" ] + "type" : "ch.ivyteam.ivy.workflow.ICase" }, { "name" : "showBackButton", "type" : "Boolean", diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/CaseInformationInIFrame/CaseInformationInIFrameProcess.p.json b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/CaseInformationInIFrame/CaseInformationInIFrameProcess.p.json index 5ef8097d350..666e4d0db33 100644 --- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/CaseInformationInIFrame/CaseInformationInIFrameProcess.p.json +++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/CaseInformationInIFrame/CaseInformationInIFrameProcess.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "1754AA136C748BA5", "kind" : "HTML_DIALOG", "config" : { diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/PortalCaseListInFrame/PortalCaseListInFrameData.d.json b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/PortalCaseListInFrame/PortalCaseListInFrameData.d.json index 2a4690b08ef..8a7d4cb03d5 100644 --- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/PortalCaseListInFrame/PortalCaseListInFrameData.d.json +++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/PortalCaseListInFrame/PortalCaseListInFrameData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "PortalCaseListInFrameData", "namespace" : "ch.ivy.addon.portal.component.iframe.PortalCaseListInFrame", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/PortalCaseListInFrame/PortalCaseListInFrameProcess.p.json b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/PortalCaseListInFrame/PortalCaseListInFrameProcess.p.json index 057d5d21d84..65273d1ca04 100644 --- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/PortalCaseListInFrame/PortalCaseListInFrameProcess.p.json +++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/PortalCaseListInFrame/PortalCaseListInFrameProcess.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "175547CA9E6BDFA4", "kind" : "HTML_DIALOG", "config" : { diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/PortalTaskItemDetailsInIFrame/PortalTaskItemDetailsInIFrameData.d.json b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/PortalTaskItemDetailsInIFrame/PortalTaskItemDetailsInIFrameData.d.json index a35c84f0a15..1f5224c4cf7 100644 --- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/PortalTaskItemDetailsInIFrame/PortalTaskItemDetailsInIFrameData.d.json +++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/PortalTaskItemDetailsInIFrame/PortalTaskItemDetailsInIFrameData.d.json @@ -1,24 +1,21 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "PortalTaskItemDetailsInIFrameData", "namespace" : "ch.ivy.addon.portal.component.iframe.PortalTaskItemDetailsInIFrame", "isBusinessCaseData" : false, "fields" : [ { "name" : "dataModel", - "type" : "ch.ivy.addon.portalkit.datamodel.TaskLazyDataModel", - "modifiers" : [ "PERSISTENT" ] + "type" : "ch.ivy.addon.portalkit.datamodel.TaskLazyDataModel" }, { "name" : "isFromTaskList", "type" : "Boolean", "modifiers" : [ "PERSISTENT" ] }, { "name" : "portalPage", - "type" : "ch.ivy.addon.portalkit.enums.PortalPage", - "modifiers" : [ "PERSISTENT" ] + "type" : "ch.ivy.addon.portalkit.enums.PortalPage" }, { "name" : "task", - "type" : "ch.ivyteam.ivy.workflow.ITask", - "modifiers" : [ "PERSISTENT" ] + "type" : "ch.ivyteam.ivy.workflow.ITask" }, { "name" : "isTaskStartedInDetails", "type" : "Boolean", diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/PortalTaskItemDetailsInIFrame/PortalTaskItemDetailsInIFrameProcess.p.json b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/PortalTaskItemDetailsInIFrame/PortalTaskItemDetailsInIFrameProcess.p.json index 8ce3cd1ba0f..5bd1d914e9a 100644 --- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/PortalTaskItemDetailsInIFrame/PortalTaskItemDetailsInIFrameProcess.p.json +++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/PortalTaskItemDetailsInIFrame/PortalTaskItemDetailsInIFrameProcess.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "1754F760476EA790", "kind" : "HTML_DIALOG", "config" : { diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/PortalTaskListInFrame/PortalTaskListInFrameData.d.json b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/PortalTaskListInFrame/PortalTaskListInFrameData.d.json index c4a2eb06a8a..cd9e2308901 100644 --- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/PortalTaskListInFrame/PortalTaskListInFrameData.d.json +++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/PortalTaskListInFrame/PortalTaskListInFrameData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "PortalTaskListInFrameData", "namespace" : "ch.ivy.addon.portal.component.iframe.PortalTaskListInFrame", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/PortalTaskListInFrame/PortalTaskListInFrameProcess.p.json b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/PortalTaskListInFrame/PortalTaskListInFrameProcess.p.json index 7e628c562a6..c8372ec8fd8 100644 --- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/PortalTaskListInFrame/PortalTaskListInFrameProcess.p.json +++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/component/iframe/PortalTaskListInFrame/PortalTaskListInFrameProcess.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "1754E87196DBC6F3", "kind" : "HTML_DIALOG", "config" : { diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/error/ErrorPage/ErrorPageData.d.json b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/error/ErrorPage/ErrorPageData.d.json index 847f66a70c2..4b63a194eb2 100644 --- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/error/ErrorPage/ErrorPageData.d.json +++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/error/ErrorPage/ErrorPageData.d.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "ErrorPageData", "namespace" : "ch.ivy.addon.portal.error.ErrorPage", "isBusinessCaseData" : false, diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/error/ErrorPage/ErrorPageProcess.p.json b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/error/ErrorPage/ErrorPageProcess.p.json index 0da011fdc26..f77714de0cf 100644 --- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/error/ErrorPage/ErrorPageProcess.p.json +++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/error/ErrorPage/ErrorPageProcess.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "15268544244B73B8", "kind" : "HTML_DIALOG", "config" : { diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/AdditionalCaseDetails/AdditionalCaseDetailsData.d.json b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/AdditionalCaseDetails/AdditionalCaseDetailsData.d.json index 9a60f9cb4b1..0fa38c8a127 100644 --- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/AdditionalCaseDetails/AdditionalCaseDetailsData.d.json +++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/AdditionalCaseDetails/AdditionalCaseDetailsData.d.json @@ -1,11 +1,10 @@ { - "$schema" : "https://json-schema.axonivy.com/data-class/11.4.0/data-class.json", + "$schema" : "https://json-schema.axonivy.com/data-class/12.0.0/data-class.json", "simpleName" : "AdditionalCaseDetailsData", "namespace" : "ch.ivy.addon.portal.generic.AdditionalCaseDetails", "isBusinessCaseData" : false, "fields" : [ { "name" : "selectedCase", - "type" : "ch.ivyteam.ivy.workflow.ICase", - "modifiers" : [ "PERSISTENT" ] + "type" : "ch.ivyteam.ivy.workflow.ICase" } ] } \ No newline at end of file diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/AdditionalCaseDetails/AdditionalCaseDetailsProcess.p.json b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/AdditionalCaseDetails/AdditionalCaseDetailsProcess.p.json index 6cf6b10c9a4..e44984c5d22 100644 --- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/AdditionalCaseDetails/AdditionalCaseDetailsProcess.p.json +++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/AdditionalCaseDetails/AdditionalCaseDetailsProcess.p.json @@ -1,5 +1,5 @@ { - "$schema" : "https://json-schema.axonivy.com/process/11.3.0/process.json", + "$schema" : "https://json-schema.axonivy.com/process/12.0.0/process.json", "id" : "160FD493AA8D5416", "kind" : "HTML_DIALOG", "config" : { diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/ApplicationSelectionMenu/ApplicationSelectionMenu.xhtml b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/ApplicationSelectionMenu/ApplicationSelectionMenu.xhtml index c66ffa8e8dc..d8624f50328 100644 --- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/ApplicationSelectionMenu/ApplicationSelectionMenu.xhtml +++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/ApplicationSelectionMenu/ApplicationSelectionMenu.xhtml @@ -36,7 +36,7 @@ -