Skip to main content

Version: 23.10

Custom Cards

The customCards property defines the set of cards displayed on the Details screen in the Custom Cards section. The custom card config can be added as a mapping from the global config, or inline as an object into the properties array. The example below demonstrates both approaches.

The following custom card types are supported.

  • list: Display key/value pairs in a grid container.
  • listStacked: Display key/value pairs in a scrollable container.
  • listExtended: A list custom card with color-coded values.
  • table: Display a Txn JSON array in a table layout.
  • tableExtended: A table custom card with additional features.

The appearance of custom cards changes depending upon the content contained within.

  • If the content in a custom card exceeds the card's width, a horizontal scrollbar appears allowing all content to be accessed.
  • If there is no data to display for a custom card, the card is hidden.

When multiple custom cards are specified in the customCards property, the top-level cards are shown as tabs. Each custom card tab can have one or more custom cards within it.

Attributes

All custom card types support several properties that allow fields and cards to be shown or hidden based on empty values or permissions. All properties are optional unless otherwise indicated.

AttributeDescription
hideEmptyboolean
Whether to show or hide empty fields in a card.
To learn more, see Mappings > Hide Empty.
permissionsGlobalPermissions
Show or hide cards based on the current user role or group.
To learn more, see Permissions.
rulesGlobalRules
Rules provide additional control to show or hide custom cards.
To learn more, see Visibility Rules.
checkStatusGlobalCheckStatus
Use checkStatus when there is a negative result that needs attention.
If checkStatus is true, an indicator (red disc) appears on the custom card tab that contains the negative result.

For a full list of supported attributes, see the configuration reference.

Example config

The following example is a partial space config showing a custom card config.

import { ConfigCurrentSpace } from '@transact-open-ux/workspaces/dist/types';

export const applicantsConfig = ({ date }: any): ConfigCurrentSpace => ({
...
customCards: [
{
label: 'Applicants',
properties: ['$applicants'],
},
{
label: 'Review Checklist',
properties: ['$reviewChecklist'],
hideEmpty: true,
rules: [
{
dataIndex: 'userLoginName',
value: currentUser,
},
],
},
{
label: 'Communications',
properties: ['$sentEmails'],
hideEmpty: true,
},
{
label: 'Validations',
properties: ['$applicantValidations'],
},
{
label: 'Documents Checklist',
properties: ['$docsList'],
},
],
...
});

export default applicantsConfig;

Custom card types

List

The list type is used to display key/value pairs in a grid container. It can be configured to pull data from different Txn properties or use a dataSource config to pull data from a single Txn JSON property.

List Stacked

The listStacked type is used to display key/value pairs in a scrollable horizontal container.

  $customCard: {
label: 'Review Checklist',
type: 'listStacked',
icon: 'BallotOutlined',
hideEmpty: true,
permissions: {
type: 'role',
value: ['Processing Staff'],
},
properties: [
{
label: 'Personal Details',
dataIndex: 'properties["PersonalDetails"]',
type: 'text',
},
{
label: 'Background Checks',
dataIndex: 'properties["BackgroundChecks"]',
type: 'text',
filter: {
type: 'input',
},
},
{
label: 'Attachments',
dataIndex: 'properties["Attachments"]',
type: 'text',
},
{
label: "Remarks",
dataIndex: 'properties["Remarks"]',
type: 'text',
},
],
},

List Extended

The listExtended type, in conjunction with the statusColors config, displays color-coded key/value pairs in a grid container.

info

statusColors is used to map the integrations values to predefined colors.

$customCard: {
label: 'Background Checks',
type: 'listExtended',
hideEmpty: false,
permissions: {
type: 'role',
value: ['Helpdesk Staff'],
},
statusColors: {
Black: [
'HARDFAIL',
],
LightGreen: [
'LOW',
],
Green: [
'VERIFIED',
'PASSED',
'ACCEPT',
'APPROVE',
'TRUSTED',
'PASS',
],
Red: [
'FAILED',
'DECLINE',
'HIGH',
'FAIL',
],
Blue: [
'REVIEW',
'NEUTRAL',
'UNVERIFIED',
],
Orange: [
'INSUFFICIENT',
'MEDIUM',
],
},
properties: [
{
label: 'FIS Chexsystems',
properties: [
{
label: 'IDA',
dataIndex: 'integrations.[0].items[0].value',
type: 'text',
},
{
label: 'IDV',
dataIndex: 'integrations.[0].items[1].value',
type: 'text',
link: {
dataIndex: 'integrations.[0].items[1].link',
type: 'html',
},
},
{
label: 'OFAC',
dataIndex: 'integrations.[0].items[2].value',
type: 'text',
},
{
label: 'Qualfile',
dataIndex: 'integrations.[0].items[3].value',
type: 'text',
link: {
dataIndex: 'integrations.[0].items[3].link',
type: 'html',
},
},
],
},
{
label: 'Threat Metrix',
properties: [
{
label: 'DECISION',
dataIndex: 'integrations.[1].items[0].value',
type: 'text',
link: {
dataIndex: 'integrations.[1].items[0].link',
type: 'json',
},
},
{
label: 'RISK RATING',
dataIndex: 'integrations.[1].items[1].value',
type: 'text',
},
{
label: 'SCORE',
dataIndex: 'integrations.[1].items[2].value',
type: 'number',
},
],
},
{
label: 'TIN Check',
properties: [
{
label: 'TIN Verification',
dataIndex: 'integrations.[2].items[0].value',
type: 'text',
link: {
dataIndex: 'integrations.[2].items[0].link',
type: 'xml',
},
},
],
},
],
},

Table

The table type is used to display a JSON array Txn property in a table. It is designed to display tabular data stored in a Txn JSON property. Using the dataSource, the table component will iterate (foreach) over the array and display the data in multiple rows.

Table Extended

The tableExtended type is used to display a JSON array Txn property in a selectable table container with sub-sections that can be of type list, listExtended or table. tableExtended uses a structure similar to that used by the table type but differs from table in that it allows selection on the table. When a row is clicked, all data is passed to the sections config.

info

This custom card type was introduced to support multi-applicants but can be used with any data source as long as the structure is correct.

The example below shows a reference data structure for a multi-applicant/multi-product scenario.

JM Txn property
[
{
"profile": {
"name": "Tom Riddle",
"email": "[email protected]",
"ssn": "###-##-2033",
"phone": "(123) 303-4044",
"dob": "1918-01-11",
"address": "2/1a Rialto Ln, Manly NSW 2095"
},
"integrations": [
{
"name": "Fis Check Systems",
"items": [
{
"name": "IDA",
"value": "FAILED"
},
{
"name": "IDV",
"value": "VERIFIED",
"link": "<html> Sample HTML </html>"
},
{
"name": "OFAC",
"value": "PASSED"
},
{
"name": "QUALFILE",
"value": "ACCEPT",
"link": "<html> Sample HTML </html>"
}
]
},
{
"name": "Threat metrix",
"items": [
{
"name": "Decision",
"value": "APPROVE",
"link": "{\"jsonStructure\":\"value\"}"
},
{
"name": "Risk Rating",
"value": "TRUSTED"
},
{
"name": "Score",
"value": "-10"
}
]
},
{
"name": "TIN Check",
"items": [
{
"name": "Tin Verification",
"value": "PASS",
"link": "<?xml version=\"1.0\"?>\r\n<soap:Envelope xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\">\r\n <soap:Body></soap:Body>\r\n</soap:Envelope>"
}
]
}
],
"products": {
"Trust": "Primary",
"Standard Checking": "Primary"
},
"checkStatus": true
}
]

Given a Txn property called ApplicationDetails with the above structure, we can configure a custom card as follows.

  $customCard: {
label: 'Applicants',
icon: 'PermIdentityTwoTone',
type: 'tableExtended',
dataSource: 'properties["ApplicationDetails"]',
permissions: {
type: 'group',
value: ['Fraud Review'],
},
properties: [
{
label: 'Status',
dataIndex: 'checkStatus',
type: 'alert',
},
{
label: 'Name',
dataIndex: 'profile.name',
type: 'text',
},
{
label: 'Email',
dataIndex: 'profile.email',
type: 'text',
},
{
label: 'Trust',
dataIndex: 'products["Trust"]',
type: 'text',
},
{
label: 'Super Saver',
dataIndex: 'products["Super Saver"]',
type: 'text',
},
{
label: 'Standard Checking',
dataIndex: 'products["Standard Checking"]',
type: 'text',
},
],
sections: [
{
label: 'Personal Info',
type: 'list',
properties: [
{
label: 'Full Name',
dataIndex: 'profile.name',
type: 'text',
fullWidth: true,
},
{
label: 'Address',
dataIndex: 'profile.address',
type: 'text',
fullWidth: true,
},
{
label: 'SSN',
dataIndex: 'profile.ssn',
type: 'text',
},
{
label: 'Email',
dataIndex: 'profile.email',
type: 'text',
},
{
label: 'Phone #',
dataIndex: 'profile.phone',
type: 'text',
},
{
label: 'Date of Birth',
dataIndex: 'profile.dob',
type: 'text',
},
],
},
{
label: 'Background Checks',
type: 'listExtended',
statusColors: {
Black: [
'HARDFAIL',
],
LightGreen: [
'LOW',
],
Green: [
'VERIFIED',
'PASSED',
'ACCEPT',
'APPROVE',
'TRUSTED',
'PASS',
],
Red: [
'FAILED',
'DECLINE',
'HIGH',
'FAIL',
],
Blue: [
'REVIEW',
'NEUTRAL',
'UNVERIFIED',
],
Orange: [
'INSUFFICIENT',
'MEDIUM',
],
},
properties: [
{
label: 'FIS Chexsystems',
properties: [
{
label: 'IDA',
dataIndex: 'integrations.[0].items[0].value',
type: 'text',
},
{
label: 'IDV',
dataIndex: 'integrations.[0].items[1].value',
type: 'text',
link: {
dataIndex: 'integrations.[0].items[1].link',
type: 'html',
},
},
{
label: 'OFAC',
dataIndex: 'integrations.[0].items[2].value',
type: 'text',
},
{
label: 'Qualfile',
dataIndex: 'integrations.[0].items[3].value',
type: 'text',
link: {
dataIndex: 'integrations.[0].items[3].link',
type: 'html',
},
},
],
},
{
label: 'Threat Metrix',
properties: [
{
label: 'DECISION',
dataIndex: 'integrations.[1].items[0].value',
type: 'text',
link: {
dataIndex: 'integrations.[1].items[0].link',
type: 'json',
},
},
{
label: 'RISK RATING',
dataIndex: 'integrations.[1].items[1].value',
type: 'text',
},
{
label: 'SCORE',
dataIndex: 'integrations.[1].items[2].value',
type: 'number',
},
],
},
{
label: 'TIN Check',
properties: [
{
label: 'TIN Verification',
dataIndex: 'integrations.[2].items[0].value',
type: 'text',
link: {
dataIndex: 'integrations.[2].items[0].link',
type: 'xml',
},
},
],
},
],
},
],
},

Links allow the display of additional content, usually rendered within a modal window when a link button is clicked. Links are supported for the listExtended, table, and tableExtended custom card types. Each link has a type and a data value with additional optional attributes for some link types. The following link types are supported: pdf, html, text, xml, json, url, invoke, download.

PDF

The pdf link type renders a PDF document in a modal window. The PDF data is defined in the dataIndex attribute which needs to be a URL for a PDF file.

{
label: 'View PDF',
link: {
dataIndex: 'pdfContent',
type: 'pdf',
},
}

HTML

The html link type renders HTML content in a modal window. The HTML data is defined in the dataIndex attribute which can be either plain text or a base64-encoded string.

{
label: 'View report',
type: 'text',
link: {
dataIndex: 'htmlContent',
type: 'html',
encoding: 'base64',
},
}

Text

The text link type renders plain text in a modal window. The text data is defined in the dataIndex attribute as a plain text string.

{
label: 'View content',
type: 'text',
link: {
dataIndex: 'value',
type: 'text',
},
}

XML

The xml link type renders an XML document in a modal window. The XML data is defined by the dataIndex attribute which can be either plain text or a base64-encoded string.

{
label: 'View XML',
type: 'text',
link: {
dataIndex: 'xmlContent',
type: 'xml',
encoding: 'base64',
},
}

JSON

The json link type renders a JSON document in a modal window. The JSON data is defined in the dataIndex attribute which must be a base64-encoded string.

{
label: 'View JSON',
type: 'text',
link: {
dataIndex: 'jsonContent',
type: 'json',
encoding: 'base64',
},
}

URL

The url link type renders the contents of a URL in a modal window. The URL is defined in the dataIndex attribute as a plain text string.

info

The URL may have to be on the same domain as the application depending on the CORS policy setup in Journey Manager.

{
label: 'View URL',
type: 'text',
link: {
dataIndex: 'urlContent',
type: 'url',
},
}

Download

The download link type allows the contents of a specified URL to be downloaded. The source of the download data is defined in the dataIndex attribute as a URL which is downloaded when the link is clicked.

{
label: 'View',
type: 'text',
link: {
dataIndex: 'fileUrl',
type: 'download'
}
}

Invoke

The invoke link type invokes a Fluent Function when the link is clicked. You can change the icon displayed for an invoke link from the default icon. To learn how to configure an icon, see Icons.

The invoke link type is similar to the Invoke configuration, requiring you to define a serviceName, versionNumber and params. However, the invoke link type doesn't need to return an object on the fluent function. As long as it returns an HTTP 200 status code, the action will be deemed successful.

When used within a table custom card, the dataIndex value can be used to identify which row was clicked as long as they have a unique value.

note

In order to use invoke functions, the user must have the Invoke Fluent Functions permission.

{
label: 'Resend',
link: {
dataIndex: 'name',
type: 'invoke',
serviceName: 'DAO - Resend Email',
versionNumber: '0.1.0',
icon: 'mark_chat_read', // Icon can be changed here
},
},

Example

The following example showcases two different ways the customCards property can be configured. It can be done by using a global mapping string or by including the whole definition object without using any mappings.

Txn properties
{
"properties": {
"FundingAmount": "$25,000",
"FundingType": "ACH",
"SecondaryName": "[email protected]",
"SecondaryEmail": "MIchael Green",
"SecondarySSN": "311-333-1222",
"ThirdName": "[email protected]",
"ThirdEmail": "Daniel Green",
"ThirdSSN": "122-122-1222",
"Integrations": "[{ \"IsSuccess\": true, \"Data\": { \"ApplicationResult\": \"PROCEED\"}]",
"ThreatMetrixScore.PrimaryApplicant": "-55",
"ThreatMetrixScore.SecondaryApplicant": "69",
"ThreatMetrixDecision.PrimaryApplicant": "APPROVE",
"ThreatMetrixDecision.SecondaryApplicant": "HARDFAIL",
"ThreatMetrixRiskRating.PrimaryApplicant": "HIGH",
"ThreatMetrixRiskRating.SecondaryApplicant": "HIGH",
"FisIda.PrimaryApplicant.verifyStatus": "VERIFIED",
"FisIda.SecondaryApplicant.verifyStatus": "FAILED",
"FisIdv.PrimaryApplicant.idvVerifyStatus": "FAILED",
"FisIdv.SecondaryApplicant.idvVerifyStatus": "FAILED",
"FisIdv.PrimaryApplicant.ofacStatus": "PASSED",
"FisIdv.SecondaryApplicant.ofacStatus": "FAILED",
"FisQualiFile.PrimaryApplicant.accountAcceptanceTxt": "REVIEW",
"FisQualiFile.SecondaryApplicant.accountAcceptanceTxt": "APPROVE"
"Applicants": "[{\"type\":\"Primary\",\"extracts\":{\"PrimaryEmail\":\"[email protected]\",\"PrimaryName\":\"Matt Green\",\"PrimarySSN\":\"111-233-1234\"}}]",
"GenericContent": "[{\"type\": \"Identity verification\",\"pdfContent\": \"https://tm.workspaces.avoka-transact.com/workspaces/servlet/FormReceipt.pdf?submitKey=54cb2ad573303fedd0044cba2208223f\"},{\"type\": \"Driver licence\",\"pdfContent\": \"https://tm.workspaces.avoka-transact.com/workspaces/servlet/FormReceipt.pdf?submitKey=54cb2ad573303fedd0044cba2208223f\"}]",
"EmailList": "[{\"name\": \"AO402.1.AVOKA\",\"dateAttempted\": \"05/30/2018 14:55:01\",\"emailSent\": \"true\"}]"
}
}
src/configs/custom/global.ts
import { ConfigGlobal } from '@transact-open-ux/workspaces/dist/types';

export const globalConfig = ({ date }: any): ConfigGlobal => ({
...
mappings: {
$applicants: {
label: 'Applicants',
icon: 'PermIdentityTwoTone',
type: 'tableExtended',
dataSource: "properties['Applicants']",
properties: [
{
label: 'Name',
// dataIndex: 'profile.name',
dataIndex: 'extracts.PrimaryName',
type: 'text',
},
{
label: 'Email',
// dataIndex: 'profile.email',
dataIndex: 'extracts.PrimaryEmail',
type: 'text',
},
{
label: 'Trust',
dataIndex: "products['Trust']",
type: 'text',
},
{
label: 'Super Saver',
dataIndex: "products['Super Saver']",
type: 'text',
},
{
label: 'Standard Checking',
dataIndex: "products['Standard Checking']",
type: 'text',
},
],
sections: [
{
label: 'Personal Info',
type: 'list',
properties: [
{
label: 'Full Name',
dataIndex: 'extracts.PrimaryName',
type: 'text',
fullWidth: true,
},
{
label: 'Address',
dataIndex: 'profile.address',
type: 'text',
fullWidth: true,
},
{
label: 'SSN',
dataIndex: 'extracts.PrimarySSN',
type: 'text',
},
{
label: 'Email',
dataIndex: 'extracts.PrimaryEmail',
type: 'text',
},

{
label: 'Phone #',
dataIndex: 'profile.phone',
type: 'text',
},
{
label: 'Date of Birth',
dataIndex: 'extracts.dob',
type: 'date',
format: 'relative',
},
],
},

{
label: 'Background Checks',
type: 'listExtended',
statusColors: {
Black: ['HARDFAIL'],
LightGreen: ['LOW'],
Green: [
'VERIFIED',
'PASSED',
'ACCEPT',
'APPROVE',
'TRUSTED',
'PASS',
],
Red: ['FAILED', 'DECLINE', 'HIGH', 'FAIL'],
Blue: ['REVIEW', 'NEUTRAL', 'UNVERIFIED'],
Orange: ['INSUFFICIENT', 'MEDIUM'],
},
properties: [
{
label: 'FIS Chexsystems',
properties: [
{
label: 'IDA',
dataIndex: 'integrations.[0].items[0].value',
type: 'text',
},
{
label: 'IDV',
dataIndex: 'integrations.[0].items[1].value',
type: 'text',
link: {
dataIndex: 'integrations.[0].items[1].link',
type: 'html',
},
},
{
label: 'OFAC',
dataIndex: 'integrations.[0].items[2].value',
type: 'text',
},
{
label: 'Qualfile',
dataIndex: 'integrations.[0].items[3].value',
type: 'text',
link: {
dataIndex: 'integrations.[0].items[3].link',
type: 'html',
},
},
],
},
{
label: 'Threat Metrix',
properties: [
{
label: 'DECISION',
dataIndex: 'integrations.[1].items[0].value',
type: 'text',
link: {
dataIndex: 'integrations.[1].items[0].link',
type: 'json',
},
},
{
label: 'RISK RATING',
dataIndex: 'integrations.[1].items[1].value',
type: 'text',
},
{
label: 'SCORE',
dataIndex: 'integrations.[1].items[2].value',
type: 'number',
},
],
},
{
label: 'TIN Check',
properties: [
{
label: 'TIN Verification',
dataIndex: 'integrations.[2].items[0].value',
type: 'text',
link: {
dataIndex: 'integrations.[2].items[0].link',
type: 'xml',
},
},
],
},
],
},
],
},
$txnProperties: {
label: 'Properties',
icon: 'InfoTwoTone',
type: 'table',
dataSource: "txnProperties",
properties: [
{
label: 'Name',
dataIndex: 'name',
type: 'text',
},
{
label: 'Info',
dataIndex: 'short',
type: 'text',
},
{
label: 'View content',
type: 'text',
link: {
dataIndex: 'value',
type: 'html',
},
},
],
},
$txnFormDataMap: {
label: 'Form Data Extracts',
icon: 'InfoTwoTone',
type: 'table',
dataSource: 'txnFormDataMap',
properties: [
{
label: 'Name',
dataIndex: 'name',
type: 'text',
},
{
label: 'Info',
dataIndex: 'short',
type: 'text',
},
{
label: 'View content',
type: 'text',
link: {
dataIndex: 'value',
type: 'html',
},
},
],
},
$applicantValidations: {
label: 'Applicant validations',
icon: 'InfoTwoTone',
type: 'table',
dataSource: "properties['GenericContent']",
properties: [
{
label: 'Type',
dataIndex: 'type',
type: 'text',
},
{
label: 'View report',
type: 'text',
link: {
dataIndex: 'htmlContent',
type: 'html',
encoding: 'base64',
},
},
{
label: 'View JSON',
type: 'text',
link: {
dataIndex: 'jsonContent',
type: 'json',
encoding: 'base64',
},
},
{
label: 'View XML',
type: 'text',
link: {
dataIndex: 'xmlContent',
type: 'xml',
encoding: 'base64',
},
},
{
label: 'View PDF',
link: {
dataIndex: 'pdfContent',
type: 'pdf',
},
},
],
},
$reviewChecklist: {
label: 'Review Checklist',
type: 'listStacked',
icon: 'BallotOutlined',
properties: [
{
label: 'Personal Details',
dataIndex: ["properties['PersonalDetails']"],
type: 'text',
},
{
label: 'Background Checks',
dataIndex: ["properties['BackgroundChecks']"],
type: 'text',
filter: {
type: 'input',
},
},
{
label: 'Attachments',
dataIndex: ["properties['Attachments']"],
type: 'text',
},
{
label: 'Remarks',
dataIndex: ["properties['Remarks']"],
type: 'text',
},
],
},
},
...
});

export default globalConfig;
src/configs/custom/brokers.ts:
{
...
customCards: [
{
label: 'Applicants',
properties: ['$applicants', '$txnProperties'],
},
{
label: 'Properties',
properties: ['$txnProperties'],
},
{
label: 'Form Data Extracts',
properties: ['$txnFormDataMap'],
},
{
label: 'Application Validation',
properties: [
{
label: 'Review Checklist',
type: 'listStacked',
icon: 'BallotOutlined',
properties: [
{
label: 'Personal Details',
dataIndex: ["properties['PersonalDetails']"],
type: 'text',
},
{
label: 'Background Checks',
dataIndex: ["properties['BackgroundChecks']"],
type: 'text',
filter: {
type: 'input',
},
},
{
label: 'Attachments',
dataIndex: ["properties['Attachments']"],
type: 'text',
},
{
label: 'Remarks',
dataIndex: ["properties['Remarks']"],
type: 'text',
},
],
}
],
},
];
...
}