Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Tables display information in a way that makes it easy for end - users to visually scan the data. Data series that cannot be aggregated are especially suited for tables. An example could can be a list of prices.

Simple Table

simple
Code Block
languagegroovy
themeMidnight
titlehttps://github.com/pricefx/example-configuration/tree/main/pricefxSrc/CalculationLogic/Dashboard_Chart_Examples/elements/SimpleTable.groovy
linenumbersfalse
ResultMatrix simpleTable(
        List<Map> data,
        Map<String, String> labels
) {
    def table = api.newMatrix()

    table.withColumns(labels.keySet())
    table.withRows(data)

    // Add labels to the columns
    labels.each { name, label ->
        table.withColumnTranslation(name, ['': label])
    }

    return table
}
Use as such
Code Block
languagegroovy
themeMidnight
titlehttps://github.com/pricefx/example-configuration/tree/main/pricefxSrc/CalculationLogic/Dashboard_Chart_Examples/elements/SimpleTable.groovy
linenumbersfalse
ResultMatrix data = [
        [
                customerId: 'CD-00001',
                label     : 'Mega Evil Space Cooperation',
                totalSales: 12.8e3,
        ], [
                customerId: 'CD-00001',
                label     : 'Mom & Pop Store Inc.',
                totalSales: 66.0e3,
        ], [
                customerId: 'CD-00001',
                label     : 'Academy Toddlers',
                totalSales: 32.2e3,
        ]
]

def labels = [
        // Do not include the customerId
        label     : 'Customer Name',
        totalSales: 'Total Sales (€)',
]

return simpleTable(data, labels)

Cell Formatting

You can specify exactly how the cells in a column should be formatted with the FielFormatType enumeration.

field formatting
Code Block
languagegroovy
themeMidnight
titlehttps://github.com/pricefx/example-configuration/tree/main/pricefxSrc/CalculationLogic/Dashboard_Chart_Examples/elements/TableWithFormatting.groovy
linenumbersfalse
ResultMatrix tableWithFormatting(
        List<Map> data,
        Map<String, String> labels,
        Map<String, FieldFormatType> formatting
) {
    def table = api.newMatrix()

    table.withColumns(labels.keySet())
    table.withRows(data)
    table.withColumnFormats(formatting)

    // Add labels to the columns
    labels.each { name, label ->
        table.withColumnTranslation(name, ['': label])
    }

    return table
}
Filter

Filtering &

Sort

Sorting

A table header can allow the end - user to filter and sort rows according to their field values. Both these features must we be switched on by method calls.

filter and sort
Code Block
languagegroovy
themeMidnight
titlehttps://github.com/pricefx/example-configuration/tree/main/pricefxSrc/CalculationLogic/Dashboard_Chart_Examples/elements/TableWithSortAndSearch.groovy
linenumbersfalse
ResultMatrix simpleTableWithSortAndSearch(
        List<Map> data,
        Map<String, String> labels
) {
    def table = api.newMatrix()

    table.withColumns(labels.keySet())
    table.withRows(data)

    table.withDisableSorting(false)
    table.withEnableClientFilter(true)

    // Add labels to the columns
    labels.each { name, label ->
        table.withColumnTranslation(name, ['': label])
    }

    return table
}

...

If you want to link to a page within the Pricefx application, it is best to use ResultMatrix.linkCell(). This will ensure that the link that the end - user clicks on points to the proper a valid page within the same frontend application. Otherwise, you will get a problem there will be issues if the url URL changes. For example, if the customer migrates from the Classic frontend application to Unity, all links would still be pointing to Classic!.

Tip
For the a full list of pages that can be targeted with ResultMatrix.linkCell(), see the reference.
Code Block
languagegroovy
themeMidnight
titlehttps://github.com/pricefx/example-configuration/tree/main/pricefxSrc/CalculationLogic/Dashboard_Chart_Examples/elements/TableWithInternallLinks.groovy
linenumbersfalse
ResultMatrix tableWithCustomerDetail(
        List<Map> data,
        Map<String, String> labels
) {
    def table = api.newMatrix()

    def allLabels = labels + [openCustomerDetail: 'Customer Detail']

    table.withColumns(allLabels.keySet())

    def rows = data.collect { dataRow ->
        // Add a field to the data set
        dataRow + [
                openCustomerDetail: customerDetailLink(table, dataRow.customerId)
        ]
    }

    table.withRows(rows)

    // Add labels to the columns
    allLabels.each { name, label ->
        table.withColumnTranslation(name, ['': label])
    }

    return table
}

String customerDetailLink(ResultMatrix table, String customerId){
    // If customerId is null, the customer master table screen would open
    if(customerId == null){
        throw new Exception('customerId must be provided')
    }
    return table.linkCell('Customer Detail', 'customersPage', customerId)
}

Cell Styling

Table cells can be styled, for example, to draw attention to certain rows.

styled cells
Code Block
languagegroovy
themeMidnight
titlehttps://github.com/pricefx/example-configuration/tree/main/pricefxSrc/CalculationLogic/Dashboard_Chart_Examples/elements/TableQuoteStatus.groovy
linenumbersfalse
ResultMatrix quotesTable(
        String title,
        List<Quote> quotes
){

    def table = api.newMatrix()
    table.withTitle(title)

    def labels = [
            // typedId should be hidden, because it is only there to be supplied to the table action handler
            name       : 'Name',
            label      : 'Label',
            quoteStatus: 'Status',
            viewQuote  : 'View',
    ]

    def rows = quotes.collect { quote ->
        [
                typedId    : quote.typedId,
                name       : quote.uniqueName,
                label      : quote.label,
                quoteStatus: getQuoteStatusCell(table, quote.quoteStatus),
                viewQuote  : link("#/qc/quotes/${quote.typedId}", 'Open')
        ]
    }

    def columns = labels.keySet() as List<String>
    table.withColumns(columns)
    table.withRows(rows)
    table.withDisableSorting(false)
    table.withEnableClientFilter(true)

    // Add labels, in the backend referred to as "translations"
    labels.each { name, label ->
        table.withColumnTranslation(name, ['': label])
    }

    return table
}

def getQuoteStatusCell(ResultMatrix table, String quoteStatus) {
    def colors = libs.Library_CSS.Color
    switch (quoteStatus) {
        case 'DEAL':
            return table.styledCell(quoteStatus, colors.CONTRAST_TEXT, colors.SUCCESS)
        case 'OFFER':
            return table.styledCell(quoteStatus, colors.CONTRAST_TEXT, colors.WARNING)
        case 'LOST':
            return table.styledCell(quoteStatus, colors.CONTRAST_TEXT, colors.ERROR)
        default:
            return table.styledCell(quoteStatus)
    }
}
Use as such"
Code Block
languagegroovy
themeMidnight
linenumbersfalse
def quotes = quoteUtils.getByYear(year)

return quotesTable("Quotes $year", quotes)

Row Actions

End -user users can be allowed to perform actions on the rows. These actions are strictly limited in that they must correspond to a single REST API call.

row action success
Code Block
languagegroovy
themeMidnight
titlehttps://github.com/pricefx/example-configuration/tree/main/pricefxSrc/CalculationLogic/Dashboard_Chart_Examples/elements/TableRowActions.groovy
linenumbersfalse
ResultMatrix quotesTable(
        String title,
        List<Map> quotes
){

    def table = api.newMatrix()
    table.withTitle(title)

    def labels = [
            // typedId should be hidden, because it is only there to be supplied to the matrix action handler
            name       : 'Name',
            label      : 'Label',
            viewQuote  : 'View',
            actions  : 'Actions',
    ]

    def rows = quotes.collect { quote ->
        [
                name       : quote.uniqueName,
                label      : quote.label,
                viewQuote  : link("#/qc/quotes/${quote.typedId}", 'View'),
                actions  : table.cells('Actions', submitAction(table, quote)),
        ]
    }

    def columns = labels.keySet() as List<String>
    table.withColumns(columns)
    table.withRows(rows)
    table.withDisableSorting(false)
    table.withEnableClientFilter(true)

    // Add labels, in the backend referred to as "translations"
    labels.each { name, label ->
        table.withColumnTranslation(name, ['': label])
    }

    return table
}

ResultMatrix.ResultMatrixBackEndCell submitAction(ResultMatrix table, Map quote){
    return table.backEndAction(
            'Submit',
            "/clicmanager.runjob/${quote.typedId}/submit", // Must have leading forward slash
            null,
            "Quote ${quote.uniqueName} was successfully submitted",
            "Failed to submit ${quote.uniqueName}"
    )
}

String link(String href, String children) {
    return """<a href="$href">${children}</a>"""
}

Use as such:

Code Block
languagegroovy
themeMidnight
titlehttps://github.com/pricefx/example-configuration/tree/main/pricefxSrc/CalculationLogic/Dashboard_Chart_Examples/elements/TableRowActions.groovy
linenumbersfalse
def quotes = quoteUtils.getDraftsByYear(year)

return quotesTable("Quote Drafts $year (Row Action)", quotes)

Row Selection Actions

End - users can be allowed to perform actions on selected rows. When one or more rows are selected, a set of action buttons are made available (on at the bottom of the table). When one of these buttons are is clicked, a callback logic is invoked by the frontend application. This logic must have the default logic nature. An alert will pop - up on the screen, indicating whether the execution was successful.

selected rows action success
Code Block
languagegroovy
themeMidnight
titlehttps://github.com/pricefx/example-configuration/tree/main/pricefxSrc/CalculationLogic/Dashboard_Chart_Examples/elements/TableRowSelectionActions.groovy
linenumbersfalse
ResultMatrix quotesTable(
        String title,
        List<Quote> quotes
){

    def table = api.newMatrix()
    table.withTitle(title)

    def labels = [
            // typedId should be hidden, because it is only there to be supplied to the matrix action handler
            name       : 'Name',
            label      : 'Label',
            viewQuote  : 'View',
    ]

    def rows = quotes.collect { quote ->
        [
                typedId    : quote.typedId,
                name       : quote.uniqueName,
                label      : quote.label,
                viewQuote  : link("#/qc/quotes/${quote.typedId}", 'View')
        ]
    }

    def columns = labels.keySet() as List<String>
    table.withColumns(columns)
    table.withRows(rows)
    table.withDisableSorting(false)
    table.withEnableClientFilter(true)

    table.rowSelectionBackEndAction('quotes')
            .withLogicName('Handler_SubmitQuotes')
            .withColumns('typedId')
            .withButtonLabel('Submit')
            .withSuccessMessage('Successfully submitted all selected quotes.')
            .withFailureMessage('Failed to submit all selected rows.')

    // Add labels, in the backend referred to as "translations"
    labels.each { name, label ->
        table.withColumnTranslation(name, ['': label])
    }

    return table
}

String link(String href, String children) {
    return """<a href="$href">${children}</a>"""
}

Set up a bound partition with the name 'thisPartition' that point points to the same partition you’re you are using, and add the callback logic:.

Code Block
languagegroovy
themeMidnight
titlehttps://github.com/pricefx/example-configuration/tree/main/pricefxSrc/CalculationLogic/Handler_SubmitQuotes/elements/Handler.groovy
linenumbersfalse
// Expects the input to have a property 'quotes'
// that is a list of maps with one property 'typedId'
def typedIds = input.quotes.collect { it.typedId as String }

typedIds.each { typedId ->
    submitQuote(typedId)
}

return

void submitQuote(String typedId){
    api.boundCall(
            'thisPartition',
            "clicmanager.runjob/$typedId/submit",
            '',
    )
}