import { Card, CardContent, CardHeader, Typography, CardActions, Button, TableContainer, Table, TableBody, TableHead, TableCell, TableRow } from '@mui/material'; import { withStyles, createStyles } from '@mui/styles'; import makeStyles from '@mui/styles/makeStyles'; import { PConnProps } from '@pega/react-sdk-components/lib/types/PConnProps'; import StyledPegaDxilMyPageWidgetWrapper from './styles'; import isDeepEqual from 'fast-deep-equal/react'; import { Utils } from '@pega/react-sdk-components/lib/components/helpers/utils'; import { useRef, useEffect, useState } from 'react'; import { Theme as MuiTheme } from "@mui/material/styles"; declare module "@mui/private-theming" { interface DefaultTheme extends MuiTheme { spacing: (spacing: number) => string; } } interface PegaDxilMyPageWidgetProps extends PConnProps { // If any, enter additional props that only exist on this component header?: string; description?: string; datasource?: any; whatsnewlink?: string; } const useStyles = makeStyles(myTheme => ({ root: { marginTop: myTheme.spacing(1), marginBottom: myTheme.spacing(1), borderLeft: '6px solid', borderLeftColor: myTheme.palette.primary.light } })); const StyledTableCell = withStyles((myTheme) => createStyles({ head: { borderWidth: '1px', borderStyle: 'solid', borderColor: 'silver', backgroundColor: myTheme.palette.text.disabled, color: myTheme.palette.getContrastText(myTheme.palette.text.disabled) }, body: { borderWidth: '1px', borderStyle: 'solid', borderColor: 'silver' // fontSize: 14, } }) )(TableCell); // Page Widget example is the "App Announcment" // props passed in combination of props from property panel (config.json) and run time props from Constellation export default function PegaDxilMyPageWidget(props: PegaDxilMyPageWidgetProps) { const { header = '', description = '', datasource = [], whatsnewlink = '', getPConnect } = props; let details = []; if (datasource && datasource.source) { details = datasource.source.map(item => { return item.name; }); } // eslint-disable-next-line @typescript-eslint/no-unused-vars const [waitingForData, setWaitingForData] = useState(true); const thePConn = getPConnect(); const caseID = thePConn.getValue(PCore.getConstants().CASE_INFO.CASE_INFO_ID, ''); // 2nd arg empty string until typedef marked correctly const dataViewName = 'D_pyMyWorkList'; const context = thePConn.getContextName(); const rowData: any = useRef([]); const classes = useStyles(); const displayedColumns = [ { label: thePConn.getLocalizedValue('Case type', '', ''), type: 'TextInput', fieldName: 'pxProcessName' }, // 2nd and 3rd args empty string until typedef marked correctly { label: thePConn.getLocalizedValue('Key', '', ''), type: 'TextInput', fieldName: 'pxRefObjectInsName' }, // 2nd and 3rd args empty string until typedef marked correctly { label: thePConn.getLocalizedValue('Status', '', ''), type: 'TextInput', fieldName: 'pyAssignmentStatus' }, // 2nd and 3rd args empty string until typedef marked correctly { label: thePConn.getLocalizedValue('Stage', '', ''), type: 'TextInput', fieldName: 'pxTaskLabel' } // 2nd and 3rd args empty string until typedef marked correctly ]; function computeRowData(rows: object[]): void { const theRowData: object[] = []; rows?.forEach((row: any, rowIndex: number) => { // Now, for each property in the index of row properties (displayedColumns), add an object // to a new array of values const rowDisplayValues: any = []; displayedColumns.forEach((column: any, rowValIndex) => { const theType = column.type; const theFieldName = column.fieldName; const theValue = theType === 'Date' || theType === 'DateTime' ? Utils.generateDateTime(row[theFieldName], 'DateTime-Short') : row[theFieldName]; rowDisplayValues[rowValIndex] = theValue; }); theRowData[rowIndex] = rowDisplayValues; }); if (!isDeepEqual(theRowData, rowData.current)) { // Only update rowData.current when it actually changes (to prevent infinite loop) rowData.current = theRowData; } } const handleClick = () => { window.open(whatsnewlink); }; // Get the case history data when component mounted/initialized useEffect(() => { let bCallSetWaitingForData = true; const worklistData = PCore.getDataApiUtils().getData( dataViewName, { dataViewParameters: [{ CaseInstanceKey: caseID }] } as any, context ) as Promise; worklistData.then((worklistJSON: any) => { const tableDataResults = worklistJSON.data.data; // compute the rowData using the tableDataResults computeRowData(tableDataResults); // At this point, if we have data ready to render and haven't been asked // to NOT call setWaitingForData, we can stop progress indicator if (bCallSetWaitingForData) { setWaitingForData(false); } }); return () => { // Inspired by https://juliangaramendy.dev/blog/use-promise-subscription // The useEffect closure lets us have access to the bCallSetWaitingForData // variable inside the useEffect and inside the "then" clause of the // historyData promise // So, if this cleanup code gets run before the promise .then is called, // we can avoid calling the useState setter which would otherwise show a warning bCallSetWaitingForData = false; }; }, []); function getTableHeader() { const theRowKey = 'CaseHistory.TableHeader'; const theHeaderCells: any[] = displayedColumns.map((headerCol, index) => { const theCellKey = `${theRowKey}.${index}`; return {headerCol.label}; }); return {theHeaderCells}; } function getTableData() { const theDataRows: any[] = []; // Note: using rowData.current since we're using useRef as a mutatable // value that's only updated when it changes. if (rowData.current.length > 0) { rowData.current.forEach((dataRow: object[], index) => { // using dataRow[0]-dataRow[1] as the array key since it's a unique value const theKey = `CaseHistory-${index}`; theDataRows.push( {dataRow[0] ? (dataRow[0]) : '---' as any} {dataRow[1] ? (dataRow[1]) : '---' as any} {dataRow[2] ? (dataRow[2]) : '---' as any} {dataRow[3] ? (dataRow[3]) : '---' as any} ); }); } return theDataRows; } return ( {header}} /> {description} {details.map((itm, idx) => { const theKey = `AppAnn-item-${idx}`; return ( - {itm} ); })} {getTableHeader()}{getTableData()}
); }