Skip to content

Commit 58bfea6

Browse files
authored
Merge pull request #158 from pegasystems/bugfix/disp
add new Hierarchical Form as Tasks component
2 parents 2294a1b + a203182 commit 58bfea6

File tree

14 files changed

+844
-386
lines changed

14 files changed

+844
-386
lines changed

package-lock.json

Lines changed: 372 additions & 370 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,17 @@
5858
"help": "custom-dx-components showHelp"
5959
},
6060
"dependencies": {
61-
"@arcgis/core": "^4.32.9",
61+
"@arcgis/core": "^4.32.10",
6262
"@dagrejs/dagre": "^1.1.4",
6363
"@fullcalendar/core": "^6.1.17",
6464
"@fullcalendar/daygrid": "^6.1.17",
6565
"@fullcalendar/react": "^6.1.17",
6666
"@fullcalendar/timegrid": "^6.1.17",
6767
"@hello-pangea/dnd": "^16.6.0",
68-
"@pega/cosmos-react-core": "^7.5.1",
69-
"@pega/cosmos-react-rte": "^7.5.1",
70-
"@pega/cosmos-react-social": "^7.5.1",
71-
"@pega/cosmos-react-work": "^7.5.1",
68+
"@pega/cosmos-react-core": "^7.5.3",
69+
"@pega/cosmos-react-rte": "^7.5.3",
70+
"@pega/cosmos-react-social": "^7.5.3",
71+
"@pega/cosmos-react-work": "^7.5.3",
7272
"gantt-task-react": "^0.3.9",
7373
"imask": "^7.6.1",
7474
"jsbarcode": "^3.11.6",
@@ -85,7 +85,7 @@
8585
"@babel/preset-react": "^7.26.3",
8686
"@babel/preset-typescript": "^7.27.0",
8787
"@pega/configs": "^0.16.3",
88-
"@pega/custom-dx-components": "^24.2.12",
88+
"@pega/custom-dx-components": "^24.2.13",
8989
"@pega/eslint-config": "^0.16.3",
9090
"@pega/pcore-pconnect-typedefs": "^3.2.1",
9191
"@pega/tsconfig": "^0.16.3",
@@ -110,7 +110,7 @@
110110
"eslint-plugin-import": "^2.31.0",
111111
"eslint-plugin-jest": "^28.11.0",
112112
"eslint-plugin-jsx-a11y": "^6.10.2",
113-
"eslint-plugin-mdx": "^3.3.2",
113+
"eslint-plugin-mdx": "^3.4.0",
114114
"eslint-plugin-prettier": "^5.2.6",
115115
"eslint-plugin-react": "^7.37.5",
116116
"eslint-plugin-react-hooks": "^4.6.2",
@@ -123,9 +123,9 @@
123123
"prettier": "^3.5.3",
124124
"sort-package-json": "^2.14.0",
125125
"storybook": "^7.6.19",
126-
"stylelint": "16.17.0",
127-
"ts-jest": "^29.3.1",
128-
"typescript": "^5.8.2"
126+
"stylelint": "16.18.0",
127+
"ts-jest": "^29.3.2",
128+
"typescript": "^5.8.3"
129129
},
130130
"organization": "Pega"
131131
}

src/components/Pega_Extensions_Banner/config.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,7 @@
88
"allowedApplications": [],
99
"componentKey": "Pega_Extensions_Banner",
1010
"type": "Widget",
11-
"subtype": [
12-
"PAGE",
13-
"CASE"
14-
],
11+
"subtype": ["PAGE", "CASE"],
1512
"properties": [
1613
{
1714
"name": "variant",
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Meta, Primary, Controls, Story } from '@storybook/blocks';
2+
import * as DemoStories from './demo.stories';
3+
4+
<Meta of={DemoStories} />
5+
6+
# Overview
7+
8+
<Primary />
9+
10+
## Props
11+
12+
<Controls />
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import { Flex, Button } from '@pega/cosmos-react-core';
2+
import type { Task } from './types';
3+
4+
type TaskDetailProps = {
5+
task: Task;
6+
onSubmit: (task: Task) => void;
7+
onClose: (task: Task) => void;
8+
};
9+
10+
/**
11+
* Component that renders the detailed view of a task
12+
*/
13+
export const TaskDetail = ({ task, onSubmit, onClose }: TaskDetailProps) => {
14+
return (
15+
<Flex container={{ direction: 'column', gap: 1 }}>
16+
{task.content}
17+
<Flex container={{ direction: 'row', justify: 'between' }}>
18+
<Button onClick={() => onClose(task)} variant='secondary'>
19+
{'< Back'}
20+
</Button>
21+
<Button onClick={() => onSubmit(task)} variant='primary'>
22+
Continue
23+
</Button>
24+
</Flex>
25+
</Flex>
26+
);
27+
};
28+
29+
export default TaskDetail;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { Button } from '@pega/cosmos-react-core';
2+
import type { Task } from './types';
3+
4+
type TaskListItemProps = {
5+
task: Task;
6+
onOpen: (task: Task) => void;
7+
};
8+
9+
/**
10+
* Component that renders a single task item in the task list
11+
*/
12+
export const TaskListItem = ({ task, onOpen }: TaskListItemProps) => {
13+
return (
14+
<li className='task'>
15+
<div className='name'>
16+
<Button variant='link' onClick={() => onOpen(task)}>
17+
{task.title}
18+
</Button>
19+
</div>
20+
<div className='status'>
21+
<span>{task.status}</span>
22+
</div>
23+
</li>
24+
);
25+
};
26+
27+
export default TaskListItem;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"name": "Pega_Extensions_HierarchicalFormAsTasks",
3+
"label": "Hierarchical Form as Tasks",
4+
"description": "Hierarchical Form as Tasks",
5+
"organization": "Pega",
6+
"version": "1.0.0",
7+
"library": "Extensions",
8+
"allowedApplications": [],
9+
"componentKey": "Pega_Extensions_HierarchicalFormAsTasks",
10+
"type": "Template",
11+
"subtype": "FORM",
12+
"icon": "HierarchicalForm.svg",
13+
"properties": [
14+
{
15+
"name": "heading",
16+
"label": "Label",
17+
"format": "TEXT"
18+
},
19+
{
20+
"name": "A",
21+
"label": "Region A",
22+
"format": "CONTENTPICKER",
23+
"addTypeList": ["Fields", "Views"],
24+
"allowCreatingGroup": true
25+
}
26+
]
27+
}
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import type { StoryObj } from '@storybook/react';
2+
import {
3+
Text,
4+
Grid,
5+
Card,
6+
CardContent,
7+
CardHeader,
8+
Input,
9+
FormControl,
10+
FormField
11+
} from '@pega/cosmos-react-core';
12+
import { PegaExtensionsHierarchicalFormAsTasks } from './index';
13+
import React from 'react';
14+
15+
export default {
16+
title: 'Templates/Hierarchical Form as Tasks',
17+
argTypes: {
18+
getPConnect: {
19+
table: {
20+
disable: true
21+
}
22+
}
23+
},
24+
component: PegaExtensionsHierarchicalFormAsTasks
25+
};
26+
27+
type Story = StoryObj<typeof PegaExtensionsHierarchicalFormAsTasks>;
28+
export const Default: Story = {
29+
render: args => {
30+
const props = {
31+
template: 'HierarchicalFormAsTasks',
32+
heading: args.heading,
33+
getPConnect: () => {
34+
return {};
35+
}
36+
};
37+
38+
// Create a wrapper component that has the necessary structure
39+
interface ChildWrapperProps {
40+
getPConnect: () => {
41+
getChildren: () => Array<any>;
42+
};
43+
}
44+
45+
const ChildComponentWrapper: React.FC<ChildWrapperProps> = () => {
46+
// This component provides the structure expected by the parent component
47+
return null; // The actual rendering is handled by the parent
48+
};
49+
50+
// Mock the children components with the correct structure
51+
const generateView = (viewName: string) => ({
52+
getPConnect: () => ({
53+
getComponent: () => (
54+
<Card>
55+
<CardHeader>
56+
<Text variant='h2'>{viewName}</Text>
57+
</CardHeader>
58+
<CardContent>
59+
<Grid
60+
container={{ gap: 1, cols: `repeat(1, minmax(0, 1fr))` }}
61+
style={{ maxWidth: '80ch' }}
62+
>
63+
{[1, 2, 3].map(index => (
64+
<FormField key={index} label={`${viewName}-Field${index}`}>
65+
<FormControl ariaLabel={`${viewName}-Field${index}`}>
66+
<Input />
67+
</FormControl>
68+
</FormField>
69+
))}
70+
</Grid>
71+
</CardContent>
72+
</Card>
73+
),
74+
getConfigProps: () => ({
75+
name: viewName
76+
})
77+
})
78+
});
79+
80+
const generateGroup = (groupNumber: number, viewCount: number) => ({
81+
getPConnect: () => ({
82+
getConfigProps: () => ({
83+
heading: `Group${groupNumber}`
84+
}),
85+
getChildren: () =>
86+
Array(viewCount)
87+
.fill(null)
88+
.map((_, i) => generateView(`View${groupNumber}-${i + 1}`))
89+
})
90+
});
91+
92+
const generateChildren = (groupCount: number, viewsPerGroup: number) => [
93+
<ChildComponentWrapper
94+
key='1'
95+
getPConnect={() => ({
96+
getChildren: () =>
97+
Array(groupCount)
98+
.fill(null)
99+
.map((_, i) => generateGroup(i + 1, viewsPerGroup))
100+
})}
101+
/>
102+
];
103+
104+
const children = generateChildren(args.numberOfGroups || 2, args.viewsPerGroup || 2);
105+
106+
return (
107+
<Card>
108+
<CardContent>
109+
<PegaExtensionsHierarchicalFormAsTasks {...props}>
110+
{children}
111+
</PegaExtensionsHierarchicalFormAsTasks>
112+
</CardContent>
113+
</Card>
114+
);
115+
},
116+
args: {
117+
heading: 'Heading',
118+
numberOfGroups: 2,
119+
viewsPerGroup: 2
120+
}
121+
};
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import { render, screen } from '@testing-library/react';
2+
import { composeStories } from '@storybook/react';
3+
import * as DemoStories from './demo.stories';
4+
5+
const { Default } = composeStories(DemoStories);
6+
7+
test('renders PegaExtensionsHierarchicalFormAsTasks component with default args', async () => {
8+
render(<Default />);
9+
expect(await screen.findByText('Heading')).toBeVisible();
10+
});

0 commit comments

Comments
 (0)