diff --git a/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/DataCreationData.d.json b/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/DataCreationData.d.json
index c4840de0bb5..031f769941c 100644
--- a/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/DataCreationData.d.json
+++ b/AxonIvyPortal/PortalKitTestHelper/dataclasses/portalKit_test/DataCreationData.d.json
@@ -60,5 +60,9 @@
}, {
"name" : "jsonKey",
"type" : "String"
+ }, {
+ "name" : "persistedCounter",
+ "type" : "java.lang.Integer",
+ "modifiers" : [ "PERSISTENT" ]
} ]
}
\ No newline at end of file
diff --git a/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/DataCreation.p.json b/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/DataCreation.p.json
index b948a8a66b2..1d48309753b 100644
--- a/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/DataCreation.p.json
+++ b/AxonIvyPortal/PortalKitTestHelper/processes/Start Processes/DataCreation.p.json
@@ -1004,11 +1004,6 @@
}, {
"id" : "f112",
"type" : "TaskSwitchGateway",
- "config" : {
- "tasks" : [ {
- "id" : "TaskA"
- } ]
- },
"visual" : {
"at" : { "x" : 1472, "y" : 192 }
},
@@ -1282,11 +1277,6 @@
}, {
"id" : "S10-f5",
"type" : "TaskSwitchGateway",
- "config" : {
- "tasks" : [ {
- "id" : "TaskA"
- } ]
- },
"visual" : {
"at" : { "x" : 640, "y" : 256 }
},
@@ -1914,5 +1904,309 @@
"connect" : [
{ "id" : "f191", "to" : "f186", "color" : "default" }
]
+ }, {
+ "id" : "f145",
+ "type" : "RequestStart",
+ "name" : "createABusinessCaseHasLotsOfTasksCases",
+ "config" : {
+ "signature" : "createBusinessCaseHasLotsOfTasksCases",
+ "request" : {
+ "name" : "Create a business case has lots of tasks cases"
+ },
+ "task" : {
+ "name" : "First task of the case"
+ },
+ "case" : {
+ "name" : "Business case has lots of tasks cases"
+ }
+ },
+ "visual" : {
+ "at" : { "x" : 64, "y" : 2144 },
+ "labelOffset" : { "x" : 17, "y" : 49 }
+ },
+ "connect" : [
+ { "id" : "f147", "to" : "f146" }
+ ]
+ }, {
+ "id" : "f146",
+ "type" : "Script",
+ "name" : "Init",
+ "config" : {
+ "output" : {
+ "code" : "in.counter = 0;"
+ }
+ },
+ "visual" : {
+ "at" : { "x" : 216, "y" : 2144 }
+ },
+ "connect" : [
+ { "id" : "f216", "to" : "f217" }
+ ]
+ }, {
+ "id" : "f148",
+ "type" : "RequestStart",
+ "name" : "createACaseHasLotsOfTasks",
+ "config" : {
+ "signature" : "createCaseHasLotsOfTasks",
+ "request" : {
+ "isHttpRequestable" : false
+ },
+ "triggerable" : true,
+ "task" : {
+ "name" : "First task of the case",
+ "responsible" : {
+ "activator" : "SYSTEM"
+ }
+ },
+ "case" : {
+ "name" : "Technical case"
+ }
+ },
+ "visual" : {
+ "at" : { "x" : 64, "y" : 2352 }
+ },
+ "connect" : [
+ { "id" : "f192", "to" : "f149" }
+ ]
+ }, {
+ "id" : "f149",
+ "type" : "Script",
+ "name" : "Init",
+ "config" : {
+ "output" : {
+ "code" : "in.persistedCounter = 0;"
+ }
+ },
+ "visual" : {
+ "at" : { "x" : 216, "y" : 2352 }
+ },
+ "connect" : [
+ { "id" : "f194", "to" : "f224" }
+ ]
+ }, {
+ "id" : "f193",
+ "type" : "TaskSwitchGateway",
+ "config" : {
+ "tasks" : [ {
+ "id" : "TaskA",
+ "name" : "<%= \"Task A \" + in1.persistedCounter + \" of case \" + ivy.case.getId() %>"
+ }, {
+ "id" : "TaskB",
+ "name" : "<%= \"Task B \" + in1.persistedCounter + \" of case \" + ivy.case.getId() %>"
+ }, {
+ "id" : "TaskC",
+ "name" : "<%= \"Task C \" + in1.persistedCounter + \" of case \" + ivy.case.getId() %>"
+ }, {
+ "id" : "TaskD",
+ "name" : "<%= \"Task D \" + in1.persistedCounter + \" of case \" + ivy.case.getId() %>"
+ }, {
+ "id" : "TaskE",
+ "name" : "<%= \"Task E \" + in1.persistedCounter + \" of case \" + ivy.case.getId() %>"
+ }, {
+ "id" : "TaskF",
+ "name" : "<%= \"Task F \" + in1.persistedCounter + \" of case \" + ivy.case.getId() %>"
+ }, {
+ "id" : "TaskG",
+ "name" : "<%= \"Task G \" + in1.persistedCounter + \" of case \" + ivy.case.getId() %>"
+ }, {
+ "id" : "TaskH",
+ "name" : "<%= \"Task H \" + in1.persistedCounter + \" of case \" + ivy.case.getId() %>"
+ }, {
+ "id" : "TaskI",
+ "name" : "<%= \"Task I \" + in1.persistedCounter + \" of case \" + ivy.case.getId() %>"
+ }, {
+ "id" : "TaskJ",
+ "name" : "<%= \"Task J \" + in1.persistedCounter + \" of case \" + ivy.case.getId() %>",
+ "responsible" : {
+ "activator" : "SYSTEM"
+ }
+ } ]
+ },
+ "visual" : {
+ "at" : { "x" : 480, "y" : 2352 },
+ "labelOffset" : { "x" : 14, "y" : 34 }
+ },
+ "connect" : [
+ { "id" : "f196", "to" : "f195", "condition" : "ivp==\"TaskA.ivp\"" },
+ { "id" : "f198", "to" : "f197", "condition" : "ivp==\"TaskB.ivp\"" },
+ { "id" : "f207", "to" : "f199", "condition" : "ivp==\"TaskC.ivp\"" },
+ { "id" : "f208", "to" : "f200", "condition" : "ivp==\"TaskD.ivp\"" },
+ { "id" : "f209", "to" : "f205", "condition" : "ivp==\"TaskE.ivp\"" },
+ { "id" : "f210", "to" : "f206", "condition" : "ivp==\"TaskF.ivp\"" },
+ { "id" : "f211", "to" : "f201", "condition" : "ivp==\"TaskG.ivp\"" },
+ { "id" : "f212", "to" : "f202", "condition" : "ivp==\"TaskH.ivp\"" },
+ { "id" : "f213", "to" : "f227", "condition" : "ivp==\"TaskI.ivp\"" },
+ { "id" : "f228", "to" : "f204", "via" : [ { "x" : 480, "y" : 2272 } ], "condition" : "ivp==\"TaskJ.ivp\"" }
+ ]
+ }, {
+ "id" : "f195",
+ "type" : "TaskEnd",
+ "visual" : {
+ "at" : { "x" : 608, "y" : 2352 },
+ "labelOffset" : { "x" : 13, "y" : 33 }
+ }
+ }, {
+ "id" : "f197",
+ "type" : "TaskEnd",
+ "visual" : {
+ "at" : { "x" : 608, "y" : 2384 },
+ "labelOffset" : { "x" : 13, "y" : 33 }
+ }
+ }, {
+ "id" : "f199",
+ "type" : "TaskEnd",
+ "visual" : {
+ "at" : { "x" : 608, "y" : 2416 },
+ "labelOffset" : { "x" : 13, "y" : 33 }
+ }
+ }, {
+ "id" : "f200",
+ "type" : "TaskEnd",
+ "visual" : {
+ "at" : { "x" : 608, "y" : 2448 },
+ "labelOffset" : { "x" : 13, "y" : 33 }
+ }
+ }, {
+ "id" : "f201",
+ "type" : "TaskEnd",
+ "visual" : {
+ "at" : { "x" : 544, "y" : 2480 },
+ "labelOffset" : { "x" : 13, "y" : 33 }
+ }
+ }, {
+ "id" : "f202",
+ "type" : "TaskEnd",
+ "visual" : {
+ "at" : { "x" : 512, "y" : 2480 },
+ "labelOffset" : { "x" : 13, "y" : 33 }
+ }
+ }, {
+ "id" : "f205",
+ "type" : "TaskEnd",
+ "visual" : {
+ "at" : { "x" : 608, "y" : 2480 },
+ "labelOffset" : { "x" : 13, "y" : 33 }
+ }
+ }, {
+ "id" : "f206",
+ "type" : "TaskEnd",
+ "visual" : {
+ "at" : { "x" : 576, "y" : 2480 },
+ "labelOffset" : { "x" : 13, "y" : 33 }
+ }
+ }, {
+ "id" : "f215",
+ "type" : "TriggerCall",
+ "name" : "Create a case has lots of tasks",
+ "config" : {
+ "processCall" : "Start Processes/DataCreation:createCaseHasLotsOfTasks()"
+ },
+ "visual" : {
+ "at" : { "x" : 576, "y" : 2144 }
+ },
+ "connect" : [
+ { "id" : "f219", "to" : "f222" }
+ ]
+ }, {
+ "id" : "f217",
+ "type" : "Alternative",
+ "name" : "counter < 50",
+ "config" : {
+ "conditions" : {
+ "f218" : "in.counter < 50"
+ }
+ },
+ "visual" : {
+ "at" : { "x" : 384, "y" : 2144 },
+ "labelOffset" : { "x" : -24, "y" : -8 }
+ },
+ "connect" : [
+ { "id" : "f218", "to" : "f215", "label" : {
+ "name" : "Yes"
+ }, "color" : "default" },
+ { "id" : "f221", "to" : "f220", "label" : {
+ "name" : "No"
+ } }
+ ]
+ }, {
+ "id" : "f220",
+ "type" : "TaskEnd",
+ "visual" : {
+ "at" : { "x" : 384, "y" : 2208 }
+ }
+ }, {
+ "id" : "f222",
+ "type" : "Script",
+ "name" : "Increase counter",
+ "config" : {
+ "output" : {
+ "code" : [
+ "import java.lang.Thread;",
+ "in.counter++;",
+ "Thread.sleep(1000);",
+ "ivy.log.warn(\"Increased counter {0} of business case {1}\", in.counter, ivy.case.getId());"
+ ]
+ }
+ },
+ "visual" : {
+ "at" : { "x" : 576, "y" : 2064 }
+ },
+ "connect" : [
+ { "id" : "f223", "to" : "f217", "via" : [ { "x" : 384, "y" : 2064 } ] }
+ ]
+ }, {
+ "id" : "f204",
+ "type" : "Script",
+ "name" : "Increase counter",
+ "config" : {
+ "output" : {
+ "code" : [
+ "import java.lang.Thread;",
+ "in.persistedCounter++;",
+ "Thread.sleep(100);",
+ "ivy.log.warn(\"Increased counter {0} of case {1}\", in.persistedCounter, ivy.case.getId());"
+ ]
+ }
+ },
+ "visual" : {
+ "at" : { "x" : 384, "y" : 2272 }
+ },
+ "connect" : [
+ { "id" : "f203", "to" : "f224" }
+ ]
+ }, {
+ "id" : "f224",
+ "type" : "Alternative",
+ "name" : "counter < 10",
+ "config" : {
+ "conditions" : {
+ "f225" : "in.persistedCounter < 10"
+ }
+ },
+ "visual" : {
+ "at" : { "x" : 384, "y" : 2352 },
+ "labelOffset" : { "x" : -24, "y" : -8 }
+ },
+ "connect" : [
+ { "id" : "f225", "to" : "f193", "label" : {
+ "name" : "Yes"
+ }, "color" : "default", "var" : "in1" },
+ { "id" : "f226", "to" : "f214", "label" : {
+ "name" : "No"
+ } }
+ ]
+ }, {
+ "id" : "f214",
+ "type" : "TaskEnd",
+ "visual" : {
+ "at" : { "x" : 384, "y" : 2480 }
+ }
+ }, {
+ "id" : "f227",
+ "type" : "TaskEnd",
+ "visual" : {
+ "at" : { "x" : 480, "y" : 2480 },
+ "labelOffset" : { "x" : 13, "y" : 33 }
+ }
} ]
}
\ No newline at end of file
diff --git a/AxonIvyPortal/portal-product/pom.xml b/AxonIvyPortal/portal-product/pom.xml
index 6bdcfa2960a..51d02c681b0 100644
--- a/AxonIvyPortal/portal-product/pom.xml
+++ b/AxonIvyPortal/portal-product/pom.xml
@@ -24,7 +24,7 @@
Axonivy Repo
release-repo
- http://repo.axonivy.com/artifactory/libs-release/
+ https://repo.axonivy.com/artifactory/libs-release/
default
@@ -35,7 +35,7 @@
Axonivy Repo
snapshots-repo
- http://repo.axonivy.com/artifactory/libs-snapshot/
+ https://repo.axonivy.com/artifactory/libs-snapshot/
default
diff --git a/AxonIvyPortal/portal-selenium-test/jmeter/portal_walkthrough_testplan.jmx b/AxonIvyPortal/portal-selenium-test/jmeter/portal_walkthrough_testplan.jmx
index b8279fee7d0..68a9ea29895 100644
--- a/AxonIvyPortal/portal-selenium-test/jmeter/portal_walkthrough_testplan.jmx
+++ b/AxonIvyPortal/portal-selenium-test/jmeter/portal_walkthrough_testplan.jmx
@@ -1650,7 +1650,7 @@
true
- Create test data with category attach to one business case
+ Business case has lots of tasks cases
=
true
case-default_case_list_dashboard_case_1:quick-search-form:quick-search-input-0
diff --git a/AxonIvyPortal/portal-selenium-test/resources/js/document-screenshot.js b/AxonIvyPortal/portal-selenium-test/resources/js/document-screenshot.js
index 72d33cbad1f..d6de1e6f34c 100644
--- a/AxonIvyPortal/portal-selenium-test/resources/js/document-screenshot.js
+++ b/AxonIvyPortal/portal-selenium-test/resources/js/document-screenshot.js
@@ -124,7 +124,7 @@ function highlightProcessItems() {
}
function highlightEditProcessIcon() {
- appendStepAnnotation($("[id$='process-widget:edit-process-form:edit-process-icon:awesome-icon-selection']"), "4", -10, 100);
+ appendStepAnnotation($("[id$='process-widget:edit-process-form:edit-process-icon:awesome-icon-selection']"), "4", -40, 110);
}
function highlightEditProcessDialog() {
diff --git a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/document/screenshot/PortalCasesScreenshotTest.java b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/document/screenshot/PortalCasesScreenshotTest.java
index ffd8a3412be..8a6f125fe7f 100644
--- a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/document/screenshot/PortalCasesScreenshotTest.java
+++ b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/document/screenshot/PortalCasesScreenshotTest.java
@@ -84,7 +84,7 @@ public void screenshotCaseDetails() throws IOException {
ScreenshotUtils.captureElementWithMarginOptionScreenshot(detailsPage.openAddAttachmentDialog(),
ScreenshotUtils.CASE_DETAIL_FOLDER + "how-to-attach-document-to-case", new ScreenshotMargin(10));
detailsPage.closeAddAttachmentDialog();
- detailsPage.uploadDocumentWithoutError(FileHelper.getAbsolutePathToTestFile("test-no-files-no-js.pdf"));
+ detailsPage.uploadDocument(FileHelper.getAbsolutePathToTestFile("test-no-files-no-js.pdf"));
refreshPage();
detailsPage.waitForCaseDetailsDisplay();
diff --git a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/document/screenshot/PortalProcessesScreenshotTest.java b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/document/screenshot/PortalProcessesScreenshotTest.java
index d7421a40e6a..84856693bec 100644
--- a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/document/screenshot/PortalProcessesScreenshotTest.java
+++ b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/document/screenshot/PortalProcessesScreenshotTest.java
@@ -79,10 +79,11 @@ public void screenshotPortalFullProcessesList() throws IOException {
ScreenshotUtils.captureElementWithMarginOptionScreenshot(processWidget.getProcessEditMenu(0),
ScreenshotUtils.PROCESSES_WIDGET_FOLDER + "edit-process-menu-item", new ScreenshotMargin(150, 200));
processWidget.clickOnProcessEditMenu(0);
+ ScreenshotUtils.maximizeBrowser();
ScreenshotUtils.executeDecorateJs("highlightEditProcessDialog()");
ScreenshotUtils.executeDecorateJs("highlightEditProcessIcon()");
ScreenshotUtils.captureElementWithMarginOptionScreenshot(processWidget.getEditProcessDialog(),
- ScreenshotUtils.PROCESSES_WIDGET_FOLDER + "edit-process-dialog", new ScreenshotMargin(10));
+ ScreenshotUtils.PROCESSES_WIDGET_FOLDER + "edit-process-dialog", new ScreenshotMargin(5));
ScreenshotUtils.resizeBrowser(new Dimension(1366, 800));
refreshPage();
processWidget.waitUtilProcessWidgetDisplayed();
diff --git a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/CaseDetailsPage.java b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/CaseDetailsPage.java
index cec20f12a4e..e069a25ee19 100644
--- a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/CaseDetailsPage.java
+++ b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/CaseDetailsPage.java
@@ -850,6 +850,11 @@ public void uploadDocumentWithoutError(String pathToFile) {
$("button[id$='document:document-upload-close-command']").shouldBe(getClickableCondition(), DEFAULT_TIMEOUT)
.click();
}
+
+ public void uploadDocument(String pathToFile) {
+ $("input[id$='document-upload-panel_input']").shouldBe(exist, DEFAULT_TIMEOUT)
+ .shouldBe(Condition.hidden, DEFAULT_TIMEOUT).sendKeys(pathToFile);
+ }
public void openAddDocumentDialogAndUploadDocument(String pathToFile) {
getAddAttachmentDialog();
diff --git a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/CaseEditWidgetNewDashBoardPage.java b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/CaseEditWidgetNewDashBoardPage.java
index 240f8b4b48b..0ac3272b52e 100644
--- a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/CaseEditWidgetNewDashBoardPage.java
+++ b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/CaseEditWidgetNewDashBoardPage.java
@@ -424,4 +424,16 @@ public void resizeColumn() {
.clickAndHold(element)
.perform();
}
+
+ public void clickOnCaseNameColumn() {
+ $("div[id$='case-widget-preview:dashboard-cases']").shouldBe(appear, DEFAULT_TIMEOUT)
+ .$("th[id$='dashboard-cases-columns:1']").shouldBe(getClickableCondition()).click();
+ }
+
+ public SelenideElement getFirstCaseOfCaseWidget() {
+ $("div[id$='case-widget-preview:dashboard-cases']").shouldBe(appear, DEFAULT_TIMEOUT).$$("table tbody tr").get(0).shouldBe(appear,
+ DEFAULT_TIMEOUT);
+ return $("div[id$='case-widget-preview:dashboard-cases']").$$("table tbody tr").get(0);
+ }
+
}
diff --git a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/CaseWidgetNewDashBoardPage.java b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/CaseWidgetNewDashBoardPage.java
index 4b2914eac2b..59a7e13f672 100644
--- a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/CaseWidgetNewDashBoardPage.java
+++ b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/CaseWidgetNewDashBoardPage.java
@@ -162,7 +162,7 @@ public void nextPageTable() {
}
public void resetFilter() {
- $("div.filter-overlay-panel__footer").shouldBe(appear, DEFAULT_TIMEOUT).$$("button[id$='reset-button']")
+ $("div.filter-overlay-panel__footer").shouldBe(appear, DEFAULT_TIMEOUT).$$("a[id$='reset-button']")
.filter(text("Reset")).first().shouldBe(getClickableCondition(), DEFAULT_TIMEOUT).click();
$("div.filter-overlay-panel__footer").shouldBe(disappear, DEFAULT_TIMEOUT);
waitForElementClickable($$("div.table-widget-panel")
@@ -269,7 +269,7 @@ public void removeAllFilterItems() {
}
public void openManageFiltersDialog() {
- $("div#manage-filter").shouldBe(appear, DEFAULT_TIMEOUT).$("button").shouldBe(getClickableCondition()).click();
+ $("div#manage-filter").shouldBe(appear, DEFAULT_TIMEOUT).$("a").shouldBe(getClickableCondition()).click();
}
public void closeManageFilterDialog() {
diff --git a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/NewDashboardPage.java b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/NewDashboardPage.java
index aa73b4029ce..d06faa3f5f6 100644
--- a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/NewDashboardPage.java
+++ b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/NewDashboardPage.java
@@ -545,7 +545,7 @@ public SelenideElement getCompactModeProcessFilterPanelSaveButton() {
}
public SelenideElement getCompactModeProcessFilterPanelResetButton() {
- return getCompactModeProcessFilterPanel().$("button[id$=':reset-button']");
+ return getCompactModeProcessFilterPanel().$("a[id$=':reset-button']");
}
public void resetCompactModeProcessFilterPanel() {
@@ -1033,7 +1033,7 @@ public NotificationCompactPage openNotificationPanel() {
}
public void clickOnManageFilterLink() {
- $("div[class*='filter-overlay-panel__footer']").shouldBe(appear, DEFAULT_TIMEOUT).$("div#manage-filter").shouldBe(appear, DEFAULT_TIMEOUT).$("button[class*='saved-filter__manage-filter']").shouldBe(getClickableCondition(), DEFAULT_TIMEOUT).click();
+ $("div[class*='filter-overlay-panel__footer']").shouldBe(appear, DEFAULT_TIMEOUT).$("div#manage-filter").shouldBe(appear, DEFAULT_TIMEOUT).$("a[class*='saved-filter__manage-filter']").shouldBe(getClickableCondition(), DEFAULT_TIMEOUT).click();
$("[id$='manage-filter-dialog']").shouldBe(appear, DEFAULT_TIMEOUT);
}
diff --git a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/TaskEditWidgetNewDashBoardPage.java b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/TaskEditWidgetNewDashBoardPage.java
index f0c8a6497d8..efd88f36f55 100644
--- a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/TaskEditWidgetNewDashBoardPage.java
+++ b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/TaskEditWidgetNewDashBoardPage.java
@@ -478,4 +478,21 @@ public SelenideElement getExpandModeCheckbox() {
public void clickOnExpandModeCheckbox() {
getExpandModeCheckbox().shouldBe(getClickableCondition(), DEFAULT_TIMEOUT).click();
}
+
+ public void clickOnTaskNameColumn() {
+ $("div[id$='task-widget-preview:dashboard-tasks']").shouldBe(appear, DEFAULT_TIMEOUT)
+ .$("th[id$='dashboard-tasks-columns:3']").shouldBe(getClickableCondition()).click();
+ }
+
+ public void clickOnTaskPriorityColumn() {
+ $("div[id$='task-widget-preview:dashboard-tasks']").shouldBe(appear, DEFAULT_TIMEOUT)
+ .$("th[id$='dashboard-tasks-columns:1']").shouldBe(getClickableCondition()).click();
+ }
+
+ public SelenideElement getFirstTaskOfTaskWidget() {
+ $("div[id$='task-widget-preview:dashboard-tasks']").shouldBe(appear, DEFAULT_TIMEOUT).$$("table tbody tr").get(0).shouldBe(appear,
+ DEFAULT_TIMEOUT);
+ return $("div[id$='task-widget-preview:dashboard-tasks']").$$("table tbody tr").get(0);
+ }
+
}
\ No newline at end of file
diff --git a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/TaskWidgetNewDashBoardPage.java b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/TaskWidgetNewDashBoardPage.java
index b2c269d7f42..c94ce3ae09f 100644
--- a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/TaskWidgetNewDashBoardPage.java
+++ b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/TaskWidgetNewDashBoardPage.java
@@ -132,7 +132,7 @@ public void applyFilter() {
}
public void resetFilter() {
- $("div.filter-overlay-panel__footer").shouldBe(appear, DEFAULT_TIMEOUT).$$("button[id$='reset-button']")
+ $("div.filter-overlay-panel__footer").shouldBe(appear, DEFAULT_TIMEOUT).$$("a[id$='reset-button']")
.filter(text("Reset")).first().shouldBe(getClickableCondition(), DEFAULT_TIMEOUT).click();
}
@@ -183,7 +183,7 @@ public boolean hasSavedFilterItem(String filterName) {
}
public void clickOnManageFilterLink() {
- $("div#manage-filter").shouldBe(appear, DEFAULT_TIMEOUT).$("button").shouldBe(getClickableCondition()).click();
+ $("div#manage-filter").shouldBe(appear, DEFAULT_TIMEOUT).$("a").shouldBe(getClickableCondition()).click();
$("[id$='manage-filter-dialog']").shouldBe(appear, DEFAULT_TIMEOUT);
}
@@ -530,7 +530,7 @@ public void saveFilter(String widgetFilterName) {
}
public void openManageFiltersDialog() {
- $("div#manage-filter").shouldBe(appear, DEFAULT_TIMEOUT).$("button").shouldBe(getClickableCondition()).click();
+ $("div#manage-filter").shouldBe(appear, DEFAULT_TIMEOUT).$("a").shouldBe(getClickableCondition()).click();
}
public void removeAllFilterItems() {
diff --git a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/TemplatePage.java b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/TemplatePage.java
index 4038d8afe67..952b993f09e 100644
--- a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/TemplatePage.java
+++ b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/page/TemplatePage.java
@@ -481,6 +481,10 @@ public NewDashboardPage openTaskList() {
return openMainMenu().selectTaskMenu();
}
+ public void waitForTaskTitleAppear() {
+ waitForElementDisplayed(By.id("title"), true);
+ }
+
public void waitForIFrameContentVisible() {
waitForIFrameScreenshotSizeGreaterThan(IFRAME_SCREENSHOT_FILE_SIZE_AT_MINIMUM);
}
diff --git a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/LanguageSettingTest.java b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/LanguageSettingTest.java
index f0b988a2334..8699cc2c955 100644
--- a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/LanguageSettingTest.java
+++ b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/LanguageSettingTest.java
@@ -8,6 +8,7 @@
import com.axonivy.portal.selenium.common.NavigationHelper;
import com.axonivy.portal.selenium.page.MainMenuPage;
import com.axonivy.portal.selenium.page.NewDashboardPage;
+import com.axonivy.portal.selenium.page.TaskIFrameTemplatePage;
import com.axonivy.portal.selenium.page.TopMenuTaskWidgetPage;
import com.axonivy.portal.selenium.page.UserProfilePage;
import com.axonivy.portal.selenium.page.WorkingTaskDialogFromUserProfilePage;
@@ -26,9 +27,10 @@ public void setup() {
public void testChangeLanguageWhenWorkingOnTask() {
NavigationHelper.navigateToTaskList();
TopMenuTaskWidgetPage taskWidget = new TopMenuTaskWidgetPage();
- taskWidget.startTaskIFrameByIndex(0);
+ TaskIFrameTemplatePage taskPage = taskWidget.startTaskIFrameByIndex(0);
taskWidget.switchBackToParent();
- taskWidget.clickOnMyProfile();
+ taskPage.waitForTaskTitleAppear();
+ taskPage.clickOnMyProfile();
WorkingTaskDialogFromUserProfilePage workingTaskDialogPage = new WorkingTaskDialogFromUserProfilePage();
workingTaskDialogPage.leaveTask();
UserProfilePage userProfilePage = new UserProfilePage();
diff --git a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/dashboard/DashboardEditCaseWidgetTest.java b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/dashboard/DashboardEditCaseWidgetTest.java
index bc6f4702b75..3d55583f38e 100644
--- a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/dashboard/DashboardEditCaseWidgetTest.java
+++ b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/dashboard/DashboardEditCaseWidgetTest.java
@@ -1,5 +1,7 @@
package com.axonivy.portal.selenium.test.dashboard;
+import static com.codeborne.selenide.Condition.text;
+
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Dimension;
@@ -12,6 +14,7 @@
import com.axonivy.portal.selenium.common.ScreenshotUtils;
import com.axonivy.portal.selenium.common.TestAccount;
import com.axonivy.portal.selenium.page.CaseEditWidgetNewDashBoardPage;
+import com.axonivy.portal.selenium.page.CaseWidgetNewDashBoardPage;
import com.axonivy.portal.selenium.page.DashboardConfigurationPage;
import com.axonivy.portal.selenium.page.NewDashboardDetailsEditPage;
import com.codeborne.selenide.CollectionCondition;
@@ -19,6 +22,10 @@
@IvyWebTest
public class DashboardEditCaseWidgetTest extends BaseTest {
private static final String NAME_STR = "Name";
+ private static final String YOUR_CASES_WIDGET = "Your Cases";
+
+ private static final String ALPHA_COMPANY = "Alpha Company";
+ private static final String ORDER_PIZZA = " Order Pizza";
@Override
@BeforeEach
@@ -201,4 +208,24 @@ private NewDashboardDetailsEditPage gotoEditPublicDashboardPage() {
return modificationPage.navigateToEditDashboardDetailsByName("Dashboard");
}
+ @Test
+ public void testDefaultSortOnCaseWidget() {
+ redirectToRelativeLink(createCaseWithTechnicalCaseUrl);
+ redirectToRelativeLink(createAlphaCompanyUrl);
+
+ LinkNavigator.redirectToPortalDashboardConfiguration();
+ var configurationPage = new DashboardConfigurationPage();
+ var modificationPage = configurationPage.openEditPublicDashboardsPage();
+ modificationPage.navigateToEditDashboardDetailsByName("Dashboard");
+
+ CaseWidgetNewDashBoardPage caseWidget = new CaseWidgetNewDashBoardPage(YOUR_CASES_WIDGET);
+ CaseEditWidgetNewDashBoardPage caseEditWidgetPage = caseWidget.openEditWidget();
+
+ caseEditWidgetPage.clickOnCaseNameColumn();
+ caseEditWidgetPage.getFirstCaseOfCaseWidget().shouldHave(text(ALPHA_COMPANY), DEFAULT_TIMEOUT);;
+
+ caseEditWidgetPage.clickOnCaseNameColumn();
+ caseEditWidgetPage.getFirstCaseOfCaseWidget().shouldHave(text(ORDER_PIZZA), DEFAULT_TIMEOUT);;
+
+ }
}
diff --git a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/dashboard/DashboardEditTaskWidgetTest.java b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/dashboard/DashboardEditTaskWidgetTest.java
index bf56c48e4ae..1fffa4e4867 100644
--- a/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/dashboard/DashboardEditTaskWidgetTest.java
+++ b/AxonIvyPortal/portal-selenium-test/src_test/com/axonivy/portal/selenium/test/dashboard/DashboardEditTaskWidgetTest.java
@@ -1,5 +1,7 @@
package com.axonivy.portal.selenium.test.dashboard;
+import static com.codeborne.selenide.Condition.text;
+
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -12,10 +14,15 @@
import com.axonivy.portal.selenium.page.DashboardConfigurationPage;
import com.axonivy.portal.selenium.page.NewDashboardDetailsEditPage;
import com.axonivy.portal.selenium.page.TaskEditWidgetNewDashBoardPage;
+import com.axonivy.portal.selenium.page.TaskWidgetNewDashBoardPage;
import com.codeborne.selenide.CollectionCondition;
@IvyWebTest
public class DashboardEditTaskWidgetTest extends BaseTest {
+ private static final String YOUR_TASKS_WIDGET = "Your Tasks";
+ private static final String MATERNITY_LEAVE_REQUEST = "Maternity Leave Request";
+ private static final String SICK_LEAVE_REQUEST = "Sick Leave Request";
+
private NewDashboardDetailsEditPage newDashboardDetailsEditPage;
@Override
@@ -165,4 +172,26 @@ public void testFilterResponsible() {
taskWidget.applyFilter();
taskWidget.countAllTasks().shouldHave(CollectionCondition.size(0));
}
+
+ @Test
+ public void testDefaultSortOnTaskWidget() {
+ LinkNavigator.redirectToPortalDashboardConfiguration();
+ var configurationPage = new DashboardConfigurationPage();
+ var modificationPage = configurationPage.openEditPublicDashboardsPage();
+ modificationPage.navigateToEditDashboardDetailsByName("Dashboard");
+
+ TaskWidgetNewDashBoardPage taskWidget = new TaskWidgetNewDashBoardPage(YOUR_TASKS_WIDGET);
+ TaskEditWidgetNewDashBoardPage taskEditWidgetPage = taskWidget.openEditTaskWidget();
+
+ // sort by task priority
+ taskEditWidgetPage.clickOnTaskPriorityColumn();
+ taskEditWidgetPage.getFirstTaskOfTaskWidget();
+ taskEditWidgetPage.getFirstTaskOfTaskWidget().shouldHave(text(SICK_LEAVE_REQUEST), DEFAULT_TIMEOUT);
+
+ // sort by task name
+ taskEditWidgetPage.clickOnTaskNameColumn();
+ taskEditWidgetPage.getFirstTaskOfTaskWidget();
+ taskEditWidgetPage.getFirstTaskOfTaskWidget().shouldHave(text(MATERNITY_LEAVE_REQUEST), DEFAULT_TIMEOUT);
+
+ }
}
diff --git a/AxonIvyPortal/portal/cms/cms_de.yaml b/AxonIvyPortal/portal/cms/cms_de.yaml
index dd66e122eea..f7223acbf51 100644
--- a/AxonIvyPortal/portal/cms/cms_de.yaml
+++ b/AxonIvyPortal/portal/cms/cms_de.yaml
@@ -410,6 +410,7 @@ ch.ivy.addon.portalkit.ui.jsf:
active: Aktiviert
add: Hinzufügen
addDocument: Dokument hinzufügen
+ addLink: Link hinzufügen
addNote: Notiz hinzufügen
allCategories: Alle Kategorien
allTypes: Alle Typen
diff --git a/AxonIvyPortal/portal/cms/cms_en.yaml b/AxonIvyPortal/portal/cms/cms_en.yaml
index aee201428bf..73c02a2e09d 100644
--- a/AxonIvyPortal/portal/cms/cms_en.yaml
+++ b/AxonIvyPortal/portal/cms/cms_en.yaml
@@ -409,6 +409,7 @@ ch.ivy.addon.portalkit.ui.jsf:
active: Active
add: Add
addDocument: Add document
+ addLink: Add Link
addNote: Add note
allCategories: All Categories
allTypes: All types
diff --git a/AxonIvyPortal/portal/cms/cms_es.yaml b/AxonIvyPortal/portal/cms/cms_es.yaml
index f74b3738de8..cc0eeedb7d0 100644
--- a/AxonIvyPortal/portal/cms/cms_es.yaml
+++ b/AxonIvyPortal/portal/cms/cms_es.yaml
@@ -411,6 +411,7 @@ ch.ivy.addon.portalkit.ui.jsf:
active: Activado
add: Añadir
addDocument: Agregar documento
+ addLink: Añadir enlace
addNote: Agregar nota
allCategories: Todas las categorias
allTypes: Todos los tipos
diff --git a/AxonIvyPortal/portal/cms/cms_fr.yaml b/AxonIvyPortal/portal/cms/cms_fr.yaml
index 53419436396..c343a2a9a7b 100644
--- a/AxonIvyPortal/portal/cms/cms_fr.yaml
+++ b/AxonIvyPortal/portal/cms/cms_fr.yaml
@@ -408,6 +408,7 @@ ch.ivy.addon.portalkit.ui.jsf:
active: Activé
add: Ajouter
addDocument: Ajouter un document
+ addLink: Ajouter un lien
addNote: Ajouter une note
allCategories: Toutes les catégories
allTypes: Tous les types
diff --git a/AxonIvyPortal/portal/config/variables/Portal/Dashboard.json b/AxonIvyPortal/portal/config/variables/Portal/Dashboard.json
index c222e3a9993..c3116189da4 100644
--- a/AxonIvyPortal/portal/config/variables/Portal/Dashboard.json
+++ b/AxonIvyPortal/portal/config/variables/Portal/Dashboard.json
@@ -377,7 +377,7 @@
],
"layout": {
"w": 12,
- "h": 8,
+ "h": 12,
"x": 0,
"y": 0
},
@@ -489,7 +489,7 @@
],
"layout": {
"w": 12,
- "h": 8,
+ "h": 12,
"x": 0,
"y": 0
},
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 668df5c4364..25dc3cf939d 100644
--- a/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/MenuView.java
+++ b/AxonIvyPortal/portal/src/ch/addon/portal/generic/menu/MenuView.java
@@ -91,8 +91,6 @@ 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) {
@@ -152,13 +150,17 @@ private MenuElement buildDashboardItem() {
String mainMenuDisplayName = mainMenuEntryService.getNameInCurrentLocale();
String mainMenuIcon = mainMenuEntryService.getMenuIcon();
- var subItemDashboards = getSubItemDashboards();
+ List subItemDashboards = getSubItemDashboards();
if (subItemDashboards.size() > 1) {
return buildDashboardGroupMenu(subItemDashboards, dashboardTitle, mainMenuDisplayName, mainMenuIcon,
currentLanguage, dashboardLink);
+ } else if (subItemDashboards.size() == 1) {
+ Dashboard dashboard = subItemDashboards.getFirst();
+ String localizedTitle = getLocalizedTitle(dashboard, currentLanguage, dashboardTitle);
+ return buildSingleDashboardMenu(localizedTitle, dashboardId, dashboardLink, dashboard.getIcon());
}
-
- return buildSingleDashboardMenu(dashboardTitle, dashboardId, dashboardLink);
+
+ return buildSingleDashboardMenu(dashboardTitle, "", dashboardLink, "");
}
private String determineDashboardLink() {
@@ -240,9 +242,11 @@ private void setMenuExpansion(DefaultSubMenu dashboardGroupMenu) {
}
}
- private MenuElement buildSingleDashboardMenu(String dashboardTitle, String dashboardId, String dashboardLink) {
+ private MenuElement buildSingleDashboardMenu(String dashboardTitle, String dashboardId, String dashboardLink,
+ String dashboardIcon) {
var dashboardMenu = new PortalMenuBuilder(dashboardTitle, MenuKind.DASHBOARD, this.isWorkingOnATask)
- .icon(PortalMenuItem.DEFAULT_DASHBOARD_ICON).url(dashboardLink).workingTaskId(this.workingTaskId).build();
+ .icon(StringUtils.isNoneEmpty(dashboardIcon) ? dashboardIcon : PortalMenuItem.DEFAULT_DASHBOARD_ICON)
+ .url(dashboardLink).workingTaskId(this.workingTaskId).build();
if (StringUtils.isBlank(dashboardId)) {
dashboardId = dashboardMenu.getId();
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 b573ec9dde1..1a1ea137112 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
@@ -91,38 +91,28 @@ public void init() {
currentDashboardIndex = 0;
dashboards = collectDashboards();
-
if (isReadOnlyMode) {
MenuView menuView = (MenuView) ManagedBeans.get("menuView");
menuView.updateDashboardCache(dashboards);
}
- if (CollectionUtils.isNotEmpty(DashboardUtils.getDashboardsWithoutMenuItem())) {
+ if (CollectionUtils.isNotEmpty(DashboardUtils.getDashboardsWithoutMenuItem())
+ || isRequestPathForMainOrDetailModification()) {
updateSelectedDashboardIdFromSessionAttribute();
- currentDashboardIndex = findIndexOfDashboardById(selectedDashboardId);
- selectedDashboard = dashboards.get(currentDashboardIndex);
-
- String selectedDashboardName = selectedDashboard.getTitles().stream()
- .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())
- && DashboardUtils.getDashboardsWithoutMenuItem().size() > 1)) {
- DashboardUtils.storeDashboardInSession(selectedDashboard.getId());
- }
- if (isReadOnlyMode) {
- DashboardUtils.highlightDashboardMenuItem(selectedDashboard.getId());
- }
- }
+ updateSelectedDashboard();
+ storeAndHighlightDashboardIfRequired();
+ }
buildWidgetModels(selectedDashboard);
isRunningTaskWhenClickingOnTaskInList = GlobalSettingService.getInstance()
.findGlobalSettingValue(GlobalVariable.DEFAULT_BEHAVIOUR_WHEN_CLICKING_ON_LINE_IN_TASK_LIST)
.equals(BehaviourWhenClickingOnLineInTaskList.RUN_TASK.name());
+ // Set responsive option for default task list and case list
+ if (DashboardUtils.isDefaultCaseListDashboard(selectedDashboard)
+ || DashboardUtils.isDefaultTaskListDashboard(selectedDashboard)) {
+ selectedDashboard.setIsResponsive(true);
+ }
+
buildClientStatisticApiUri();
}
@@ -131,6 +121,33 @@ private void buildClientStatisticApiUri() {
.getExternalContext().getRequestContextPath() + "/api/statistics/data";
}
+ private boolean isRequestPathForMainOrDetailModification() {
+ String requestPath = Ivy.request().getRequestPath();
+ return requestPath.endsWith("/PortalMainDashboard.xhtml")
+ || requestPath.endsWith("/PortalDashboardDetailModification.xhtml");
+ }
+
+ private void updateSelectedDashboard() {
+ currentDashboardIndex = findIndexOfDashboardById(selectedDashboardId);
+ selectedDashboard = dashboards.get(currentDashboardIndex);
+
+ String selectedDashboardName = selectedDashboard.getTitles().stream()
+ .filter(displayName -> displayName.getLocale().equals(Ivy.session().getContentLocale())).findFirst()
+ .orElseGet(() -> selectedDashboard.getTitles().get(0)).getValue();
+ setSelectedDashboardName(selectedDashboardName);
+ initShareDashboardLink(selectedDashboard);
+ }
+
+ private void storeAndHighlightDashboardIfRequired() {
+ if (StringUtils.isBlank(selectedDashboardId) || (!selectedDashboardId.equalsIgnoreCase(selectedDashboard.getId())
+ && DashboardUtils.getDashboardsWithoutMenuItem().size() > 1)) {
+ DashboardUtils.storeDashboardInSession(selectedDashboard.getId());
+ }
+ if (isReadOnlyMode) {
+ DashboardUtils.highlightDashboardMenuItem(selectedDashboard.getId());
+ }
+ }
+
protected List collectDashboards() {
return DashboardUtils.collectDashboards();
}
diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/DashboardTemplateSelectionBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/DashboardTemplateSelectionBean.java
index 0b7a3a48e8a..a1fd3a1c3c4 100644
--- a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/DashboardTemplateSelectionBean.java
+++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/DashboardTemplateSelectionBean.java
@@ -46,6 +46,7 @@ private void onAddDashboard(boolean isPublicDashboard) {
private void mappingCommonDataToNewDashboard(String templateId, String dashboardId) {
this.selectedDashboard.setTemplateId(templateId);
+ this.selectedDashboard.setPermissionDTOs(new ArrayList<>());
this.selectedDashboard.setId(dashboardId);
this.selectedDashboard.setTitles(new ArrayList<>());
this.selectedDashboard.setIcon(this.isPublicDashboard ? PUBLIC_DASHBOARD_DEFAULT_ICON : PRIVATE_DASHBOARD_DEFAULT_ICON);
diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/IFrameTaskTemplateBean.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/IFrameTaskTemplateBean.java
index c7b6b99bcd2..af864d25651 100644
--- a/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/IFrameTaskTemplateBean.java
+++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portal/generic/bean/IFrameTaskTemplateBean.java
@@ -54,6 +54,7 @@ public class IFrameTaskTemplateBean extends AbstractTaskTemplateBean implements
public static final String PORTAL_GROWL_MESSGE_PARAM = "portalGrowlMessage";
private static final String DEFAULT_TASK_ICON = "si si-task-list-edit";
private static final String TASK_ICON = "taskIcon";
+ private static final String TASK_URL = "taskUrl";
private int currentProcessStep;
private List processSteps;
@@ -74,6 +75,12 @@ public class IFrameTaskTemplateBean extends AbstractTaskTemplateBean implements
private Long caseId = null;
+ public String getTaskUrl() {
+ return Optional.ofNullable(FacesContext.getCurrentInstance()
+ .getExternalContext().getRequestParameterMap().get(TASK_URL))
+ .orElse(StringUtils.EMPTY);
+ }
+
public void useTaskInIFrame() {
keepOverridePortalGrowl();
Map requestParamMap = getRequestParameterMap();
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 0896ec2dc67..234df2d8057 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
@@ -35,9 +35,13 @@ public class Dashboard extends AbstractConfiguration implements Serializable {
private String displayedPermission;
private Boolean isTopMenu;
+ @JsonIgnore
+ private Boolean isResponsive;
+
public Dashboard() {
// Set default values
isTopMenu = false;
+ isResponsive = false;
}
public Dashboard(Dashboard dashboard) {
@@ -54,6 +58,7 @@ public Dashboard(Dashboard dashboard) {
permissionDTOs = dashboard.permissionDTOs;
displayedPermission = dashboard.displayedPermission;
isTopMenu = dashboard.isTopMenu;
+ isResponsive = dashboard.isResponsive;
}
public String getTitle() {
@@ -146,6 +151,16 @@ public void setIsTopMenu(Boolean isTopMenu) {
this.isTopMenu = isTopMenu;
}
+ @JsonIgnore
+ public Boolean getIsResponsive() {
+ return isResponsive;
+ }
+
+ @JsonIgnore
+ public void setIsResponsive(Boolean isResponsive) {
+ this.isResponsive = isResponsive;
+ }
+
@Override
public int hashCode() {
final int prime = 31;
diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/CookieHelper.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/CookieHelper.java
index 0408b8e8451..2e7d1520ee6 100644
--- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/CookieHelper.java
+++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/CookieHelper.java
@@ -39,6 +39,7 @@ public void setCookie(String name, String value) {
}
}
cookie.setPath("/");
+ cookie.setSecure(true);
HttpServletResponse response = (HttpServletResponse) facesContext.getExternalContext().getResponse();
response.addCookie(cookie);
}
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 f42e63ec3d2..5a66ea4269e 100644
--- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/DashboardUtils.java
+++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/DashboardUtils.java
@@ -327,4 +327,13 @@ public static void updatePropertiesToNullIfCurrentValueIsDefaultValue(List "").contentEquals(DEFAULT_TASK_LIST_DASHBOARD);
+ }
+
+ public static boolean isDefaultCaseListDashboard(Dashboard dashboard) {
+ return Optional.ofNullable(dashboard).map(Dashboard::getId)
+ .orElseGet(() -> "").contentEquals(DEFAULT_CASE_LIST_DASHBOARD);
+ }
}
diff --git a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/DefaultDashboardUtils.java b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/DefaultDashboardUtils.java
index f092c03fb23..7c996cbaee0 100644
--- a/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/DefaultDashboardUtils.java
+++ b/AxonIvyPortal/portal/src/ch/ivy/addon/portalkit/util/DefaultDashboardUtils.java
@@ -53,7 +53,7 @@ public class DefaultDashboardUtils {
],
"layout": {
"w": 12,
- "h": 8,
+ "h": 12,
"x": 0,
"y": 0
},
@@ -168,7 +168,7 @@ public class DefaultDashboardUtils {
],
"layout": {
"w": 12,
- "h": 8,
+ "h": 12,
"x": 0,
"y": 0
},
diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/rest/ChatBotRestService.java b/AxonIvyPortal/portal/src/com/axonivy/portal/rest/ChatBotRestService.java
index d38106741b3..438d6d470f6 100644
--- a/AxonIvyPortal/portal/src/com/axonivy/portal/rest/ChatBotRestService.java
+++ b/AxonIvyPortal/portal/src/com/axonivy/portal/rest/ChatBotRestService.java
@@ -63,7 +63,8 @@ public Response processes(@PathParam("clientId") String clientId, ChatbotPayload
return Response.ok(toJson(response)).build();
} catch (NotFoundException e) {
- return Response.status(Status.NOT_FOUND).entity(e.getMessage()).build();
+ Ivy.log().error(e);
+ return Response.status(Status.NOT_FOUND).build();
}
}
diff --git a/AxonIvyPortal/portal/src/com/axonivy/portal/rest/GlobalSearchRestService.java b/AxonIvyPortal/portal/src/com/axonivy/portal/rest/GlobalSearchRestService.java
index efc3629eaef..01f57262ea9 100644
--- a/AxonIvyPortal/portal/src/com/axonivy/portal/rest/GlobalSearchRestService.java
+++ b/AxonIvyPortal/portal/src/com/axonivy/portal/rest/GlobalSearchRestService.java
@@ -11,6 +11,7 @@
import com.axonivy.portal.response.GlobalSearchResponse;
import com.axonivy.portal.service.GlobalSearchService;
+import ch.ivyteam.ivy.environment.Ivy;
import ch.ivyteam.ivy.security.ISecurityConstants;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
@@ -30,7 +31,8 @@ public Response processes(SearchPayload payload) {
GlobalSearchResponse result = service.searchProcesses(payload);
return Response.ok(result).build();
} catch (NotFoundException e) {
- return Response.status(Status.NOT_FOUND).entity(e.getMessage()).build();
+ Ivy.log().error(e);
+ return Response.status(Status.NOT_FOUND).build();
}
}
@@ -42,7 +44,8 @@ public Response tasks(SearchPayload payload) {
GlobalSearchResponse result = service.searchTasks(payload);
return Response.ok(result).build();
} catch (NotFoundException e) {
- return Response.status(Status.NOT_FOUND).entity(e.getMessage()).build();
+ Ivy.log().error(e);
+ return Response.status(Status.NOT_FOUND).build();
}
}
@@ -54,7 +57,8 @@ public Response cases(SearchPayload payload) {
GlobalSearchResponse result = service.searchCases(payload);
return Response.ok(result).build();
} catch (NotFoundException e) {
- return Response.status(Status.NOT_FOUND).entity(e.getMessage()).build();
+ Ivy.log().error(e);
+ return Response.status(Status.NOT_FOUND).build();
}
}
}
diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/CaseDocuments/CaseDocuments.xhtml b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/CaseDocuments/CaseDocuments.xhtml
index 5b3ad1a5c31..74e7f501aee 100644
--- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/CaseDocuments/CaseDocuments.xhtml
+++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/CaseDocuments/CaseDocuments.xhtml
@@ -99,13 +99,13 @@
-
+
diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/TaskDocuments/TaskDocuments.xhtml b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/TaskDocuments/TaskDocuments.xhtml
index 2e40333a337..b4c4e1da392 100644
--- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/TaskDocuments/TaskDocuments.xhtml
+++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/TaskDocuments/TaskDocuments.xhtml
@@ -99,13 +99,13 @@
-
+
diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/dashboard/PortalDashboardDetailModification/PortalDashboardDetailModification.xhtml b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/dashboard/PortalDashboardDetailModification/PortalDashboardDetailModification.xhtml
index 4d83a6a8f0a..e00fe4deb0b 100644
--- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/dashboard/PortalDashboardDetailModification/PortalDashboardDetailModification.xhtml
+++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/dashboard/PortalDashboardDetailModification/PortalDashboardDetailModification.xhtml
@@ -24,11 +24,12 @@
-
+ update="grid-stack @this" process="@this">
+
+ #{ivy.cms.co('/ch.ivy.addon.portalkit.ui.jsf/common/back')}
+
@@ -102,13 +103,14 @@
-
-
+
+
+
+
diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/dashboard/component/CaseWidget/CaseWidget.xhtml b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/dashboard/component/CaseWidget/CaseWidget.xhtml
index a955c99272a..6d37265bc9f 100644
--- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/dashboard/component/CaseWidget/CaseWidget.xhtml
+++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/dashboard/component/CaseWidget/CaseWidget.xhtml
@@ -52,7 +52,7 @@
-
+
diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/dashboard/component/DashboardModification/DashboardModification.xhtml b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/dashboard/component/DashboardModification/DashboardModification.xhtml
index a90abd57fac..d3e6db1fefd 100644
--- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/dashboard/component/DashboardModification/DashboardModification.xhtml
+++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/dashboard/component/DashboardModification/DashboardModification.xhtml
@@ -130,7 +130,7 @@
value="#{ivy.cms.co('/ch.ivy.addon.portalkit.ui.jsf/dashboard/dashboardManagement/deleteDashboardMessage',[dashboardModificationBean.selectedDashboard.title])}" />
-
-
@@ -52,7 +52,7 @@
+
diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/dashboard/component/WelcomeDashboardWidget/WelcomeDashboardWidget.xhtml b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/dashboard/component/WelcomeDashboardWidget/WelcomeDashboardWidget.xhtml
index e56100d9edd..7220bddd9d0 100644
--- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/dashboard/component/WelcomeDashboardWidget/WelcomeDashboardWidget.xhtml
+++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portal/generic/dashboard/component/WelcomeDashboardWidget/WelcomeDashboardWidget.xhtml
@@ -33,7 +33,7 @@
oncomplete="PF('new-widget-configuration-dialog').show()" />
-
@@ -253,17 +253,17 @@
-
-
-
+
+
+
+
diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portalkit/admin/AdminSettings/AdminSettings.xhtml b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portalkit/admin/AdminSettings/AdminSettings.xhtml
index 1accd261b13..f390f58154e 100644
--- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portalkit/admin/AdminSettings/AdminSettings.xhtml
+++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portalkit/admin/AdminSettings/AdminSettings.xhtml
@@ -81,7 +81,7 @@
process="@this" />
-
+
@@ -363,12 +363,14 @@
-
+
+
+
diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portalkit/component/ActionStep/ActionStep.xhtml b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portalkit/component/ActionStep/ActionStep.xhtml
index f91f3032968..7e008bc2554 100644
--- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portalkit/component/ActionStep/ActionStep.xhtml
+++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portalkit/component/ActionStep/ActionStep.xhtml
@@ -74,7 +74,7 @@
-
+
diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portalkit/component/CaseItemDetails/CaseItemDetails.xhtml b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portalkit/component/CaseItemDetails/CaseItemDetails.xhtml
index a035bbc8d98..b18ad939d28 100644
--- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portalkit/component/CaseItemDetails/CaseItemDetails.xhtml
+++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portalkit/component/CaseItemDetails/CaseItemDetails.xhtml
@@ -181,12 +181,14 @@
-
-
+
+
+
+
diff --git a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portalkit/component/CaseItemDocument/CaseItemDocument.xhtml b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portalkit/component/CaseItemDocument/CaseItemDocument.xhtml
index 4c966982edf..3d073e96869 100644
--- a/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portalkit/component/CaseItemDocument/CaseItemDocument.xhtml
+++ b/AxonIvyPortal/portal/src_hd/ch/ivy/addon/portalkit/component/CaseItemDocument/CaseItemDocument.xhtml
@@ -167,13 +167,13 @@
-
+
+ window.taskName = "Approve Investment";
+ window.taskIcon = "si si-bulb";
+ window.isHideTaskName = false;
+ window.caseId = "123456";
+ window.isHideCaseInfo = false;
+ window.currentProcessStep = 0;
+ window.processSteps = ["Create Investment Request", "Approve Investment Request"];
+ // Convert Java List of steps to JSON format if needed:
+ window.processSteps = #{portalComponentUtilsBean.convertToJSON(data.steps)};
+ window.isShowAllSteps = true;
+ window.processChainDirection = "VERTICAL";
+ window.processChainShape = "LINE";
+ window.isHideTaskAction = false;
+ window.isWorkingOnATask = false;
+ window.announcementInvisible = false;
+ window.isCardFrame = true;
+ window.viewName = "TASK_DETAIL";
+
-->
@@ -113,6 +113,19 @@
+
diff --git a/AxonIvyPortal/portal/webContent/layouts/restricted/decorator/TableWidget.xhtml b/AxonIvyPortal/portal/webContent/layouts/restricted/decorator/TableWidget.xhtml
index b8b8eefe3bc..6b54297ccbd 100644
--- a/AxonIvyPortal/portal/webContent/layouts/restricted/decorator/TableWidget.xhtml
+++ b/AxonIvyPortal/portal/webContent/layouts/restricted/decorator/TableWidget.xhtml
@@ -232,9 +232,12 @@