fleet/frontend/components/ClickableUrls/ClickableUrls.tsx
jacobshandling 6b42d7c45a
UI – Make download CSR "missing private key" error link clickable (#21515)
## Addresses #20531 

###
[Demo](https://www.loom.com/share/79af364b61cb426b9c92abf19f3858ca?sid=4d476e0e-861d-4227-8c5f-086b5ca632cb)

<img width="1800" alt="Screenshot 2024-08-22 at 4 56 21 PM"
src="https://github.com/user-attachments/assets/24400570-65a6-4641-ba01-81ed82e248c8">


- [x] Changes file added for user-visible changes in `changes/`,
- [x] Manual QA for all new/changed functionality

---------

Co-authored-by: Jacob Shandling <jacob@fleetdm.com>
2024-08-23 08:20:36 -07:00

38 lines
1.1 KiB
TypeScript

import React from "react";
import * as DOMPurify from "dompurify";
import classnames from "classnames";
interface IClickableUrls {
text: string;
className?: string;
}
const baseClass = "clickable-urls";
const urlReplacer = (match: string) => {
const url = match.startsWith("http") ? match : `https://${match}`;
return `<a href=${url} target="_blank" rel="noreferrer">
${match}
</a>`;
};
const ClickableUrls = ({ text, className }: IClickableUrls): JSX.Element => {
const clickableUrlClasses = classnames(baseClass, className);
// Regex to find case insensitive URLs and replace with link
const textWithLinks = text.replaceAll(
/(((https?)?(:\/\/))|((https?)?(:\/\/)?(www\.)))[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)/g,
urlReplacer
);
const sanitizedTextWithLinks = DOMPurify.sanitize(textWithLinks, {
ADD_ATTR: ["target"], // Allows opening in a new tab
});
return (
<div
className={clickableUrlClasses}
dangerouslySetInnerHTML={{ __html: sanitizedTextWithLinks }}
/>
);
};
export default ClickableUrls;