diff --git a/packages/module/patternfly-docs/content/extensions/component-groups/examples/StaleDataWarning/StaleDataWarning.md b/packages/module/patternfly-docs/content/extensions/component-groups/examples/StaleDataWarning/StaleDataWarning.md new file mode 100644 index 00000000..7454210b --- /dev/null +++ b/packages/module/patternfly-docs/content/extensions/component-groups/examples/StaleDataWarning/StaleDataWarning.md @@ -0,0 +1,37 @@ +--- +# Sidenav top-level section +# should be the same for all markdown files +section: Component groups +subsection: Status and state indicators +# Sidenav secondary level section +# should be the same for all markdown files +id: Stale data warning +# Tab (react | react-demos | html | html-demos | design-guidelines | accessibility) +source: react +# If you use typescript, the name of the interface to display props for +# These are found through the sourceProps function provided in patternfly-docs.source.js +propComponents: ['StaleDataWarning'] +sourceLink: https://github.com/patternfly/react-component-groups/blob/main/packages/module/patternfly-docs/content/extensions/component-groups/examples/StaleDataWarning/StaleDataWarning.md +--- + +import StaleDataWarning from '@patternfly/react-component-groups/dist/dynamic/StaleDataWarning'; + +A **stale data warning** component displays a warning status when an object is stale and planned for removal. Additional warning details can be displayed as a tooltip or text label. + +## Examples + +### Basic stale data warning example + +A basic stale data warning component displays a warning icon with additional details in a tooltip, including a timeline for data removal. + +```js file="./StaleDataWarningExample.tsx" + +``` + +### Stale data warning with customized props + +Instead of sharing details in a tooltip, you can place a short message beside the icon. You can still utilize all properties of the [tooltip component](/components/tooltip), with the exception of `content`. + +```js file="./StaleDataWarningCustomExample.tsx" + +``` \ No newline at end of file diff --git a/packages/module/patternfly-docs/content/extensions/component-groups/examples/StaleDataWarning/StaleDataWarningCustomExample.tsx b/packages/module/patternfly-docs/content/extensions/component-groups/examples/StaleDataWarning/StaleDataWarningCustomExample.tsx new file mode 100644 index 00000000..813b3c93 --- /dev/null +++ b/packages/module/patternfly-docs/content/extensions/component-groups/examples/StaleDataWarning/StaleDataWarningCustomExample.tsx @@ -0,0 +1,36 @@ +import React from 'react'; +import StaleDataWarning from '@patternfly/react-component-groups/dist/dynamic/StaleDataWarning'; +import { Stack, StackItem } from '@patternfly/react-core'; + + +export const CustomizedRenderExample: React.FunctionComponent = () => { + const staleDate = new Date('Sun Jan 26 2020'); + const warningDate = new Date('Mon Feb 15 2025'); + const cullingDate = new Date('Fri Feb 20 2025'); + return <> + + + ({msg})}> + + + + + (This is an error message where the item is overdue)}> + + + + + + + +}; \ No newline at end of file diff --git a/packages/module/patternfly-docs/content/extensions/component-groups/examples/StaleDataWarning/StaleDataWarningExample.tsx b/packages/module/patternfly-docs/content/extensions/component-groups/examples/StaleDataWarning/StaleDataWarningExample.tsx new file mode 100644 index 00000000..82046ff5 --- /dev/null +++ b/packages/module/patternfly-docs/content/extensions/component-groups/examples/StaleDataWarning/StaleDataWarningExample.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import StaleDataWarning from '@patternfly/react-component-groups/dist/dynamic/StaleDataWarning'; +import { Stack, StackItem } from '@patternfly/react-core'; + +export const BasicExample: React.FunctionComponent = () => { + const staleDate = new Date('Sun Jan 26 2020'); + const warningDate = new Date('Mon Feb 15 2025'); + const cullingDate = new Date('Fri Feb 20 2025'); + return <> + + + + + + + + + + + + + + +}; diff --git a/packages/module/src/StaleDataWarning/StaleDataWarning.tsx b/packages/module/src/StaleDataWarning/StaleDataWarning.tsx new file mode 100644 index 00000000..fa9dc673 --- /dev/null +++ b/packages/module/src/StaleDataWarning/StaleDataWarning.tsx @@ -0,0 +1,130 @@ +import React from 'react'; +import { ExclamationCircleIcon, ExclamationTriangleIcon } from '@patternfly/react-icons'; +import { Button, Icon, Tooltip, TooltipProps } from '@patternfly/react-core'; +import clsx from 'clsx'; +import { createUseStyles } from 'react-jss'; + +type Render = (config: { msg: string }) => React.ReactElement | null; +type CullingDate = string | number | Date; + +interface StaleDataInfo { + isWarn?: boolean; + isError?: boolean; + msg: string; +} + +const seconds = 1000; +const minutes: number = seconds * 60; +const hours: number = minutes * 60; +const days: number = hours * 24; + +type CalculateTooltip = (culled: CullingDate, warning: CullingDate, currDate: CullingDate) => StaleDataInfo; + +const useStyles = createUseStyles({ + inventoryCullingWarning: { + color: 'var(--pf-t--global--icon--color--status--warning--default)', + }, + inventoryCullingDanger: { + color: 'var(--pf-t--global--icon--color--status--danger--default)', + }, + iconMargin: { + marginRight: 'var(--pf-t--global--spacer--sm)' + }, + messageFont: { + fontWeight: 'var(--pf-t--global--font--weight--body--bold)', + }, +}); + +/** extends TooltipProps */ +export interface StaleDataWarningProps extends Omit { + /** Option to add custom css classes */ + className?: string; + /** Warning date for when object becomes stale */ + staleWarning: CullingDate; + /** Date when object becomes culled */ + culled: CullingDate; + /** Date when object becomes stale */ + stale: CullingDate; + /** Current date */ + currDate: CullingDate; + /** Optional prop to add custom children */ + children?: React.ReactElement> | undefined; + /** Option to add custom message ReactElement */ + render?: Render; + /** Optional custom warning message */ + message?: string; + /** Accessible label for the icon */ + "aria-label"?: string; +} + +const StaleDataWarning: React.FunctionComponent = ({ + culled = new Date(0), + className, + staleWarning = new Date(0), + stale = new Date(0), + currDate = new Date(0), + children, + render, + message, + "aria-label": ariaLabel, + ...props +}) => { + const classes = useStyles(); + + const calculateTooltip: CalculateTooltip = (culled, warning, currDate) => { + const culledDate: Date = new Date(culled); + const warningDate: Date = new Date(warning); + const diffTime: number = new Date(currDate).valueOf() - warningDate.valueOf(); + const removeIn: number = Math.ceil((culledDate.valueOf() - new Date(currDate).valueOf()) / days); + const msg = message ? message : `System scheduled for inventory removal in ${removeIn} days`; + if (diffTime >= 0) { + return { + isError: true, + msg, + }; + } + + return { + isWarn: true, + msg, + }; + }; + + if (new Date(currDate).valueOf() - new Date(stale).valueOf() < 0) { + return render + ? render({ + msg: '', + }) + : children || null; + } + + const { isWarn, isError, msg }: StaleDataInfo = calculateTooltip(culled, staleWarning, currDate); + if (render) { + return ( + + {isWarn && + + } + {isError && + + } + + {render({ msg })} + + + ); + } + + return ( + <> + {isError && {msg}}>