react-integration-buttons
Version:
A TypeScript React component for Microsoft Teams and ServiceNow integrations with deep linking support
106 lines (103 loc) • 3.98 kB
JavaScript
import React from 'react';
const IntegrationButton = (props) => {
const { platform, buttonText, className = "", style = {} } = props;
const platformConfigs = {
teams: {
defaultText: "Open in Teams",
defaultColor: "#464775",
icon: "",
},
servicenow: {
defaultText: "Create in ServiceNow",
defaultColor: "#81b5a1",
icon: "",
},
};
const config = platformConfigs[platform] || platformConfigs.teams;
const handleClick = () => {
if (platform === "teams") {
openTeams();
}
else if (platform === "servicenow") {
openServiceNow();
}
};
// ============================================
// TEAMS IMPLEMENTATION
// ============================================
const openTeams = () => {
if (props.platform !== "teams")
return;
const { users, message, topicName } = props;
if (!users || !message) {
console.error("Teams integration requires 'users' and 'message' props");
return;
}
const formattedMessage = formatMessageForTeams(message);
let teamsUrl = `https://teams.microsoft.com/l/chat/0/0?users=${encodeURIComponent(users)}`;
teamsUrl += `&message=${encodeURIComponent(formattedMessage)}`;
if (topicName) {
teamsUrl += `&topicName=${encodeURIComponent(topicName)}`;
}
window.open(teamsUrl, "_blank");
};
const formatMessageForTeams = (msg) => {
if (msg.includes("<")) {
return msg;
}
let formatted = msg;
formatted = formatted.replace(/\*\*(.+?)\*\*/g, "<b>$1</b>");
formatted = formatted.replace(/__(.+?)__/g, "<b>$1</b>");
formatted = formatted.replace(/\*(.+?)\*/g, "<i>$1</i>");
formatted = formatted.replace(/_(.+?)_/g, "<i>$1</i>");
formatted = formatted.replace(/~~(.+?)~~/g, "<s>$1</s>");
formatted = formatted.replace(/\n/g, "<br>");
return formatted;
};
// ============================================
// SERVICENOW IMPLEMENTATION
// ============================================
const openServiceNow = () => {
if (props.platform !== "servicenow")
return;
const { instanceUrl, table = "incident", fields = {} } = props;
if (!instanceUrl) {
console.error("ServiceNow integration requires 'instanceUrl' prop");
return;
}
const sysparmQuery = buildSysparmQuery(fields);
const serviceNowUrl = `https://${instanceUrl}/nav_to.do?uri=${table}.do?sys_id=-1${sysparmQuery}`;
window.open(serviceNowUrl, "_blank");
};
const buildSysparmQuery = (fieldsObj) => {
if (!fieldsObj || Object.keys(fieldsObj).length === 0) {
return "";
}
const queryParts = Object.entries(fieldsObj).map(([field, value]) => {
return `${field}=${encodeURIComponent(String(value))}`;
});
return `&sysparm_query=${queryParts.join("^")}`;
};
// ============================================
// RENDER
// ============================================
const defaultStyle = {
padding: "10px 20px",
backgroundColor: config.defaultColor,
color: "white",
border: "none",
borderRadius: "4px",
cursor: "pointer",
fontSize: "14px",
display: "inline-flex",
alignItems: "center",
gap: "8px",
width: "fit-content",
...style,
};
return (React.createElement("button", { onClick: handleClick, className: className, style: className ? undefined : defaultStyle },
React.createElement("span", null, config.icon),
React.createElement("span", null, buttonText || config.defaultText)));
};
export { IntegrationButton, IntegrationButton as default };
//# sourceMappingURL=index.es.js.map