Spaces:
Sleeping
Sleeping
Antigravity Bot commited on
Commit ·
ee1fafd
1
Parent(s): 9bd50b9
Blur Badges
Browse files- app.py +18 -12
- public/elements/UserMessage.jsx +157 -33
app.py
CHANGED
|
@@ -110,42 +110,36 @@ async def set_starters():
|
|
| 110 |
return [
|
| 111 |
cl.Starter(
|
| 112 |
label="Example en Français",
|
| 113 |
-
message="""Jean-Marc Durand, né le 14 avril 1987 à Lyon (69003), de nationalité française, est un ingénieur informatique marié à Sophie Martin depuis le 22 juin 2013. Il réside actuellement au 27 avenue des Lilas, appartement 42, 75019 Paris, France. Son numéro de téléphone personnel est le +33 6 48 72 19 05, son numéro de téléphone fixe est le 01 44 62 98 31, et son adresse e-mail principale est jeanmarc.durand1987@gmail.com
|
| 114 |
-
. Il utilise également l’adresse professionnelle j.durand@techsoluce.fr
|
| 115 |
-
.
|
| 116 |
Reformule ce texte""",
|
| 117 |
),
|
| 118 |
|
| 119 |
cl.Starter(
|
| 120 |
label="Example en Anglais",
|
| 121 |
message="""Michael Andrew Thompson, born on September 18, 1985, in Boston, Massachusetts (02118), USA, is a U.S. citizen currently living at 742 Evergreen Terrace, Apartment 5B, Brooklyn, New York, NY 11221. His mobile phone number is +1 (917) 555-3849, his home phone is +1 (718) 555-9021, and his primary email address is michael.thompson1985@gmail.com
|
| 122 |
-
, while his work email is m.thompson@fintechcore.com
|
| 123 |
-
. His Social Security Number is 123-45-6789, and his passport number is XK4598721, issued on March 12, 2018, expiring on March 11, 2028.
|
| 124 |
|
| 125 |
-
etabli une mise en demeure pour la personne concerné dans ce texte
|
| 126 |
""",
|
| 127 |
),
|
| 128 |
cl.Starter(
|
| 129 |
label="Example en Italien",
|
| 130 |
message="""Marco Alessandro Bianchi, nato il 12 febbraio 1989 a Milano (MI), Italia, è un cittadino italiano residente in Via Giuseppe Verdi 18, interno 7, 00198 Roma. Il suo numero di telefono cellulare è +39 347 582 9146, il telefono fisso è 06 8392 4751, e il suo indirizzo email personale è marco.bianchi1989@gmail.com
|
| 131 |
-
, mentre quello professionale è m.bianchi@italtechsolutions.it
|
| 132 |
-
. Il suo codice fiscale è BNCMRC89B12F205X e il numero di passaporto è YA3487291, rilasciato il 5 maggio 2019 con scadenza il 4 maggio 2029.
|
| 133 |
|
| 134 |
Extrait les information sous forme de tableau""",
|
| 135 |
),
|
| 136 |
cl.Starter(
|
| 137 |
label="Example en Espagnol",
|
| 138 |
message="""Carlos Javier Hernández López, nacido el 7 de julio de 1986 en Madrid (28015), España, es ciudadano español y reside en Calle Alcalá 233, piso 4ºB, 28028 Madrid. Su número de teléfono móvil es +34 612 845 739, el teléfono fijo es 91 458 2391, y su correo electrónico personal es carlos.hernandez1986@gmail.com
|
| 139 |
-
, mientras que el correo corporativo es c.hernandez@iberdata.es
|
| 140 |
-
. Su DNI es 48739215-M, y su número de pasaporte es PA7349821, expedido el 15 de abril de 2019 y válido hasta el 14 de abril de 2029.
|
| 141 |
|
| 142 |
Quelle est la personne concerné dans ce texte""",
|
| 143 |
),
|
| 144 |
cl.Starter(
|
| 145 |
label="Example en Allemand",
|
| 146 |
message="""Thomas Michael Schneider, geboren am 3. November 1984 in Hamburg (22085), Deutschland, ist deutscher Staatsbürger und wohnhaft in der Musterstraße 47, Wohnung 12, 80336 München. Seine Mobiltelefonnummer lautet +49 176 8345 2197, die Festnetznummer ist 089 4578 9321, und seine private E-Mail-Adresse ist thomas.schneider1984@gmail.com
|
| 147 |
-
, während er beruflich unter t.schneider@datafusion.de
|
| 148 |
-
erreichbar ist. Seine Steuer-Identifikationsnummer lautet 12 345 678 901, und seine Reisepassnummer ist C4X982731, ausgestellt am 22. August 2018, gültig bis 21. August 2028.
|
| 149 |
|
| 150 |
Resume moi le texte""",
|
| 151 |
)
|
|
@@ -238,6 +232,17 @@ async def format_document(pathfile, anonymized_text):
|
|
| 238 |
|
| 239 |
@cl.on_chat_start
|
| 240 |
async def start_chat():
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 241 |
return
|
| 242 |
|
| 243 |
client = Groq()
|
|
@@ -422,6 +427,7 @@ async def start_message(message: cl.Message):
|
|
| 422 |
await cl.Message("", elements=[element]).send()
|
| 423 |
# await message.remove()
|
| 424 |
|
|
|
|
| 425 |
cl.user_session.set("pii_map", updated_map)
|
| 426 |
cl.user_session.set("reverse_pii_map", reverse_map)
|
| 427 |
|
|
|
|
| 110 |
return [
|
| 111 |
cl.Starter(
|
| 112 |
label="Example en Français",
|
| 113 |
+
message="""Jean-Marc Durand, né le 14 avril 1987 à Lyon (69003), de nationalité française, est un ingénieur informatique marié à Sophie Martin depuis le 22 juin 2013. Il réside actuellement au 27 avenue des Lilas, appartement 42, 75019 Paris, France. Son numéro de téléphone personnel est le +33 6 48 72 19 05, son numéro de téléphone fixe est le 01 44 62 98 31, et son adresse e-mail principale est jeanmarc.durand1987@gmail.com. Il utilise également l’adresse professionnelle j.durand@techsoluce.fr.
|
|
|
|
|
|
|
| 114 |
Reformule ce texte""",
|
| 115 |
),
|
| 116 |
|
| 117 |
cl.Starter(
|
| 118 |
label="Example en Anglais",
|
| 119 |
message="""Michael Andrew Thompson, born on September 18, 1985, in Boston, Massachusetts (02118), USA, is a U.S. citizen currently living at 742 Evergreen Terrace, Apartment 5B, Brooklyn, New York, NY 11221. His mobile phone number is +1 (917) 555-3849, his home phone is +1 (718) 555-9021, and his primary email address is michael.thompson1985@gmail.com
|
| 120 |
+
, while his work email is m.thompson@fintechcore.com. His Social Security Number is 123-45-6789, and his passport number is XK4598721, issued on March 12, 2018, expiring on March 11, 2028.
|
|
|
|
| 121 |
|
| 122 |
+
etabli une mise en demeure pour la personne concerné dans ce texte.
|
| 123 |
""",
|
| 124 |
),
|
| 125 |
cl.Starter(
|
| 126 |
label="Example en Italien",
|
| 127 |
message="""Marco Alessandro Bianchi, nato il 12 febbraio 1989 a Milano (MI), Italia, è un cittadino italiano residente in Via Giuseppe Verdi 18, interno 7, 00198 Roma. Il suo numero di telefono cellulare è +39 347 582 9146, il telefono fisso è 06 8392 4751, e il suo indirizzo email personale è marco.bianchi1989@gmail.com
|
| 128 |
+
, mentre quello professionale è m.bianchi@italtechsolutions.it . Il suo codice fiscale è BNCMRC89B12F205X e il numero di passaporto è YA3487291, rilasciato il 5 maggio 2019 con scadenza il 4 maggio 2029.
|
|
|
|
| 129 |
|
| 130 |
Extrait les information sous forme de tableau""",
|
| 131 |
),
|
| 132 |
cl.Starter(
|
| 133 |
label="Example en Espagnol",
|
| 134 |
message="""Carlos Javier Hernández López, nacido el 7 de julio de 1986 en Madrid (28015), España, es ciudadano español y reside en Calle Alcalá 233, piso 4ºB, 28028 Madrid. Su número de teléfono móvil es +34 612 845 739, el teléfono fijo es 91 458 2391, y su correo electrónico personal es carlos.hernandez1986@gmail.com
|
| 135 |
+
, mientras que el correo corporativo es c.hernandez@iberdata.es . Su DNI es 48739215-M, y su número de pasaporte es PA7349821, expedido el 15 de abril de 2019 y válido hasta el 14 de abril de 2029.
|
|
|
|
| 136 |
|
| 137 |
Quelle est la personne concerné dans ce texte""",
|
| 138 |
),
|
| 139 |
cl.Starter(
|
| 140 |
label="Example en Allemand",
|
| 141 |
message="""Thomas Michael Schneider, geboren am 3. November 1984 in Hamburg (22085), Deutschland, ist deutscher Staatsbürger und wohnhaft in der Musterstraße 47, Wohnung 12, 80336 München. Seine Mobiltelefonnummer lautet +49 176 8345 2197, die Festnetznummer ist 089 4578 9321, und seine private E-Mail-Adresse ist thomas.schneider1984@gmail.com
|
| 142 |
+
, während er beruflich unter t.schneider@datafusion.de erreichbar ist. Seine Steuer-Identifikationsnummer lautet 12 345 678 901, und seine Reisepassnummer ist C4X982731, ausgestellt am 22. August 2018, gültig bis 21. August 2028.
|
|
|
|
| 143 |
|
| 144 |
Resume moi le texte""",
|
| 145 |
)
|
|
|
|
| 232 |
|
| 233 |
@cl.on_chat_start
|
| 234 |
async def start_chat():
|
| 235 |
+
# pii_map = cl.user_session.get("pii_map", {})
|
| 236 |
+
# reverse_map = cl.user_session.get("reverse_pii_map", {})
|
| 237 |
+
# text = """Thomas Michael Schneider, geboren am 3. November 1984 in Hamburg (22085), Deutschland, ist deutscher Staatsbürger und wohnhaft in der Musterstraße 47, Wohnung 12, 80336 München. Seine Mobiltelefonnummer lautet +49 176 8345 2197, die Festnetznummer ist 089 4578 9321, und seine private E-Mail-Adresse ist thomas.schneider1984@gmail.com
|
| 238 |
+
# , während er beruflich unter t.schneider@datafusion.de erreichbar ist. Seine Steuer-Identifikationsnummer lautet 12 345 678 901, und seine Reisepassnummer ist C4X982731, ausgestellt am 22. August 2018, gültig bis 21. August 2028.
|
| 239 |
+
|
| 240 |
+
# Resume moi le texte"""
|
| 241 |
+
# text_processed = await pii_gliner(text)
|
| 242 |
+
# text_sanitized, updated_map, reverse_map = pii_format(text_processed, pii_map, reverse_map)
|
| 243 |
+
|
| 244 |
+
# element = cl.CustomElement(name="UserMessage", props={"message": text_sanitized, "dic": reverse_map, "original": text, 'author':'user'})
|
| 245 |
+
# await cl.Message("", elements=[element]).send()
|
| 246 |
return
|
| 247 |
|
| 248 |
client = Groq()
|
|
|
|
| 427 |
await cl.Message("", elements=[element]).send()
|
| 428 |
# await message.remove()
|
| 429 |
|
| 430 |
+
|
| 431 |
cl.user_session.set("pii_map", updated_map)
|
| 432 |
cl.user_session.set("reverse_pii_map", reverse_map)
|
| 433 |
|
public/elements/UserMessage.jsx
CHANGED
|
@@ -62,10 +62,122 @@ function parseTable(lines, startIndex) {
|
|
| 62 |
}
|
| 63 |
|
| 64 |
export function Markdown({ children, dic, show }) {
|
|
|
|
|
|
|
|
|
|
|
|
|
| 65 |
const lines = children.split("\n")
|
| 66 |
const elements = []
|
| 67 |
let i = 0
|
| 68 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 69 |
while (i < lines.length) {
|
| 70 |
const line = lines[i]
|
| 71 |
|
|
@@ -133,7 +245,36 @@ export function Markdown({ children, dic, show }) {
|
|
| 133 |
i++
|
| 134 |
}
|
| 135 |
|
| 136 |
-
return
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 137 |
}
|
| 138 |
|
| 139 |
function parseInlineText(text) {
|
|
@@ -206,14 +347,21 @@ function renderInline(text, dic, show) {
|
|
| 206 |
) : (
|
| 207 |
<Tooltip key={index}>
|
| 208 |
<TooltipTrigger asChild>
|
| 209 |
-
<
|
| 210 |
-
{
|
| 211 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 212 |
</TooltipTrigger>
|
| 213 |
<TooltipContent>
|
| 214 |
<p>{dic[match[2]].value}</p>
|
| 215 |
</TooltipContent>
|
| 216 |
-
</Tooltip>
|
| 217 |
)
|
| 218 |
}
|
| 219 |
|
|
@@ -375,31 +523,7 @@ function MessageWithHighlight({ message, dic, show }) {
|
|
| 375 |
return (
|
| 376 |
<div className='flex flex-row-reverse w-full'>
|
| 377 |
<div onMouseUp={handleMouseUp} className="relative bg-accent rounded-3xl px-5 py-2.5 user-message flex-grow-0">
|
| 378 |
-
|
| 379 |
-
{parts.map((part, index) => {
|
| 380 |
-
// Check if part is [something]
|
| 381 |
-
const match = part.match(/^\[(\w+)_(.*?)\]$/);
|
| 382 |
-
|
| 383 |
-
if (match && dic[match[2]]) {
|
| 384 |
-
return (
|
| 385 |
-
show ? <Badge key={index} className="bg-pii text-blue-800 rounded-full px-2 py-1 mx-1 cursor-pointer">
|
| 386 |
-
{dic[match[2]].value}
|
| 387 |
-
</Badge> :
|
| 388 |
-
<Tooltip>
|
| 389 |
-
<TooltipTrigger asChild>
|
| 390 |
-
<button className=""><Badge key={index} className="bg-pii text-blue-800 rounded-sm px-1 py-1 mx-1 cursor-pointer">
|
| 391 |
-
{part.toUpperCase()}
|
| 392 |
-
</Badge></button>
|
| 393 |
-
</TooltipTrigger>
|
| 394 |
-
<TooltipContent>
|
| 395 |
-
<p>{dic[match[2]].value}</p>
|
| 396 |
-
</TooltipContent>
|
| 397 |
-
</Tooltip>
|
| 398 |
-
);
|
| 399 |
-
}
|
| 400 |
-
return <span key={index} data-index={index}>{part}</span>;
|
| 401 |
-
})}
|
| 402 |
-
</p>
|
| 403 |
|
| 404 |
<DropdownMenu open={open} onOpenChange={setOpen}>
|
| 405 |
<DropdownMenuTrigger asChild>
|
|
@@ -434,9 +558,9 @@ export default function UserMessage() {
|
|
| 434 |
<div className="flex flex-col gap-2">
|
| 435 |
{props.author == 'user' ? (
|
| 436 |
<div className='flex flex-row-reverse w-full'>
|
| 437 |
-
<div className="relative bg-accent rounded-3xl px-5 py-2.5 user-message flex-grow-0">
|
| 438 |
-
|
| 439 |
-
</div>
|
| 440 |
</div>
|
| 441 |
) : (
|
| 442 |
<Markdown dic={props.dic} show={show}>{props.message}</Markdown>
|
|
|
|
| 62 |
}
|
| 63 |
|
| 64 |
export function Markdown({ children, dic, show }) {
|
| 65 |
+
const [localMessage, setLocalMessage] = useState(children);
|
| 66 |
+
const [open, setOpen] = useState(false);
|
| 67 |
+
const [position, setPosition] = useState({ x: 0, y: 0 });
|
| 68 |
+
const [selectionData, setSelectionData] = useState(null);
|
| 69 |
const lines = children.split("\n")
|
| 70 |
const elements = []
|
| 71 |
let i = 0
|
| 72 |
|
| 73 |
+
const handleMouseUp = () => {
|
| 74 |
+
|
| 75 |
+
const selection = window.getSelection();
|
| 76 |
+
|
| 77 |
+
// 1. Check basic validity
|
| 78 |
+
if (!selection || selection.rangeCount === 0 || selection.isCollapsed) {
|
| 79 |
+
// If just a click (collapsed), we assume menu shouldn't open or should close
|
| 80 |
+
// But we don't want to close immediately if clicking inside the menu, handled by DropdownMenu logic
|
| 81 |
+
return;
|
| 82 |
+
}
|
| 83 |
+
|
| 84 |
+
// 2. Expand Selection to Word Boundaries
|
| 85 |
+
const anchorNode = selection.anchorNode;
|
| 86 |
+
const focusNode = selection.focusNode;
|
| 87 |
+
|
| 88 |
+
// Only support single text node selection for simplicity to map back to data-index
|
| 89 |
+
if (anchorNode !== focusNode || anchorNode.nodeType !== 3) {
|
| 90 |
+
setOpen(false);
|
| 91 |
+
return;
|
| 92 |
+
}
|
| 93 |
+
|
| 94 |
+
const textContent = anchorNode.textContent;
|
| 95 |
+
let start = Math.min(selection.anchorOffset, selection.focusOffset);
|
| 96 |
+
let end = Math.max(selection.anchorOffset, selection.focusOffset);
|
| 97 |
+
|
| 98 |
+
// Expand left
|
| 99 |
+
while (start > 0 && /\S/.test(textContent[start - 1])) {
|
| 100 |
+
start--;
|
| 101 |
+
}
|
| 102 |
+
// Expand right
|
| 103 |
+
while (end < textContent.length && /\S/.test(textContent[end])) {
|
| 104 |
+
end++;
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
+
// Update visual selection
|
| 108 |
+
const newRange = document.createRange();
|
| 109 |
+
newRange.setStart(anchorNode, start);
|
| 110 |
+
newRange.setEnd(anchorNode, end);
|
| 111 |
+
selection.removeAllRanges();
|
| 112 |
+
selection.addRange(newRange);
|
| 113 |
+
|
| 114 |
+
|
| 115 |
+
const newText = textContent.slice(start, end);
|
| 116 |
+
if (!newText.trim()) return;
|
| 117 |
+
|
| 118 |
+
// 3. Validation Logic
|
| 119 |
+
// Check 1: Less than 4 words
|
| 120 |
+
const words = newText.split(/\s+/);
|
| 121 |
+
if (words.length >= 4) {
|
| 122 |
+
setOpen(false);
|
| 123 |
+
return;
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
// Check 2: Does not contain highlighted word (brackets)
|
| 127 |
+
if (newText.includes('[') || newText.includes(']')) {
|
| 128 |
+
setOpen(false);
|
| 129 |
+
return;
|
| 130 |
+
}
|
| 131 |
+
|
| 132 |
+
// Check 3: Check if selection is inside a Badge
|
| 133 |
+
const parentElement = anchorNode.parentElement;
|
| 134 |
+
if (parentElement.closest('.bg-pii')) {
|
| 135 |
+
setOpen(false);
|
| 136 |
+
return;
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
// Identify Part Index
|
| 140 |
+
const partIndex = parseInt(parentElement.getAttribute('data-index'), 10);
|
| 141 |
+
// if (isNaN(partIndex)) {
|
| 142 |
+
// setOpen(false);
|
| 143 |
+
// return;
|
| 144 |
+
// }
|
| 145 |
+
|
| 146 |
+
const rect = newRange.getBoundingClientRect();
|
| 147 |
+
setPosition({
|
| 148 |
+
x: rect.left,
|
| 149 |
+
y: rect.bottom
|
| 150 |
+
});
|
| 151 |
+
setSelectionData({
|
| 152 |
+
partIndex,
|
| 153 |
+
start,
|
| 154 |
+
end,
|
| 155 |
+
text: newText
|
| 156 |
+
});
|
| 157 |
+
setOpen(true);
|
| 158 |
+
};
|
| 159 |
+
|
| 160 |
+
const handleAnonymize = () => {
|
| 161 |
+
if (!selectionData) return;
|
| 162 |
+
const { partIndex, start, end, text } = selectionData;
|
| 163 |
+
|
| 164 |
+
// Split by brackets to reconstruct parts array as seen in render
|
| 165 |
+
const parts = localMessage.split(/(\[[^\]]+\])/g);
|
| 166 |
+
|
| 167 |
+
if (parts[partIndex] === undefined) return;
|
| 168 |
+
|
| 169 |
+
const originalPart = parts[partIndex];
|
| 170 |
+
const newPart = originalPart.substring(0, start) + `[ANONYME_${text}]` + originalPart.substring(end);
|
| 171 |
+
|
| 172 |
+
parts[partIndex] = newPart;
|
| 173 |
+
const newMessage = parts.join('');
|
| 174 |
+
|
| 175 |
+
setLocalMessage(newMessage);
|
| 176 |
+
setOpen(false);
|
| 177 |
+
// Clear selection
|
| 178 |
+
window.getSelection().removeAllRanges();
|
| 179 |
+
};
|
| 180 |
+
|
| 181 |
while (i < lines.length) {
|
| 182 |
const line = lines[i]
|
| 183 |
|
|
|
|
| 245 |
i++
|
| 246 |
}
|
| 247 |
|
| 248 |
+
return (
|
| 249 |
+
<div onMouseUp={handleMouseUp}>
|
| 250 |
+
<div className="relative bg-accent rounded-3xl px-5 py-2.5 user-message flex-grow-0">
|
| 251 |
+
<p className="leading-[1.75] whitespace-pre-wrap">{elements}</p>
|
| 252 |
+
|
| 253 |
+
<DropdownMenu open={open} onOpenChange={setOpen}>
|
| 254 |
+
<DropdownMenuTrigger asChild>
|
| 255 |
+
<div
|
| 256 |
+
style={{
|
| 257 |
+
position: 'fixed',
|
| 258 |
+
top: position.y,
|
| 259 |
+
left: position.x,
|
| 260 |
+
width: '1px',
|
| 261 |
+
height: '1px',
|
| 262 |
+
visibility: 'hidden',
|
| 263 |
+
pointerEvents: 'none'
|
| 264 |
+
}}
|
| 265 |
+
/>
|
| 266 |
+
</DropdownMenuTrigger>
|
| 267 |
+
<DropdownMenuContent align="start">
|
| 268 |
+
<DropdownMenuGroup>
|
| 269 |
+
<DropdownMenuItem onSelect={handleAnonymize}>
|
| 270 |
+
Anonymiser
|
| 271 |
+
</DropdownMenuItem>
|
| 272 |
+
</DropdownMenuGroup>
|
| 273 |
+
</DropdownMenuContent>
|
| 274 |
+
</DropdownMenu>
|
| 275 |
+
</div>
|
| 276 |
+
</div>
|
| 277 |
+
)
|
| 278 |
}
|
| 279 |
|
| 280 |
function parseInlineText(text) {
|
|
|
|
| 347 |
) : (
|
| 348 |
<Tooltip key={index}>
|
| 349 |
<TooltipTrigger asChild>
|
| 350 |
+
<Badge
|
| 351 |
+
key={index}
|
| 352 |
+
className="bg-pii text-blue-800 rounded-full px-2 py-1 mx-1 blur-sm"
|
| 353 |
+
>
|
| 354 |
+
{dic[match[2]].value}
|
| 355 |
+
</Badge>
|
| 356 |
+
{/* <span className="bg-pii px-1 rounded cursor-pointer blur-sm">
|
| 357 |
+
{/* {part.toUpperCase()} */}
|
| 358 |
+
{/* {dic[match[2]].value} */}
|
| 359 |
+
{/* </span> */}
|
| 360 |
</TooltipTrigger>
|
| 361 |
<TooltipContent>
|
| 362 |
<p>{dic[match[2]].value}</p>
|
| 363 |
</TooltipContent>
|
| 364 |
+
</Tooltip >
|
| 365 |
)
|
| 366 |
}
|
| 367 |
|
|
|
|
| 523 |
return (
|
| 524 |
<div className='flex flex-row-reverse w-full'>
|
| 525 |
<div onMouseUp={handleMouseUp} className="relative bg-accent rounded-3xl px-5 py-2.5 user-message flex-grow-0">
|
| 526 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 527 |
|
| 528 |
<DropdownMenu open={open} onOpenChange={setOpen}>
|
| 529 |
<DropdownMenuTrigger asChild>
|
|
|
|
| 558 |
<div className="flex flex-col gap-2">
|
| 559 |
{props.author == 'user' ? (
|
| 560 |
<div className='flex flex-row-reverse w-full'>
|
| 561 |
+
{/* <div className="relative bg-accent rounded-3xl px-5 py-2.5 user-message flex-grow-0"> */}
|
| 562 |
+
<Markdown dic={props.dic} show={show}>{props.message}</Markdown>
|
| 563 |
+
{/* </div> */}
|
| 564 |
</div>
|
| 565 |
) : (
|
| 566 |
<Markdown dic={props.dic} show={show}>{props.message}</Markdown>
|