Skip to content

Commit 2478c01

Browse files
authored
feat: migrating widgets to patternfly/widgetized-dashboard (#273)
* feat: migrating widgets to patternfly/widgetized-dashboard * adding tests and updating functionality * adding currentDropInItemAtom back as removing it broke the drop on functionality
1 parent b799224 commit 2478c01

15 files changed

Lines changed: 1147 additions & 757 deletions

docs/components/custom-widgets.md

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Overview
44

5-
Custom widgets are React components that integrate with the Widget Layout system through federated modules. They are loaded dynamically via ScalprumComponent and displayed within GridTile containers that provide drag-and-drop functionality.
5+
Custom widgets are React components that integrate with the Widget Layout system through federated modules. They are loaded dynamically via ScalprumComponent and displayed within widget cards provided by `@patternfly/widgetized-dashboard`, which handles drag-and-drop functionality.
66

77
## Widget System Architecture
88

@@ -12,7 +12,7 @@ Widgets are loaded through a multi-step process:
1212

1313
1. **Widget Mapping**: The backend provides widget configuration via `/api/chrome-service/v1/dashboard-templates/widget-mapping`
1414
2. **Module Federation**: Widgets are loaded as federated modules using ScalprumComponent (configured via `fec.config.js`)
15-
3. **Grid Integration**: Each widget is wrapped in a GridTile that provides layout and interaction capabilities
15+
3. **Grid Integration**: The PatternFly GridLayout component renders each widget within a Card component that provides layout and interaction capabilities
1616

1717
*Note: Module federation is handled by the Red Hat Cloud Services frontend tooling. You don't need to configure webpack directly.*
1818

@@ -77,7 +77,7 @@ export type WidgetPermission = {
7777

7878
### Step 1: Create the Widget Component
7979

80-
Your widget is a standard React component that provides content for the CardBody wrapper. **Note**: The Card wrapper (including header, title, and actions) is automatically provided by the GridTile component - your widget should only provide the content.
80+
Your widget is a standard React component that provides content for the CardBody wrapper. **Note**: The Card wrapper (including header, title, and actions) is automatically provided by the PatternFly GridLayout component - your widget should only provide the content.
8181

8282
```tsx
8383
// MyCustomWidget.tsx
@@ -163,9 +163,9 @@ The widget mapping must be provided by the backend API at `/api/chrome-service/v
163163

164164
## Widget Integration Details
165165

166-
### GridTile Integration
166+
### PatternFly GridLayout Integration
167167

168-
Your widget is automatically wrapped in a GridTile component that provides:
168+
Your widget is automatically wrapped in a widget card by the `@patternfly/widgetized-dashboard` GridLayout component that provides:
169169

170170
- **Drag and Drop**: Move widgets around the grid
171171
- **Resize Handles**: Resize widgets within min/max constraints
@@ -174,26 +174,45 @@ Your widget is automatically wrapped in a GridTile component that provides:
174174

175175
### Widget Container Structure
176176

177-
Your custom widget content is automatically wrapped in a Card structure by the GridTile component:
177+
Your custom widget content is automatically wrapped in a Card structure by the PatternFly GridLayout component. The component internally manages widget cards with:
178+
179+
- **Card Header**: Contains the widget title, icon, and action menu
180+
- **Card Body**: Your custom widget component renders here
181+
182+
Widget rendering is handled through the widget mapping configuration:
178183

179184
```tsx
180-
// From src/Components/DnDLayout/GridTile.tsx - Simplified structure
181-
<Card className="grid-tile">
182-
<CardHeader actions={{ actions: headerActions }}>
183-
<Flex>
184-
<HeaderIcon icon={widgetConfig?.config?.icon} />
185-
<CardTitle>{widgetConfig?.config?.title || widgetType}</CardTitle>
186-
</Flex>
187-
</CardHeader>
188-
<Divider />
189-
<CardBody className="pf-v6-u-p-0">
190-
{/* Your widget component renders here - this is where your custom component appears */}
191-
{node}
192-
</CardBody>
193-
</Card>
185+
// From src/Components/DnDLayout/GridLayout.tsx
186+
const convertWidgetMapping = (scalprumMapping: ScalprumWidgetMapping): WidgetMapping => {
187+
const result: WidgetMapping = {};
188+
189+
Object.keys(scalprumMapping).forEach((widgetType) => {
190+
const scalprumWidget = scalprumMapping[widgetType];
191+
result[widgetType] = {
192+
defaults: scalprumWidget.defaults,
193+
config: {
194+
title: scalprumWidget.config?.title,
195+
icon: scalprumWidget.config?.icon ? <HeaderIcon icon={scalprumWidget.config.icon} /> : undefined,
196+
headerLink: scalprumWidget.config?.headerLink,
197+
wrapperProps: { className: scalprumWidget.scope },
198+
cardBodyProps: { className: `${scalprumWidget.scope}-${widgetType}` }
199+
},
200+
renderWidget: (_widgetId: string) => (
201+
<ScalprumComponent
202+
fallback={<Skeleton />}
203+
scope={scalprumWidget.scope}
204+
module={scalprumWidget.module}
205+
importName={scalprumWidget.importName}
206+
/>
207+
),
208+
};
209+
});
210+
211+
return result;
212+
};
194213
```
195214

196-
**Important**: Your widget should **NOT** include Card, CardHeader, or CardTitle components as these are provided by the GridTile wrapper.
215+
**Important**: Your widget should **NOT** include Card, CardHeader, or CardTitle components as these are provided by the PatternFly GridLayout component wrapper.
197216

198217
## Widget Sizing and Layout
199218

0 commit comments

Comments
 (0)