Date: Fri, 29 Mar 2024 13:37:40 +0000 (UTC) Message-ID: <1735958325.5.1711719460745@7fe93e023106> Subject: Exported From Confluence MIME-Version: 1.0 Content-Type: multipart/related; boundary="----=_Part_4_172772839.1711719460745" ------=_Part_4_172772839.1711719460745 Content-Type: text/html; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Content-Location: file:///C:/exported.html
You can enable users to select individual items in a result matr= ix dashboard portlet and run an action (trigger an event) on a button click= .
In this example, we have a Dashboard with a result matrix portlet listin= g LPG items. Users can select any of these items and run their recalculatio= n.
Under the hood, there are two logics associated with this Dashboard. One= logic (main) builds the Dashboard content. An Option Input allows the user= to select one of the Live Price Grids that exist in the partition. When th= e Dashboard is refreshed, a result matrix displays the LPG Items, one row p= er item, with SKU and lastUpdateDate.
The user can select one or multiple rows, and click on the =E2=80=9CCalc= PGI=E2=80=9D button. When the user clicks the button, we run a different l= ogic (action), which reads the list of the selected SKUs (i.e. the LPG Item= s) and triggers the calculation of each of them.
After about one minute, to allow time for the backend processing, if you= refresh the dashboard, you=E2=80=99ll see that the lastUpdateDate of the s= elected rows have changes, proving that the calculation has been done.
The =E2=80=9Caction=E2=80=9D logic can do anything we allow in the Groov= y Sandbox. Here we just recalculate the LPG items. But it could as easily c= reate a new Live Price Grid or Price List with the selected SKUs.
The Dashboard logic contains the following elements:
api.f= indPriceGrids(null, null)
def l= abels =3D api.getElement("pg_list")*.label.sort() api.option("Pick an LPG", labels)
api.b= ooleanUserEntry("Activate Embedded")
api.b= ooleanUserEntry("Activate Select")
def l= abel =3D api.getElement("input_pg_label") if (label =3D=3D null || api.syntaxCheck) return api.getElement("pg_list").find { label.equals(it.label) }
def p= g =3D api.getElement("pg") if (pg =3D=3D null || api.syntaxCheck) return def fields =3D ["sku", "activePrice", "submitDate", "lastUpdateDate"] def sortField =3D "sku" def filter =3D Filter.equal("priceGridId", pg.id) api.find("PGI", 0, 200, sortField, /* fields, */ filter)
def p= g =3D api.getElement("pg") if (pg =3D=3D null || api.syntaxCheck) return def matrix =3D api.newMatrix([ "sku", "activePrice", "lastUpdateDate", "download", "action" ]) matrix.setTitle(pg.label) matrix.setEnableClientFilter(true) matrix.setColumnFormat("lastUpdateDate", FieldFormatType.DATETIME) matrix.setPreferenceName("UltimateResultMatrix_uuid42") matrix.addColumnTranslation("sku", [en: "sku (click leads to Master Data)"]= ) api.getElement("pg_items").each { pgi -> def row =3D [:] row.sku =3D matrix.linkCell(pgi.sku, AppPages.MD_PRODUCTS_PAGE, pgi.sku) row.activePrice =3D pgi.activePrice row.lastUpdateDate =3D pgi.lastUpdateDate row.download =3D createDownloadLink(matrix, pg, pgi) row.action =3D createCalcPgiAction(matrix, pg, pgi) matrix.addRow(row) } if (api.getElement("input_activate_click")) { addClickEvent(matrix) } if (api.getElement("input_activate_select")) { addRowSelectionBackEndAction(matrix, pg) } return matrix // helper methods (they make the above code more readable) def createDownloadLink(def matrix, def pg, def pgi) { matrix.downloadButton("Download (whole PG)", "/pricegridmanager.fetchpdf/" + pg.id, null /*payload*/) } def createCalcPgiAction(def matrix, def pg, def pgi) { matrix.backEndAction("Recalculate (this item)", "/pricegridmanager.update/" + pg.id, api.toJson([data:[typedId: pgi.typedId]]), "success", "failure") } def addClickEvent(def matrix) { matrix .onRowSelection() .triggerEvent(api.dashboardWideEvent("myEvent")) .withColValueAsEventDataAttr("sku", "sku_attribute") } def addRowSelectionBackEndAction(def matrix, def pg) { matrix .rowSelectionBackEndAction("SKUs") .withLogicName("SC_UltimateMatrix_calc") .withColumns("sku") .addFormulaInput("PG_label", pg.label) .addFormulaInput("PG_id", pg.id) .withButtonLabel("Calc PGI") .withButtonTooltip("(Re)Calculate the selected Price Grid Items (SKUs= )") .withSuccessMessage("Success") .withFailureMessage("Sorry") }
if (!= api.getElement("input_activate_click")) return api.dashboard("JJ_embedded_event_chart") =09// Show the dashboard embedded ... =09.showEmbedded() =09=09=09 =09// ... and reevaluate it on "myEvent" =09// Note: "dashboardWideEvent()" fce makes the event local =09// to the containing dashboard instance =09.andRecalculateOn(api.dashboardWideEvent("myEvent")) =09=09=09 =09// Pull the "customerId" attribute out of the event payload and expose i= t =09// as the "Customer Id" input to the embedded dashboard =09.withEventDataAttr("sku_attribute").asParam("SKU") =09//.withEventDataAttr("bandBy").asParam("CustomerClass")
The action logic contains the following elements:
def p= g_id =3D api.decimalUserEntry('PG_id') // test value if (pg_id =3D=3D null) { pg_id =3D 5 // "Fourth Live Price Grid" } pg_id as Long
def m= atrix =3D api.inputMatrix("SKUs", "sku") // Front End payload validation if (!api.syntaxCheck) { validate(matrix) // throws exception if invalid - this validation is tota= lly optional, feel free to drop or tailor to your own needs } // test value if (matrix =3D=3D null) { matrix =3D [[sku: "MB-0007"]] } matrix*.sku def validate(def matrix) { if (matrix =3D=3D null) { exception(matrix, "is missing or null") } if (matrix.size() =3D=3D 0) { exception(matrix, "should not be empty") } if (! (matrix instanceof List) || ! (matrix[0] instanceof Map)) { exception(matrix, "should be an Array of Maps") } if (matrix[0].keySet() =3D=3D ["sku"] as Set) { // that's expected for backend action } else if (matrix[0].keySet() =3D=3D ["sku", "selected"] as Set) { // that's expected for UI InputMatrix } else { exception(matrix, "should have only 'sku' values") } if (matrix*.sku.find {!it instanceof String}) { exception(matrix, "should have'sku' values of type String") } } def exception(def matrix, def msg) { api.throwException("'SKUs' InputMatrix " + msg + " - " + api.toJson(matri= x)) }
def p= g_id =3D api.getElement("input_pgid") def sku_list =3D api.getElement("input_skus") api.triggerPriceGridCalculation(pg_id, [skusToRecalc: sku_list]) return null