Creating your first Field component
7 Tasks
30 mins
Scenario
Sweet Life stakeholders are happy with the new Pega self-service portal, which enables customers to raise incident tickets without having to call the help desk. This has significantly reduced calls to the customer service teams. After this success, the Sweet Life stakeholders have asked the Sweet Life Pega Center of Excellence (COE) to start the process of integrating these self-service journeys into the corporate website.
There is a strategy to align the Tell Us More - Customer Portal to the Sweet Life corporate branding and design system. As a first step, the business stakeholders have requested that the final Review screen, seen by the customer when raising a new Incident through the self-service portal, align with the corporate design pattern for confirming question responses at the end of a data capture journey before submitting the Incident case. The additional requirements are that a button (displayed as a link) should be added to each section of the Review screen that, when clicked, takes the user back to any specific steps in the Screen Flow where they can make needed changes. The Pega COE Lead System Architect (LSA) has reviewed and approved this stakeholder request, and the creation of a Constellation DX component is needed to fulfill this requirement.
The LSA has reviewed the available components listed on the Constellation Design System site to see which presentation components to use in your Constellation DX component. The LSA also performed necessary research on the ConstellationJS API to identify the correct API to use for programmatically navigating a Multi-step Form.
The LSA requires the following properties of Button and Icon to be configurable by App Studio authors when using the NavigateToStep component:
text | Will create a Text node and append it to the Button children property. |
tooltip | Maps to the label property on the Button. Optional - defaults to text. |
disabled | Maps to the disabled property on Button. Optional - defaults to false. |
iconName | Maps to the name property on Icon. Optional. If added, it creates an Icon node and append it to the Button children. |
Now that the presentation components from the Constellation Design System have been identified, the LSA reviews the ConstellationJS engine API calls that will perform the navigation action when your Button is clicked. The LSA uses the Using PCore and PConnect Public APIs documentation and identifies a suitable API that is part of the ActionsAPI class, navigateToStep.
The navigateToStep ConstellationJS API has the following API signature:
stepID | The ID of the step to be navigated to. Use the value previous to go to the previous step. |
containerItemID | The ID of the container item |
The getContextName() function derives the containerItemID. Because the containerItemID is derived, it will not be part of the configuration of the NavigateToStep component properties exposed to App Studio authors.
The LSA has provided the following inputs so that development can begin:
- Constellation design system components to use for the presentation and the relevant properties to use
- ConstellationJS APIs to call and the parameters needed
- List of properties to expose to the App Studio authors
It is now time to create the NavigateToStep Constellation DX component.
The following table provides the credentials you need to complete the challenge:
Role | User name | Password |
---|---|---|
Application Developer | Author@SL | pega123! |
Detailed Tasks
1 Create your component
- Open Visual Studio Code, and then navigate to the sldxcomponents project folder that you created in Setting up your development environment.
- In Visual Studio Code, open a terminal and enter npm run create.
- Select 1 to select the Field option.
- Navigate to URL by using the Arrow keys on your keyboard, and then press Enter
- Enter the mandatory data:
- In the Component name field, enter NavigateToStep.
- For the Component label field, enter Navigate to step.
- Accept all the defaults for the remaining questions by pressing Enter on your keyboard.
- In your project, navigate to the Sl_DXComponents_NavigateToStep folder under the src folder.
- Review the generated example code that you will modify.
The following core files make up most components:config.json A JSON file that is used by the App Studio authoring experience to build the property pane used by authors to configure your component at design time. demo.stories.tsx An example Storybook story is provided to get you started. index.tsx The entry point for your component that contains your primary Constellation DX component code. mock.ts An example of mock data used by Storybook. PConnProps.d.ts A type definition file that provides standard types for the common Constellation DX component props. styles.ts Styled Components wrapper component example generated automatically. create-nonce.ts Webpack nonce is generated to comply with secure content security policies (CSPs).
2 Clean up the autogenerated files
- Delete the following files from your component folder using VS Code:
- event-utils.js
- suggestions-handler.ts
- text-url.jsx
- Open config.json, and then replace the contents with the following code:
{
"name": "Sl_DXExtensions_NavigateToStep",
"label": "Navigate to step",
"description": "Navigate to step",
"organization": "Sl",
"version": "1.0.0",
"library": "DXExtensions",
"allowedApplications": [],
"componentKey": "Sl_DXExtensions_NavigateToStep",
"type": "Field",
"subtype": "Text-URL",
"properties": [
{
"name": "label",
"label": "Field label",
"format": "TEXT",
"required": true
},
{
"label": "Conditions",
"format": "GROUP",
"properties": [
{
"name": "visibility",
"label": "Visibility",
"format": "VISIBILITY"
}
]
},
{
"label": "Advanced",
"format": "GROUP",
"collapsible": true,
"properties": [
{
"name": "testId",
"label": "Test ID",
"format": "TEXT",
"ignorePattern": "[^-_\\p{N}\\p{L}]",
"includeAnnotations": false
}
]
}
],
"defaultConfig": {
"label": "@L $this.label"
}
} - Save the file.
- Click the following link to see a description of the schema that you use later to add the properties for the NavigateToStep component: Component Definition - config.json.
- Open index.tsx, and then replace the contents with the following code:
import { withConfiguration } from '@pega/cosmos-react-core';
import type { PConnFieldProps } from './PConnProps';
import './create-nonce';
import StyledSlDxExtensionsNavigateToStepWrapper from './styles';
// interface for props
export interface SlDxExtensionsNavigateToStepProps extends PConnFieldProps {
// If any, enter additional props that only exist on TextInput here
}
function SlDxExtensionsNavigateToStep({
getPConnect,
text = 'Edit',
stepID,
tooltip = 'Navigate to step',
variant = 'link',
}: Readonly<SlDxExtensionsNavigateToStepProps>) {
const actions = getPConnect().getActionsApi();
return (
<StyledSlDxExtensionsNavigateToStepWrapper>
</StyledSlDxExtensionsNavigateToStepWrapper>
);
}
export default withConfiguration(SlDxExtensionsNavigateToStep); - Save the file, ignoring any typescript or linting errors/warnings for now.
You will return to this code in a later step. - Open demo.stories.tsx, and then replace the contents with the following code:
import type { Meta, StoryObj } from '@storybook/react';
import SlDxExtensionsNavigateToStep from './index';
import type { SlDxExtensionsNavigateToStepProps } from './index';
import { configProps } from './mock';
const meta: Meta = {
title: 'SL/SlDxExtensionsNavigateToStep',
component: SlDxExtensionsNavigateToStep,
parameters: {
controls: { expanded: true }
}
};
export default meta;
type Story = StoryObj<SlDxExtensionsNavigateToStepProps>;
export const Primary:Story = {
args: {
text: configProps.text,
variant: configProps.variant,
getPConnect: () => {
return { } as typeof PConnect;
}
}
};Note: If you are already familiar with Storybook, we have recently upgraded to version 7, which has deprecated the use of add-ons and knobs in favor of controls. This challenge uses the updated Story structure, compared to the Storybook version 6 examples provided with DX Component Builder. - Save the file.
- Ignore typescript errors for now.
Note: You have now cleaned up the autogenerated files and can begin creating the new component.
3 Build initial Storybook story and mocks
- Browse to the sldxcomponents project folder, and then open it with VS Code.
- Open the index.tsx file in Visual Studio Code located in the SL_DXComponents_NavigateToStep folder under the src folder to see what PCore and PConnect APIs need mocking.
- Add the following properties to the
SlDxExtensionsNavigateToStepProps
interface:export interface SlDxExtensionsNavigateToStepProps extends PConnFieldProps {
text: string;
stepID: string;
tooltip?: string;
variant?: 'link' | 'simple' | 'text';
compact?: boolean;
icon?: boolean;
iconName?:
| 'pencil'
| 'arrow-bend-left'
| 'arrow-bend-right'
| 'check'
| 'undo'
| 'plus';
}- Replace the function declaration and the destructuring props block with the following code:
function SlDxExtensionsNavigateToStep({
getPConnect,
text = 'Edit',
stepID,
tooltip = 'Navigate to step',
variant = 'link',
compact = false,
icon = false,
iconName = 'pencil',
disabled = false,
testId = 'NavigateToStep'
}: Readonly<SlDxExtensionsNavigateToStepProps>) { - Add the following code in the return function:
return (
<StyledSlDxExtensionsNavigateToStepWrapper>
This is the text: {text}
</StyledSlDxExtensionsNavigateToStepWrapper>
);- Open demo.stories.tsx, and then navigate to the
args
block towards the end of the file and replace it with the following code:
args: {
text: configProps.text,
variant: configProps.variant,
getPConnect: () => {
return {
getActionsApi: () => {}
} as typeof PConnect;
}
} - Open demo.stories.tsx, and then navigate to the
- Open mock.ts, and then replace the text with the following code:
export const configProps = {
tooltip: 'Change',
stepId: 'AssignmentSF1',
text: 'Change',
variant: 'link' as const,
icon: false,
iconName: 'plus'
}; - Save all the files that you edited.
- In the root of your project, in a terminal, enter npm run startStorybook.
You see the output in your terminal window, as shown in the following figure: - In your browser, open the http://localhost:6040/ and select the SlDxExtensionsNavigateToStep/Primary story.
- In the Controls section, change the text property value and observe the component text changing.
You now have a working Storybook story to enhance.
4 Enhance component with Constellation design system
- Open Visual Studio Code in your project sldxcomponents folder.
- Open index.tsx.
- Add the registerIcon function and the Button and Icon components to the import statement:
import {
Button,
Icon,
registerIcon,
withConfiguration
} from '@pega/cosmos-react-core'; - Copy and paste the following code under the import statement added in step 2 to use the
registerIcon
function for all of the icons you want to display at runtime:import * as pencil from '@pega/cosmos-react-core/lib/components/Icon/icons/pencil.icon';
import * as arrowBendLeft from '@pega/cosmos-react-core/lib/components/Icon/icons/arrow-bend-left.icon';
import * as arrowBendRight from '@pega/cosmos-react-core/lib/components/Icon/icons/arrow-bend-right.icon';
import * as check from '@pega/cosmos-react-core/lib/components/Icon/icons/check.icon';
import * as undo from '@pega/cosmos-react-core/lib/components/Icon/icons/undo.icon';
import * as plus from '@pega/cosmos-react-core/lib/components/Icon/icons/plus.icon'; - After the import statements, insert the following code:
registerIcon(pencil, arrowBendLeft, arrowBendRight, check, undo, plus);
- Add the Button component to the return statement and map the Constellation DX component props to the Button properties by copying the following code and pasting the following code, overwriting the existing code in the return statement:
<StyledSlDxExtensionsNavigateToStepWrapper>
<Button
data-testid={testId}
name={stepID}
label={tooltip || text}
compact={compact}
disabled={disabled}
variant={variant}
icon={icon}
>
{text}
</Button>
</StyledSlDxExtensionsNavigateToStepWrapper>Your index.tsx should look like the following code:
import { Button, Icon, registerIcon, withConfiguration } from '@pega/cosmos-react-core';
import * as pencil from '@pega/cosmos-react-core/lib/components/Icon/icons/pencil.icon';
import * as arrowBendLeft from '@pega/cosmos-react-core/lib/components/Icon/icons/arrow-bend-left.icon';
import * as arrowBendRight from '@pega/cosmos-react-core/lib/components/Icon/icons/arrow-bend-right.icon';
import * as check from '@pega/cosmos-react-core/lib/components/Icon/icons/check.icon';
import * as undo from '@pega/cosmos-react-core/lib/components/Icon/icons/undo.icon';
import * as plus from '@pega/cosmos-react-core/lib/components/Icon/icons/plus.icon';
import type { PConnFieldProps } from './PConnProps';
import './create-nonce';
import StyledSlDxExtensionsNavigateToStepWrapper from './styles';
registerIcon(pencil, arrowBendLeft, arrowBendRight, check, undo, plus);
// interface for props
export interface SlDxExtensionsNavigateToStepProps extends PConnFieldProps {
text: string;
stepID: string;
tooltip?: string;
variant?: 'link' | 'simple' | 'text';
compact?: boolean;
icon?: boolean;
iconName?: 'pencil' | 'arrow-bend-left' | 'arrow-bend-right' | 'check' | 'undo' | 'plus';
}
function SlDxExtensionsNavigateToStep({
getPConnect,
text = 'Edit',
stepID,
tooltip = 'Navigate to step',
variant = 'link',
compact = false,
icon = false,
iconName = 'pencil',
disabled = false,
testId = 'NavigateToStep'
}: Readonly<SlDxExtensionsNavigateToStepProps>) {
const actions = getPConnect().getActionsApi();
return (
<StyledSlDxExtensionsNavigateToStepWrapper>
<Button
data-testid={testId}
name={stepID}
label={tooltip || text}
compact={compact}
disabled={disabled}
variant={variant}
icon={icon}
>
{text}
</Button>
</StyledSlDxExtensionsNavigateToStepWrapper>
);
}
export default withConfiguration(SlDxExtensionsNavigateToStep); - Save index.tsx, and then refresh the Storybook tab in your browser.
When you hover over the link, the story is updated with a clickable link and a tooltip.
The updated Story is displayed in Storybook, as shown in the following figure: - To add the Icon and conditional display logic that depends on the prop values, paste the following into the Button component, replacing the {text} value:
<StyledSlDxExtensionsNavigateToStepWrapper>
<Button
data-testid={testId}
name={stepID}
label={tooltip || text}
compact={compact}
disabled={disabled}
variant={variant}
icon={icon}
>
{iconName && <Icon name={iconName} />}
{!icon ? text : undefined}
</Button>
</StyledSlDxExtensionsNavigateToStepWrapper> - Update demo.stories.tsx, and then add the following additional configProps properties:
args: {
text: configProps.text,
variant: configProps.variant,
tooltip: configProps.tooltip,
stepID: configProps.stepId,
icon: configProps.icon,
iconName: configProps.iconName as SlDxExtensionsNavigateToStepProps['iconName'],
getPConnect: () => {
return {
getActionsApi: () => {}
} as typeof PConnect;
}
} - Save the files.
Storybook rebuilds any stories automatically. On the Controls tab, you can now modify the different prop values, to see how they change the component display, as shown in the following figure:
5 Connect your component to the PCore and PConnect APIs
- Open index.tsx in an editor.
- Add the onClick handler to the Button component with the following code:
<StyledSlDxExtensionsNavigateToStepWrapper>
<Button
data-testid={testId}
name={stepID}
label={tooltip || text}
compact={compact}
disabled={disabled}
variant={variant}
icon={icon}
onClick={() => actions.navigateToStep(stepID, getPConnect().getContextName())}
>
{iconName && <Icon name={iconName} />}
{!icon ? text : undefined}
</Button>
</StyledSlDxExtensionsNavigateToStepWrapper> - Save the file.
- Open demo.stories.tsx, and then replace the args with the following code:
args: {
text: configProps.text,
tooltip: configProps.tooltip,
stepID: configProps.stepId,
variant: configProps.variant,
icon: configProps.icon,
iconName: configProps.iconName as SlDxExtensionsNavigateToStepProps['iconName'],
getPConnect: () => {
return {
getActionsApi: () => {
return {
navigateToStep: (stepID, containerItemID) => {
if(stepID==='ERROR') {
return Promise.reject(new Error('Error navigating to step'));
}
return Promise.resolve(console.log(`Navigating to stepID: ${stepID} with containerItemID: ${containerItemID}`));
}
}
},
getContextName: () => 'containerItemID',
} as typeof PConnect;
}
}Note: This step ensures that the Storybook story properly mocks the navigateToStep PConnect API.
6 Update your component definition file (config.json)
- Open Visual Studio Code, and then browse to the SL_DXExtensions_NavigateToStep folder under the src directory.
- Edit the config.json file, and then replace its contents with the following code:
{
"name": "Sl_DXExtensions_NavigateToStep",
"label": "Navigate to step",
"description": "Navigate to step",
"organization": "Sl",
"version": "1.0.0",
"library": "DXExtensions",
"allowedApplications": [],
"componentKey": "Sl_DXExtensions_NavigateToStep",
"type": "Field",
"subtype": "Text-URL",
"properties": [
{
"name": "label",
"label": "Label",
"format": "TEXT",
"required": true
},
{
"name": "text",
"label": "Text to be displayed",
"format": "TEXT",
"required": true
},
{
"name": "stepID",
"label": "The Task ID of the navigation step",
"format": "TEXT",
"required": true
},
{
"name": "tooltip",
"label": "Tooltip text",
"format": "TEXT"
},
{
"name": "variant",
"label": "Display as",
"format": "SELECT",
"defaultValue": "link",
"source": [
{
"key": "link",
"value": "link"
},
{
"key": "simple",
"value": "simple"
},
{
"key": "text",
"value": "text"
}
]
},
{
"name": "compact",
"label": "Use compact mode",
"format": "BOOLEAN"
},
{
"name": "icon",
"label": "Display only icon",
"format": "BOOLEAN"
},
{
"label": "Icon settings",
"format": "GROUP",
"properties": [
{
"name": "iconName",
"label": "Icon name",
"format": "SELECT",
"defaultValue": "pencil",
"source": [
{
"key": "pencil",
"value": "pencil"
},
{
"key": "arrow-bend-left",
"value": "arrow-bend-left"
},
{
"key": "arrow-bend-right",
"value": "arrow-bend-right"
},
{
"key": "check",
"value": "check"
},
{
"key": "undo",
"value": "undo"
},
{
"key": "plus",
"value": "plus"
}
]
}
]
},
{
"label": "Conditions",
"format": "GROUP",
"properties": [
{
"name": "visibility",
"label": "Visibility",
"format": "VISIBILITY"
}
]
},
{
"label": "Advanced",
"format": "GROUP",
"collapsible": true,
"properties": [
{
"name": "testId",
"label": "Test ID",
"format": "TEXT",
"ignorePattern": "[^-_\\p{N}\\p{L}]",
"includeAnnotations": false
}
]
}
],
"defaultConfig": {}
}Tip: The previous configuration shows some simple TEXT formats and more advanced configuration options, such as SELECT and GROUP. The different sample components that you can create by using DX Component Builder provide great examples of config.json component definitions. For a full description about the schema, see Component definition (config.json).
7 Publish your component and test in App Studio
- Open up Visual Studio Code and browse to the root of the sldxcomponents project folder.
- Open a terminal.
- Run the following command: npm run authenticate.
- Enter the following credentials:
- In the user name line, enter Author@SL.
- In the password line, enter pega123!.
- Close the browser tab opened by DX Component Builder
- In the terminal, run the following command: npm run publish.
- Select the Sl_DXComponents_NavigateToStep component, and then press the Enter key.
- Accept the default values for the Enter ruleset name and Enter ruleset version questions.
- In the Pega Platform instance for the challenge, enter the following credentials:
- In the User name field, enter Author@SL.
- In the Password field, enter pega123!.
- Open the Incident Case Type, as shown in the following figure:
- In the Create Stage, click the Review Step:
- In the upper-right corner, click Configure View to open the View Authoring workspace:
- In the Fields section, click .
- Enter or search for NavigateToStepURL in the search field, and then click
- In the row for the NavigateToStepURL field, click the icon.
- In the Display as list, select the NavigateToStep component.
- Configure the field details:
- In the Field label field, enter NavigateToStep.
- In the Text to be displayed field, enter Change.
- In the Task ID of the navigation step field, enter AssignmentSF4.
- In the Tooltip text field, enter Change.
- In the Icon name list, select any option.
For example, select pencil.
- Click Save, and then click Submit.
- Click Save to save the Case Type.
- Click Preview to launch the Portal preview.
- Create a new Incident Case by clicking Create > Incident, and then enter any valid values in each Step.
- Click Next to open the Review View.
- In the Review View, click Change.
The Screen Flow jumps to the Contact Info View.
Available in the following mission:
Want to help us improve this content?