import { useEffect, useState } from 'react'; import { DateTimeInput, FieldValueList, DateTimeDisplay, Text, withConfiguration } from "@pega/cosmos-react-core"; import type { PConnFieldProps } from './PConnProps'; import './create-nonce'; // includes in bundle import DateTimeFormatter from "./date-time"; import {datetimedisplayformatter,formatExists} from "./date"; import { getFullYear, getMaxDate, getMinDate, parseClockFormat, correctDateTimeToSeconds, datetimeFireChangeBlurEvents } from "./date-utils"; import { suggestionsHandler } from './suggestions-handler'; import StyledPegaDxilMyDateTimeWrapper from './styles'; import type { DateTimeFormat, DateTimeVariant } from '@pega/cosmos-react-core/lib/components/DateTime/DateTime.types'; import type { ClockFormat } from '@pega/cosmos-react-core/lib/components/DateTime/Input/utils'; // interface for props interface PegaDxilMyDateTimeProps extends PConnFieldProps { // If any, enter additional props that only exist on TextInput here displayAsStatus?: boolean; isTableFormatter?: boolean; hasSuggestions?: boolean; variant?: any; formatter?: string; withSeconds: boolean; nextYearRange: string; previousYearRange: string; showWeekNumber: boolean; pickerInterval: string; clockFormat: number; } // interface for StateProps object interface StateProps { value: string; hasSuggestions: boolean; } interface ConfigProps { formatter?: string; } interface ActionsProps { onFocus: any; } // Duplicated runtime code from Constellation Design System Component // props passed in combination of props from property panel (config.json) and run time props from Constellation // any default values in config.pros should be set in defaultProps at bottom of this file function PegaDxilMyDateTime (props: PegaDxilMyDateTimeProps) { const { getPConnect, value, validatemessage, label, hideLabel = false, helperText, withSeconds, nextYearRange, previousYearRange, showWeekNumber = false, pickerInterval = '30', testId, additionalProps = {}, displayMode, variant = 'inline', hasSuggestions = false } = props; let { formatter } = props; const pConn = getPConnect(); const actions = pConn.getActionsApi(); const actionsProps = pConn.getActionsApi() as unknown as ActionsProps; const stateProps = pConn.getStateProps() as StateProps; const propName: string = stateProps.value; const environmentInfo = PCore.getEnvironmentInfo(); const timezone = environmentInfo && environmentInfo.getTimeZone(); let { readOnly = false, required = false, disabled = false } = props; [readOnly, required, disabled] = [readOnly, required, disabled].map( (prop) => prop === true || (typeof prop === 'string' && prop === 'true') ); const [status, setStatus] = useState(hasSuggestions ? 'pending' : undefined); // cast status let myStatus: 'success' | 'warning' | 'error' | 'pending'; // eslint-disable-next-line prefer-const myStatus = status as 'success' | 'warning' | 'error' | 'pending'; useEffect(() => { if (validatemessage !== '') { setStatus('error'); } if (hasSuggestions) { setStatus('pending'); } else if (!hasSuggestions && myStatus !== 'success') { setStatus(validatemessage !== '' ? 'error' : undefined); } }, [validatemessage, hasSuggestions, myStatus]); let { clockFormat = 0 } = props; clockFormat = parseClockFormat(clockFormat); // calculate min and max range of calendar const currentYear = getFullYear(""); const yearFromValue = getFullYear(value); const maxDate = getMaxDate(parseInt(nextYearRange, 10), currentYear, yearFromValue); const minDate = getMinDate(parseInt(previousYearRange, 10), currentYear, yearFromValue); const onResolveSuggestionHandler = (accepted: boolean) => { suggestionsHandler(accepted, pConn, setStatus); }; function handleBlur(onBlurValue: any) { const { valueAsISOString: datetimeTZ, state: errorState } = onBlurValue; const datetimeGMT = DateTimeFormatter.convertFromTimezone(datetimeTZ, timezone); const datetimeGMTCorrectedToSeconds = datetimeGMT ? correctDateTimeToSeconds(datetimeGMT, withSeconds) : datetimeGMT; datetimeFireChangeBlurEvents(errorState, value, datetimeGMTCorrectedToSeconds, actions, propName, pConn); const isValueChanged = !(value === undefined && datetimeGMTCorrectedToSeconds === '') && value !== datetimeGMTCorrectedToSeconds; if (hasSuggestions && isValueChanged) { pConn.ignoreSuggestion(""); } } function handleChange(onChangeValue: any) { const { valueAsISOString: datetimeTZ } = onChangeValue; const datetimeGMT = DateTimeFormatter.convertFromTimezone(datetimeTZ, timezone); const datetimeGMTCorrectedToSeconds = datetimeGMT ? correctDateTimeToSeconds(datetimeGMT, withSeconds) : datetimeGMT; if (hasSuggestions && value !== datetimeGMTCorrectedToSeconds) { setStatus(undefined); } pConn.clearErrorMessages({ category: "", property: propName, context: "" }); } if (displayMode === 'LABELS_LEFT' || displayMode === 'STACKED_LARGE_VAL' || displayMode === 'DISPLAY_ONLY') { let variantValue = 'datetime' as DateTimeVariant; let formatValue = withSeconds ? 'long' : 'short' as DateTimeFormat; const configProps = pConn.getConfigProps() as ConfigProps; const runtimeformatter = configProps?.formatter; if (formatter !== runtimeformatter) { formatter = runtimeformatter; } if (formatExists(formatter)) { // @ts-ignore const { variantVal, formatVal } = datetimedisplayformatter(formatter); variantValue = variantVal as DateTimeVariant; formatValue = withSeconds && formatter === 'Time-Only' ? 'long' : formatVal as DateTimeFormat; } const displayComp = ( ); switch (displayMode) { case 'DISPLAY_ONLY': { return ( {displayComp} ); } case 'LABELS_LEFT': { return ( ); } case 'STACKED_LARGE_VAL': { return ( {displayComp} ) } ]} /> ); } // no default } } return ( ); } export default withConfiguration(PegaDxilMyDateTime);