Operational Dashboard - Changes & Fixes
This page covers the changes and fixes provided to Operational Dashboard for IPF Release 2025.4.0
NPM Package Versions
Remove the following packages
The following packages have been removed and must be uninstalled:
npm uninstall @iconsolutions/audit @iconsolutions/htm @iconsolutions/ods @iconsolutions/ods-api
Install/Update the following packages
Update your package.json with the following npm package versions for IPF 2025.4.0. Note that @iconsolutions/ipf-operational-dashboard and @iconsolutions/ipf-operations are new packages that replace the packages removed above:
"@iconsolutions/common": "2025.4.5",
"@iconsolutions/htm-api": "2025.4.0",
"@iconsolutions/htm-bulk-api": "2025.4.0",
"@iconsolutions/ipf-operational-dashboard": "2025.4.5",
"@iconsolutions/ipf-operations": "2025.4.5",
"@iconsolutions/ods-gui-api": "2025.4.0",
"@iconsolutions/processing-settings": "2025.4.5",
"@iconsolutions/processing-settings-api": "2025.4.0",
Breaking Changes
Module Restructure
Remove all existing IPF routes excluding processing-settings, making sure to keep any of your own defined routes:
e.g:(PAY-14560)
Old Configuration
import { Route } from '@angular/router';
import {
AppHomeComponent,
HomeComponent,
LoginComponent,
ProcessingEntityGuard,
RoleGuard
} from '@iconsolutions/common';
export const appRoutes: Route[] = [
{ path: '', redirectTo: 'app', pathMatch: 'full' },
{ path: 'login', component: LoginComponent },
{
path: 'app',
canActivate: [ProcessingEntityGuard],
component: AppHomeComponent
},
{
path: 'app/:processingEntityId',
canActivate: [ProcessingEntityGuard],
children: [
{
path: 'home',
component: HomeComponent
},
{
path: 'ods',
data: { roles: ['ROLE_PAYMENT'] },
canActivate: [RoleGuard],
loadChildren: () => import('@iconsolutions/ods').then((m) => m.OdsModule)
},
{
path: 'version-info',
loadChildren: () => import('@iconsolutions/version-info').then((m) => m.VersionInfoModule)
},
{
path: 'cluster-health',
loadChildren: () => import('@iconsolutions/cluster-health').then((m) => m.ClusterHealthModule)
},
{
path: 'processing-settings',
loadChildren: () => import('@iconsolutions/processing-settings').then((m) => m.ProcessingSettingsModule)
},
{
path: 'audit',
canActivate: [RoleGuard],
data: { roles: ['ROLE_AUDIT'] },
loadChildren: () => import('@iconsolutions/audit').then((m) => m.AuditModule)
},
{
path: 'metrics',
canActivate: [RoleGuard],
data: { roles: ['ROLE_METRICS'] },
loadChildren: () => import('@iconsolutions/metrics').then((m) => m.MetricsModule)
},
{
path: 'permissions',
loadComponent: () => import('@iconsolutions/permissions').then((m) => m.PermissionsComponent)
},
{
path: 'htm',
loadChildren: () => import('@iconsolutions/htm').then((m) => m.HtmModule)
}
]
}
];
New Configuration (from this release)
import { Route } from '@angular/router';
import { ProcessingEntityGuard } from '@iconsolutions/common';
export const appRoutes: Route[] = [
{
path: 'app/:processingEntityId',
canActivate: [ProcessingEntityGuard],
children: [
{
path: 'processing-settings',
loadChildren: () => import('@iconsolutions/processing-settings').then((m) => m.ProcessingSettingsModule)
}
]
}
];
Add IpfOperationalDashboardModule and IpfOperationsModule to your main module imports (most likely app.module.ts).
Remove the following npm dependencies:
"@iconsolutions/audit": "189.3.3",
"@iconsolutions/cluster-health": "189.3.3",
"@iconsolutions/htm": "189.3.3",
"@iconsolutions/metrics": "189.3.3",
"@iconsolutions/ods": "189.3.3",
"@iconsolutions/permissions": "189.3.3",
"@iconsolutions/version-info": "189.3.3",
Then install the following npm dependencies:
npm i @iconsolutions/ipf-operational-dashboard
npm i @iconsolutions/ipf-operations
ODS Config Consolidation Per Journey Type
This release introduces a breaking change to the ODS module configuration structure. The configuration has been refactored to organize properties per journey type, providing better flexibility and maintainability.(PAY-14230)
Summary of Changes
-
Properties are now organized per journey type: The following properties are now structured as maps keyed by journey type:
-
Search forms (
search-form) -
Table columns (
table-columns) -
Global statuses (
global-statuses) -
Date types (
date-types) -
Amount types (
amount-types) -
Alternative identifiers (
alternative-identifiers) -
Transaction types (
transaction-types) -
Details defaults (
details-defaults)
-
-
Removed default fallbacks: The
defaultlists of amount types and date types have been removed. Each journey type must now define all required properties explicitly. There are no default fallback values.
Migration Steps
Complete Example Configuration
Here’s a complete example showing the new updated structure:
ipf.business-operations.payment-search {
# Top-level property
ods-page-results {
size = 1000
}
# Top-level shared property
system-event-names = [
"ActionInvoked",
"ActionRetriesExhausted",
"ActionTimeout",
# ... (full list)
]
journeys {
payment {
alternative-identifiers = [
{
searchBy: "CLIENT_REQUEST_ID",
displayName: "Client Request ID"
}
]
transaction-types = ["Credit", "Debit"]
details-defaults {
showGraphs = true
flows {
opened = "latest"
sort = "asc"
}
events {
opened = "all"
sort = "asc"
}
}
search-form {
searchType: "payment"
formSections: [
# ... form sections
]
}
table-columns = [
# ... column definitions
]
global-statuses = [
{
name: "PENDING",
category: "PENDING"
},
# ... more statuses
]
date-types = [
"CREATED_AT",
"INSTRUCTION_RECEIVED_AT",
"EXECUTION_STARTED_AT",
"SETTLEMENT_COMPLETED_AT",
"ACCEPTANCE_DATE_TIME",
"INTERBANK_SETTLEMENT_DATE",
"REQUESTED_EXECUTION_DATE"
]
amount-types = [
"INSTRUCTED",
"TRANSACTION",
"CREDIT",
"DEBIT",
"CONVERTED"
]
}
# Repeat for recall, bulk, batch...
}
}
Step 1: Keep shared properties at the top level
Keep ods-page-results and system-event-names at the top of your configuration, outside of the journeys object. These are shared properties that apply to all journey types.
ipf.business-operations.payment-search {
ods-page-results {
size = 1000
}
system-event-names = [
"ActionInvoked",
"ActionRetriesExhausted",
# ... (full list)
]
journeys {
# Journey-specific configuration goes here
}
}
Step 2: Create the journeys object structure
Add a journeys object to your configuration, and create an object for each journey type (e.g., payment, recall, bulk, batch) inside the journeys object.
ipf.business-operations.payment-search {
journeys {
payment {
# Journey-specific configuration goes here
}
recall {
# Journey-specific configuration goes here
}
bulk {
# Journey-specific configuration goes here
}
batch {
# Journey-specific configuration goes here
}
}
}
Step 3: Remove any default lists you may have for amount types or date types, and add these lists for each of the journey types.
Step 4: Add Journey-Specific Properties to Each Journey Type
Add the following properties to each journey type:
Search Form
search-form {
searchType: "payment"
formSections: [
{
sectionName: "Basic Search"
fields: [
{
fieldName: "paymentId"
displayName: "Payment ID"
fieldType: "text"
}
]
}
]
}
Table Columns
table-columns = [
{
columnName: "paymentId"
displayName: "Payment ID"
sortable: true
},
{
columnName: "status"
displayName: "Status"
sortable: true
}
]
Global Statuses
global-statuses = [
{
name: "PENDING"
category: "PENDING"
},
{
name: "COMPLETED"
category: "COMPLETED"
},
{
name: "FAILED"
category: "FAILED"
}
]
Date Types
date-types = [
"CREATED_AT",
"INSTRUCTION_RECEIVED_AT",
"EXECUTION_STARTED_AT",
"SETTLEMENT_COMPLETED_AT",
"ACCEPTANCE_DATE_TIME",
"INTERBANK_SETTLEMENT_DATE",
"REQUESTED_EXECUTION_DATE"
]
Alternative Identifiers
alternative-identifiers = [
{
searchBy: "CLIENT_REQUEST_ID",
displayName: "Client Request ID"
}
]
Details Defaults
details-defaults {
showGraphs = true
flows {
opened = "latest"
sort = "asc"
}
events {
opened = "all"
sort = "asc"
}
}
So your configuration for a journey type should look like this:
ipf.business-operations.payment-search {
ods-page-results {
size = 1000
}
system-event-names = [
"ActionInvoked",
"ActionRetriesExhausted",
"ActionTimeout",
# ... (full list)
]
journeys {
payment {
alternative-identifiers = [
{
searchBy: "CLIENT_REQUEST_ID",
displayName: "Client Request ID"
}
]
transaction-types = ["Credit", "Debit"]
details-defaults {
showGraphs = true
flows {
opened = "latest"
sort = "asc"
}
events {
opened = "all"
sort = "asc"
}
}
search-form {
searchType: "payment"
formSections: [
# ... form sections
]
}
table-columns = [
# ... column definitions
]
global-statuses = [
{
name: "PENDING",
category: "PENDING"
},
# ... more statuses
]
date-types = [
"CREATED_AT",
"INSTRUCTION_RECEIVED_AT",
"EXECUTION_STARTED_AT",
"SETTLEMENT_COMPLETED_AT",
"ACCEPTANCE_DATE_TIME",
"INTERBANK_SETTLEMENT_DATE",
"REQUESTED_EXECUTION_DATE"
]
amount-types = [
"INSTRUCTED",
"TRANSACTION",
"CREDIT",
"DEBIT",
"CONVERTED"
]
}
# Repeat for recall, bulk, batch...
}
}
Custom Journey Types
The new structure fully supports custom journey types. To add a custom journey type add a new entry to the journeys map with all required properties:
ipf.business-operations.payment-search {
ods-page-results {
size = 1000
}
system-event-names = [...]
journeys {
payment { ... }
recall { ... }
bulk { ... }
batch { ... }
# Custom journey type
sepa-instant {
alternative-identifiers = [...]
transaction-types = [...]
details-defaults {...}
search-form {...}
table-columns = [...]
global-statuses = [...]
date-types = [...]
amount-types = [...]
}
}
}
Table Column Configuration
If you have any configuration for payment-columns, recall-columns, bulk-columns or batch-columns then you need to update your configuration.
You will need to set the journey configurations to be part of table-columns within each journey type, change columnName to name and provide a type.
For full configuration details see IPF Operational Dashboard ODS module.
Old Configuration: An array of objects at the top level:
payment-columns = [
{
columnName: "createdAt"
},
{
columnName: "transactionType"
},
{
columnName: "debtor"
},
{
columnName: "amount"
}
]
New Configuration: Table columns are now defined within each journey type with required name and type properties:
journeys {
payment {
table-columns = [
{
name: "createdAt",
type: "DATETIME"
},
{
name: "transactionType",
type: "STRING"
},
{
name: "debtor",
type: "STRING",
paths: ["debtorName", "debtorAccount", "debtorBic", "debtorAgentBic"]
},
{
name: "amount",
type: "PRE_DEFINED"
}
]
}
recall {
table-columns = [
{
name: "createdAt",
type: "DATETIME"
},
{
name: "agentDetails",
type: "PRE_DEFINED"
},
{
name: "reasonCode",
type: "STRING"
}
]
}
newJourney {
table-columns = [
{
name: "createdAt",
type: "DATETIME"
},
{
name: "unitOfWorkdId",
type: "STRING"
}
]
}
}
All column objects must provide a name and type. paths is optional; if not provided, the name is used by default.
Additionally, if there is no value provided for the table columns for a journey, then the following default will be used:
{
name: "unitOfWorkdId",
type: "STRING"
}
Name
The name value should be a unique name that will be correlated with the translation sheet to provide a column header for the frontend. It is also used as a fallback value if paths is not defined for that column.
Paths
The paths attribute accepts an array of strings, where the value correlates to the path within the object that is expected. If the path isn’t provided, the name will be used as default.
e.g. for an object like below:
{
"createdAt": "01/01/2025",
"field1": "value1",
"field2": "value2",
"object1": {
"field3": "value3"
}
}
The paths property:
paths: ["createdAt"]
Will get the value ["01/01/2025"]
And the paths property:
paths: ["field1", "object1.field3"]
Will get the value ["value1", "value3"]. Each of the string values will be separated by a line break in the table.
Type
There are six types you can choose from:
STRING |
A standard text value |
NUMBER |
A standard number value |
CURRENCY |
A value that will be formatted to a currency value |
DATE |
A value that will be formatted to date and show date only |
DATETIME |
A value that will be formatted to date and include time |
PRE_DEFINED |
An inbuilt column definition that will handle more complicated columns (see definitions) |
For the PRE_DEFINED columns, you can use these by providing both the type and the appropriate name.
Name |
Description |
Notes |
amount |
This will display transactionAmount, instructedAmount, convertedTransactionAmount or originalInterbankSettlementAmount, returnedInterbankSettlementAmount, convertedTransactionAmount depending on the journey type |
It will also display an appropriate tooltip |
bankingAccount |
This will display debitAccount and creditAccount with prefixes |
|
totalInterbankSettlementAmount |
This will display totalInterbankSettlementAmount with totalInterbankSettlementAmountCurrency for the currency |
|
agentDetails |
This will display instructingAgent and instructedAgent |
It will also display with a prefix of 'Instructing' and 'Instructed' |
Global Status Configuration
We have also made some changes to how the global status configuration is defined. Global statuses are now defined within each journey type in the journeys object. This means that you can add custom global statuses for each of the different journey types independently.
Before: A single array at the top level:
global-statuses = [
{
name: "Pending",
category: "PENDING"
},
{
name: "Accepted",
category: "ACCEPTED"
},
{
name: "Completed",
category: "ACCEPTED"
},
{
name: "Rejected",
category: "REJECTED"
},
{
name: "Manual Action Required",
category: "MANUAL_ACTION_REQUIRED"
},
{
name: "Scheduled",
category: "SCHEDULED"
},
{
name: "Cancelled",
category: "CANCELLED"
}
]
After: Global statuses are defined within each journey type:
journeys {
payment {
global-statuses = [
{
name: "Pending",
category: "PENDING"
},
{
name: "Accepted",
category: "ACCEPTED"
},
{
name: "Completed",
category: "ACCEPTED"
}
]
# ... other payment configuration
}
recall {
global-statuses = [
{
name: "Pending",
category: "PENDING"
},
{
name: "Accepted",
category: "ACCEPTED"
},
{
name: "Scheduled",
category: "SCHEDULED"
},
{
name: "Cancelled",
category: "CANCELLED"
}
]
# ... other recall configuration
}
bulk {
global-statuses = [
{
name: "Rejected",
category: "REJECTED"
},
{
name: "Manual Action Required",
category: "MANUAL_ACTION_REQUIRED"
},
{
name: "Scheduled",
category: "SCHEDULED"
},
{
name: "Cancelled",
category: "CANCELLED"
}
]
# ... other bulk configuration
}
batch {
global-statuses = [
{
name: "Pending",
category: "PENDING"
},
{
name: "Accepted",
category: "ACCEPTED"
},
{
name: "Completed",
category: "ACCEPTED"
},
{
name: "Rejected",
category: "REJECTED"
},
{
name: "Cancelled",
category: "CANCELLED"
}
]
# ... other batch configuration
}
}