Migrate from Workspaces 19.11 to Workspaces 20.05
caution
While you can deploy the Workspaces 19.11 application in a TJM 20.05 instance, we don't recommend this mixed-release deployment. For more information, see Can I deploy the Workspaces 19.11 portal in a TJM 20.05, 20.11 or 21.05 environment?.
Prior to the 20.05 release, Workspaces was a fully integrated front-end and back-end system. In Workspaces 20.05, by using Open UX CLI to deploy the frontend as a Journey Manager Form, we were able to decouple the Workspaces API from the client-side application. This approach allows us to make the frontend more customizable, but also preserved the best parts of Workspaces 19.11 - easy to get started, configurable, i18n, and much more.
Now that the Workspaces frontend can be deployed as a form, multiple versioned Workspaces Clients can be deployed within the same Journey Manager Server.
Beyond that, Workspaces 20.05 introduces many new features: Space Configurations were moved into the code and converted to TypeScript, making it easy for developers to get instant feedback from their IDE, reuse and extend configs, use local fixtures, integrate into CI/CD pipelines and even run their own Workspaces Client without the need of a Journey Manager Server.
While our main focus will still be supporting Architects with feature requests development, from this point foward, we are also planning to work with them to create, manage and share reusable templates for different kinds of solutions. To assist in setting up the new development environment, we have created a new Form Development guide. Once the default template has been setup, migration from 19.11 to 20.05 requires a few minor changes. We recommend you make these changes in the order shown below.
Spaces
Space configurations are no longer part of Journey Manager properties. Instead, they need to be moved into the codebase under src/configs
and converted into TypeScript by running yarn run prettier
on the root folder.
note
Workspaces 20.05 introduces some new design elements, including a change to the navigation rail and space icons. The nav rail is now slimmer, allowing more screen width for space content. A consequence of this decision is that space icons no longer include labels. If you have spaces using the same icon that you previously differentiated with the icon label, we recommend using different icons for your spaces instead.
Use the following steps to copy the old JSON properties.
- Copy the
src/configs/default
folder, and rename it tosrc/configs/custom
. - Depending on how many space configs you need, update
src/configs/custom/index.ts
to import those only. - Update
src/configs/custom/global.ts
withGlobal.json
properties. Note that the TypeScript version contains a function that returns an object.Global.json
data can replace the returning object. By runningyarn run prettier
on the root folder, all your JSON properties will get updated to TypeScript properties. Now, do the same with the rest of the spaces. - You should now have the same number of files as your JM space properties plus an index file, which groups all the space configs that Workspaces is going to use. There will be some TypeScript errors indicating which properties need to be updated.
Let's say you have Global
and Process
JSON properties in JM. If you want to move them within the new Workspaces 20.05, copy their content into two new files, src/configs/custom/global.ts
and src/configs/custom/process.ts
, and create another new file called src/configs/custom/index.ts
, that exports them as default.
src/configs/custom/global.ts
Copy the
Global
JSON into this file, then removespaces
andcurrentSpace
from here.src/configs/custom/global.tsexport const globalConfig = ({ date, currentUser }: any): Config => ({
...
<Global.json>
...
});src/configs/custom/process.ts
Move
label
,icon
andpermissions
for each spaces property into the corresponding space. For example:src/configs/custom/process.tsexport const processConfig = ({ date, currentUser }: any): Config => ({
...
<Process.json>
...
label: 'Process',
icon: 'BallotOutlined',
permissions: {
type: 'role',
value: ['Processing Staff', 'Work Spaces Staff'],
},
...
});Note that
title
andvalue
can be removed from the current spaces definition.src/configs/custom/Index.ts
src/configs/custom/Index.tsimport global from './global';
import process from './process';
const spaces = [process];
export default {
global,
spaces,
};
note
Don't forget to change the config
path from ./config/development
to ./config/custom
on src/index.jsx
.
import 'dayjs/locale/en';
import App from '@transact-open-ux/workspaces/dist/App';
import configs from './configs/custom';
import messages from './locales/en';
const root = document.getElementById('root');
export default async function init() {
if (process.env.NODE_ENV === 'development') {
const { default: fixtures } = await import('./fixtures/development');
const { default: makeServer } = await import('@transact-open-ux/workspaces/dist/Server');
// start server
makeServer({
fixtures,
});
}
// start only the cleint if production
App(root, configs, messages, 'en');
}
init();
Once you've copied the content, you will see a few errors in your IDE. That's typescript reporting wrong code formatting for the configs. In order to fix that, run the following command on the root dir.
yarn run prettier
Now you can continue to fix the pending errors reported by TypeScript.
Locales
locales
and currentLocale
configs are no longer needed, and should be removed from global.ts
. The new Workspaces 20.05 locales have been moved into the codebase.
Only one locale at a time is supported, which can still be configured in index.ts
. Import the required dayjs language pack and add the corresponding messages file into the root App
.
import 'dayjs/locale/en';
import App from '@transact-open-ux/workspaces/dist/App';
import configs from './configs/development';
import messages from './locales/en';
const root = document.getElementById('root');
export default async function init() {
if (process.env.NODE_ENV === 'development') {
const { default: fixtures } = await import('./fixtures/development');
const { default: makeServer } = await import('@transact-open-ux/workspaces/dist/Server');
// start server
makeServer({
fixtures,
});
}
// start only the cleint if production
App(root, configs, messages, 'en');
}
init();
Filters
The picker
filter type has been removed and split into datepicker
and daterangepicker
to allow single date selection. If you don't need single date selection, you can replace picker
occurences with daterangepicker
.
For example, let's say previously we had an $appAge
field rendering a DateRangePicker
component, but we wanted single date selection.
{
...
"mappings": {
...
"$appAge": {
"label": "App age",
"icon": "EventOutlined",
"dataIndex": "job.timeCreated",
"type": "date",
"format": "duration",
"sorter": true,
"filter": {
"type": "picker",
"options": {
"minDate": "{{ date('1 month ago') }}",
"maxDate": "{{ date('now') }}"
}
}
},
...
},
...
}
By changing the filter type to datepicker
, the component rendered is now a single DatePicker
.
{
...
mappings: {
...
$appAge: {
label: 'App age',
icon: 'EventOutlined',
dataIndex: 'job.timeCreated',
type: 'date',
format: 'duration',
sorter: true,
filter: {
type: 'datepicker',
options: {
minDate: date('1 month ago'),
maxDate: date('now'),
},
},
},
},
...
}
Expressions
With the introduction of TypeScript, {{ currentUser }}
and {{ date( ... ) }}
expressions are converted to function parameters, so you no longer need to specify them as strings wrapped in brackets "{{ ... }}"
.
Here's an example showing how expressions were specified in Workspaces 19.11.
{
...
"views": [
...
{
"label": "Assigned to me",
"properties": [
"$appId",
"$primaryName",
"$product",
"$appAge",
"$dateOfBirth",
"$currentQueue",
"$currentTask",
"$taskCreated",
"$assigned",
"$formLastModified"
],
"filterBy": {
"$assigned": ["{{ currentUser }}"]
},
"sortOrder": "desc",
"sortBy": "$appAge"
},
...
],
"globalFilters": {
"GroupName": {
"label": "Queues",
"options": ["Error Review", "Fraud Review", "Manual Review"],
"value": "All",
},
"DateCreated": {
"label": "Created Date",
"value": ["{{ date('4 weeks ago') }}", "{{ date('now') }}"],
}
},
...
}
The refactored version for Workspaces 20.11 is shown below.
export const processConfig = ({ date, currentUser }: any): Config => ({
...
viees: [
...
{
label: 'Assigned to me',
properties: [
'$appId',
'$primaryName',
'$product',
'$appAge',
'$dateOfBirth',
'$currentQueue',
'$currentTask',
'$taskCreated',
'$assigned',
'$formLastModified',
],
filterBy: {
$assigned: [currentUser],
},
sortOrder: 'desc',
sortBy: '$appAge',
},
...
],
globalFilters: {
GroupName: {
label: 'Queues',
options: ['Error Review', 'Fraud Review', 'Manual Review'],
value: 'All',
},
DateCreated: {
label: 'Created Date',
value: [date('4 weeks ago'), date('now')],
},
},
...
});
Actions
The "actions"
JSON property has been split into jobActions
and txnActions
Typescript properties. To understand how this works, check out the example below or see Actions.
Say you had the following actions configured for your space.
{
...
"actions": {
"Claim": {
"label": "Claim"
},
"Release": {
"label": "Release"
},
"Decision": {
"label": "Decision"
},
"Receipt": {
"label": "Receipt",
"permissions": {
"type": "group",
"value": ["Manual Review"]
}
},
},
...
}
After refactoring and converting to TypeScript, the actions configuration looks like this.
{
...
txnActions: {
Claim: {
label: 'Claim',
},
Release: {
label: 'Release',
},
Decision: {
label: 'Decision',
},
},
jobActions: {
Receipt: {
label: 'Receipt',
permissions: {
type: 'group',
value: ['Manual Review'],
},
},
},
...
}
Logo
Many customers apply corporate branding to their Workspaces portal, including a logo.
To migrate your logo, simply copy your logo image file into the public/static
folder in your Workspaces Client form project.