import { useEffect, useState } from 'react';
import {
Icon,
Button,
withConfiguration,
registerIcon,
Table,
Label,
Link,
URLDisplay
} from '@pega/cosmos-react-core';
import type { PConnFieldProps } from './PConnProps';
import './create-nonce';
// IMPORTANT
// To use Icons, need to individually import the icon file form @pega/cosmos-react-core (see path below)
// Icons filename is kabab case (file-name), where as the icon you import is camel case (fileName)
// Icons need to be registered (camel case), and then used (kabab case)
import * as listNumber from '@pega/cosmos-react-core/lib/components/Icon/icons/list-number.icon';
import * as arrowRight from '@pega/cosmos-react-core/lib/components/Icon/icons/arrow-right.icon';
import * as globe from '@pega/cosmos-react-core/lib/components/Icon/icons/globe.icon';
import StyledPegaDxilMyIconButtonUrlWrapper from './styles';
// interface for props
interface PegaDxilMyIconButtonUrlProps extends PConnFieldProps {
// If any, enter additional props that only exist on TextInput here
countryCode: string;
}
export const textFormatter = (value: string) => {
return ;
};
// *************
// This component is meant to be an example of usage (Icon, Button, Link, etc.) and NOT meant to be
// used "as is"
//
// In this example, Icon is shown on its own and inside a Button
// Though an Icon can have an "onClick" event is it recommended if you want to click on it,
// to put it in a Button (shown below), so you can have a tooltip and hover style or put it
// in a Link (shown below) as a URL.
//
// For the button, the click will get a list of states for a given country and display in a
// table below. The table display will toggle with the click of the button icon. Example shows
// how to handle click, retrieve data from PCore and display it.
//
// Globe icon is an icon placed in a Link element. The Link element to use an icon internally. (NOTE: In general
// the Link element shows the open icon to the left of the link text, but here we are using
// another icon, so with "icon" specified in the Link element, the open icon doesn't show)
// Link elements do not handle bad urls well, so we have a simple validator to prevent the Link element
// from getting most bad urls.
//
// NOTE: because icons have to be imported and registered, you can NOT put the icon name
// inside the config.json and let the user pick it, if it is not already part of your
// import and registration (can't be done on the fly)
// **************
// 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 PegaDxilMyIconButtonUrl(props: PegaDxilMyIconButtonUrlProps) {
const { value, displayMode, countryCode = 'USA', getPConnect, testId } = props;
const [statelist, setStatelist] = useState([]);
const [showTable, setShowTable] = useState(false);
const [validUrl, setValidUrl] = useState('about:blank');
const PConnect = getPConnect();
// IMPORTANT: need to register icons used in camel case
registerIcon(listNumber, arrowRight, globe);
// setting up columns for the work list table
const columns = [
{ renderer: 'stateName', label: PConnect.getLocalizedValue('State name', '', '') },
{ renderer: 'stateCode', label: PConnect.getLocalizedValue('State code', '', '') }
];
// toggle showing table and getting table data
function showHideTable() {
setShowTable(prevShowTable => !prevShowTable);
}
// check if url is valid (simple)
function validateUrl(href: string) {
return /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})))(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(
href
);
}
// Testing to see if value entered is valid url, if not can't use it.
// Reason for this code is that you can NOT pass to Link component
// a bad url, or it will error out.
// For example: Since the value is the property field,
// it could be entered from another component and thus as it is
// entered (typed in), it won't be valid until it is all entered.
// NOTE: can't have a blank value for the url as the Link element will error out
// in App studio preview
useEffect(() => {
if (validateUrl(value)) {
setValidUrl(value);
} else {
setValidUrl('about:blank');
}
}, [value]);
// going to get data for worklist to put into a table
// data comes from calling a PCore function to get
// get data from a data page and a PConnect function
// to get getContextName
useEffect(() => {
const dataViewName = 'D_pyStateList';
const context = PConnect.getContextName();
const params = { pyCountry: countryCode };
// only retrieve table data if table is shown
if (showTable) {
PCore.getDataPageUtils()
.getDataAsync(dataViewName, context, params, null, null)
// @ts-ignore
.then((response: any) => {
// table requires an index or will get setExtraStackFrame error
setStatelist(
response.data.map((entry: any, index: number) => {
// mapping the data into the column names
// MUST have an id/index or will get a setExtraStackFrame error
// put a key in the table
return {
stateName: entry.pyLabel,
stateCode: entry.pyStateCode,
id: index
};
})
);
})
.catch((error: any) => {
console.log(error);
});
}
}, [PConnect, countryCode, showTable]);
// when DISPLAY_ONLY, in this example we will just show the URL.
if (displayMode === 'DISPLAY_ONLY') {
const displayComp = textFormatter(validUrl);
return (
{displayComp}
);
}
return (