Skip to main content
Version: 20.05

Migration from 19.11 to 20.05

note

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, 21.05 or 21.11 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 npm 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/defaultfolder, and rename it to src/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 with Global.json properties. Note that the TypeScript version contains a function that returns an object. Global.json data can replace the returning object. By running npm 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 remove spaces and currentSpace from here.

    src/configs/custom/global.ts
    export const globalConfig = ({ date, currentUser }: any): Config => ({
    ...
    <Global.json>
    ...
    });
  • src/configs/custom/process.ts

    Move label, icon and permissions for each spaces property into the corresponding space. For example:

    src/configs/custom/process.ts
    export const processConfig = ({ date, currentUser }: any): Config => ({
    ...
    <Process.json>
    ...
    label: 'Process',
    icon: 'BallotOutlined',
    permissions: {
    type: 'role',
    value: ['Processing Staff', 'Work Spaces Staff'],
    },
    ...
    });

    Note that title and value can be removed from the current spaces definition.

  • src/configs/custom/Index.ts

    src/configs/custom/Index.ts
    import 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.

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.

npm 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'],
},
},
},
...
}

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.