Skip to content

Commit

Permalink
Merge pull request #48 from iglep/constellation-lighthouse-lab
Browse files Browse the repository at this point in the history
Constellation Lab Lighthouse - Widget - Case Launcher
  • Loading branch information
ricmars authored Apr 5, 2024
2 parents 10d1128 + a295e76 commit 402d869
Show file tree
Hide file tree
Showing 6 changed files with 218 additions and 0 deletions.
14 changes: 14 additions & 0 deletions src/components/Pega_Extensions_CaseLauncher/Docs.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Meta, Primary, Controls, Story } from '@storybook/blocks';
import * as DemoStories from './demo.stories';

<Meta of={DemoStories} />

# Overview

The Case Launcher widget allows you to create and open a single defined case by clicking the widget button. The widget consists of a card, a header, a case description, and a button with an editable label. You can define which case to associate with the Launcher by selecting the case type in the select control (classFilter).

<Primary />

## Props

<Controls />
58 changes: 58 additions & 0 deletions src/components/Pega_Extensions_CaseLauncher/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
{
"name": "Pega_Extensions_CaseLauncher",
"label": "Case Launcher",
"description": "Widget will render a heading, text and a button to start a case",
"organization": "Pega",
"version": "1.0.0",
"library": "Extensions",
"allowedApplications": [],
"componentKey": "Pega_Extensions_CaseLauncher",
"type": "Widget",
"subtype": "PAGE",
"properties": [
{
"name": "heading",
"label": "Header",
"format": "TEXT",
"defaultValue": "Please insert here a personalized header",
"required": true
},
{
"name": "description",
"label": "Description",
"format": "TEXT",
"defaultValue": "Please insert here a personalized short description.",
"required": true
},
{
"name": "classFilter",
"label": "Case type (triggered by primary button)",
"format": "SELECT",
"placeholder": "Choose option...",
"source": {
"name": "D_pyQuickCreate",
"displayProp": "pyLabel",
"valueProp": "pyClassName"
},
"required": true
},
{
"name": "labelPrimaryButton",
"label": "Primary button text",
"format": "TEXT",
"required": true
},
{
"label": "Conditions",
"format": "GROUP",
"properties": [
{
"name": "visibility",
"label": "Visibility",
"format": "VISIBILITY"
}
]
}
],
"defaultConfig": {}
}
57 changes: 57 additions & 0 deletions src/components/Pega_Extensions_CaseLauncher/demo.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import type { StoryObj } from '@storybook/react';

import PegaExtensionsCaseLauncher from './index';

export default {
title: 'Widgets/Case Launcher',
component: PegaExtensionsCaseLauncher,
argTypes: {
classFilter: {
options: ['Work-'],
control: { control: 'select' }
},
getPConnect: {
table: {
disable: true
}
}
}
};

const setPCore = () => {
(window as any).PCore = {
getEnvironmentInfo: () => {
return {};
}
};
};

type Story = StoryObj<typeof PegaExtensionsCaseLauncher>;

export const Default: Story = {
render: args => {
setPCore();
const props = {
...args,
getPConnect: () => {
return {
getActionsApi: () => {
return {
createWork: (className: string) => {
// eslint-disable-next-line no-alert
alert(`Create case type with className: ${className}`);
}
};
}
};
}
};
return <PegaExtensionsCaseLauncher {...props} />;
},
args: {
heading: 'Start Case',
description: 'Short description about the case that you will be able to start',
classFilter: 'Work-',
labelPrimaryButton: 'Start a case'
}
};
18 changes: 18 additions & 0 deletions src/components/Pega_Extensions_CaseLauncher/demo.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { render, screen, fireEvent } from '@testing-library/react';
import { composeStories } from '@storybook/react';
import * as DemoStories from './demo.stories';

const { Default } = composeStories(DemoStories);

test('renders Case Launcher widget with default args', () => {
jest.spyOn(window, 'alert').mockImplementation(() => {});
render(<Default />);

const headingElement = screen.getByRole('heading');
expect(headingElement).not.toBeNull();

const buttonElement = screen.getByRole('button', { name: 'Start a case' });
expect(buttonElement).not.toBeNull();
fireEvent.click(buttonElement);
expect(window.alert).toHaveBeenCalled();
});
60 changes: 60 additions & 0 deletions src/components/Pega_Extensions_CaseLauncher/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import {
Card,
CardHeader,
CardContent,
CardFooter,
Text,
Button,
Configuration
} from '@pega/cosmos-react-core';
import StyledCard from './styles';

// interface for props
export type CaseLauncherProps = {
/** Card heading */
heading: string;
/** Description of the case launched by the widget */
description: string;
/** Class name of the case; used as property when launching pyStartCase */
classFilter: any;
/** Primary button label */
labelPrimaryButton: string;
getPConnect: any;
};

export default function PegaExtensionsCaseLauncher(props: CaseLauncherProps) {
const { heading, description, classFilter, labelPrimaryButton, getPConnect } = props;
const pConn = getPConnect();

/* Create a new case on click of the selected button */
const createCase = (className: string) => {
const options = {
flowType: 'pyStartCase',
containerName: 'primary',
openCaseViewAfterCreate: true
};

pConn.getActionsApi().createWork(className, options);
};

return (
<Configuration>
<Card as={StyledCard}>
<CardHeader>
<Text variant='h2'>{heading}</Text>
</CardHeader>
<CardContent>{description}</CardContent>
<CardFooter justify='end'>
<Button
variant='primary'
onClick={() => {
createCase(classFilter);
}}
>
{labelPrimaryButton}
</Button>
</CardFooter>
</Card>
</Configuration>
);
}
11 changes: 11 additions & 0 deletions src/components/Pega_Extensions_CaseLauncher/styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import styled, { css } from 'styled-components';
import { themeDefinition } from '@pega/cosmos-react-core';

const StyledCard = styled.article(({ theme }: { theme: typeof themeDefinition }) => {
return css`
background-color: ${theme.base.colors.white};
border-radius: 0.25rem;
width: 100%;
`;
});
export default StyledCard;

0 comments on commit 402d869

Please sign in to comment.