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
: Alist
custom card with color-coded values.table
: Display aTxn
JSON array in a table layout.tableExtended
: Atable
custom card with additional features.iframe
: Display an iframe in a custom card embedded in the Details screen.
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.
Attribute | Description |
---|---|
hideEmpty | boolean Whether to show or hide empty fields in a card. To learn more, see Mappings > Hide Empty. |
permissions | GlobalPermissions Show or hide cards based on the current user role or group .To learn more, see Permissions. |
rules | GlobalRules Rules provide additional control to show or hide custom cards. To learn more, see Visibility Rules. |
checkStatus | GlobalCheckStatus 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.
tip
The list
type has a copy-to-clipboard feature, available via a Copy Text button that appears on hover. Click Copy Text to copy the entire value inside the box to the clipboard regardless of whether the entire value is visible. A toast message appears, indicating whether the copy was successful.
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.
[
{
"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
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
, download
, img
, invoke
.
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.
tip
By default, the url
link type displays a button to open the content in a new browser window. You can hide this button using the modalPopoutDisabled: true
config option in the global config.
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'
}
}
Img
The img
link type allows an image to be shown in the modal. To display a base64-encoded image, specify the optional property encoding: 'base64'
.
{
label: 'View',
type: 'text',
link: {
dataIndex: 'imgSource',
type: 'img',
// encoding: 'base64',
},
}
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.
{
"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\"}]"
}
}
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',
},
],
}
],
},
];
...
}