Skip to content

Commit 53bd96e

Browse files
Feature: Add copy button to answer UI (#2131)
* add-copy-button * Update ptBR/translation.json Co-authored-by: Pamela Fox <[email protected]> * Update fr/translation.json Co-authored-by: Pamela Fox <[email protected]> * Update es/translation.json Co-authored-by: Pamela Fox <[email protected]> * Update da/translation.json * Update nl/translation.json * Update ja/translation.json * Update app/frontend/src/locales/en/translation.json --------- Co-authored-by: Pamela Fox <[email protected]>
1 parent c3810e8 commit 53bd96e

File tree

8 files changed

+43
-8
lines changed

8 files changed

+43
-8
lines changed

app/frontend/src/components/Answer/Answer.tsx

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useMemo } from "react";
1+
import { useMemo, useState } from "react";
22
import { Stack, IconButton } from "@fluentui/react";
33
import { useTranslation } from "react-i18next";
44
import DOMPurify from "dompurify";
@@ -46,13 +46,34 @@ export const Answer = ({
4646
const parsedAnswer = useMemo(() => parseAnswerToHtml(answer, isStreaming, onCitationClicked), [answer]);
4747
const { t } = useTranslation();
4848
const sanitizedAnswerHtml = DOMPurify.sanitize(parsedAnswer.answerHtml);
49+
const [copied, setCopied] = useState(false);
50+
51+
const handleCopy = () => {
52+
// Single replace to remove all HTML tags to remove the citations
53+
const textToCopy = sanitizedAnswerHtml.replace(/<a [^>]*><sup>\d+<\/sup><\/a>|<[^>]+>/g, "");
54+
55+
navigator.clipboard
56+
.writeText(textToCopy)
57+
.then(() => {
58+
setCopied(true);
59+
setTimeout(() => setCopied(false), 2000);
60+
})
61+
.catch(err => console.error("Failed to copy text: ", err));
62+
};
4963

5064
return (
5165
<Stack className={`${styles.answerContainer} ${isSelected && styles.selected}`} verticalAlign="space-between">
5266
<Stack.Item>
5367
<Stack horizontal horizontalAlign="space-between">
5468
<AnswerIcon />
5569
<div>
70+
<IconButton
71+
style={{ color: "black" }}
72+
iconProps={{ iconName: copied ? "CheckMark" : "Copy" }}
73+
title={copied ? t("tooltips.copied") : t("tooltips.copy")}
74+
ariaLabel={copied ? t("tooltips.copied") : t("tooltips.copy")}
75+
onClick={handleCopy}
76+
/>
5677
<IconButton
5778
style={{ color: "black" }}
5879
iconProps={{ iconName: "Lightbulb" }}

app/frontend/src/locales/da/translation.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,9 @@
5959
"showSupportingContent": "Vis understøttende indhold",
6060
"speakAnswer": "Afspil svar",
6161
"info": "Info",
62-
"save": "Gem"
62+
"save": "Gem",
63+
"copy": "Kopier",
64+
"copied": "Kopieret!"
6365
},
6466
"headerTexts": {
6567
"thoughtProcess": "Tankeproces",

app/frontend/src/locales/en/translation.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@
6161
"showSupportingContent": "Show supporting content",
6262
"speakAnswer": "Speak answer",
6363
"info": "Info",
64-
"save": "Save"
64+
"save": "Save",
65+
"copy": "Copy",
66+
"copied": "Copied!"
6567
},
6668

6769
"headerTexts":{

app/frontend/src/locales/es/translation.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@
6161
"showSupportingContent": "Mostrar contenido de soporte",
6262
"speakAnswer": "Hablar respuesta",
6363
"info": "Información",
64-
"save": "Guardar"
64+
"save": "Guardar",
65+
"copy": "Copiar",
66+
"copied": "¡Copiado!"
6567
},
6668

6769
"headerTexts":{

app/frontend/src/locales/fr/translation.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@
6161
"showSupportingContent": "Montrer le contenu de soutien",
6262
"speakAnswer": "Parler réponse",
6363
"info": "Info",
64-
"save": "Sauvegarder"
64+
"save": "Sauvegarder",
65+
"copy": "Copier",
66+
"copied": "Copié!"
6567
},
6668

6769
"headerTexts":{

app/frontend/src/locales/ja/translation.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@
6161
"showSupportingContent": "サポート内容の表示",
6262
"speakAnswer": "音声による回答",
6363
"info": "情報",
64-
"save": "保存"
64+
"save": "保存",
65+
"copy": "コピー",
66+
"copied": "コピーしました!"
6567
},
6668

6769
"headerTexts":{

app/frontend/src/locales/nl/translation.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@
6161
"showSupportingContent": "Ondersteunende inhoud tonen",
6262
"speakAnswer": "Antwoord uitspreken",
6363
"info": "Info",
64-
"save": "Opslaan"
64+
"save": "Opslaan",
65+
"copy": "Kopieer",
66+
"copied": "Gekopieerd!"
6567
},
6668

6769
"headerTexts": {

app/frontend/src/locales/ptBR/translation.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@
6161
"showSupportingContent": "Mostrar conteúdo de suporte",
6262
"speakAnswer": "Falar a resposta",
6363
"info": "Info",
64-
"save": "Save"
64+
"save": "Save",
65+
"copy": "Copiar",
66+
"copied": "Copiado!"
6567
},
6668

6769
"headerTexts":{

0 commit comments

Comments
 (0)