From 9488fc5ffb55fd7a6a750826c4507198ad64bd15 Mon Sep 17 00:00:00 2001 From: Chad Elliott Date: Fri, 14 Feb 2025 12:09:05 -0600 Subject: [PATCH 1/2] Search for names in kudos text and link any that are unambiguous. --- .../src/components/kudos/PublicKudosCard.jsx | 78 ++++++++++- .../components/kudos/PublicKudosCard.test.jsx | 117 ++++++++++++++++ .../PublicKudosCard.test.jsx.snap | 128 ++++++++++++++++++ 3 files changed, 322 insertions(+), 1 deletion(-) create mode 100644 web-ui/src/components/kudos/PublicKudosCard.test.jsx create mode 100644 web-ui/src/components/kudos/__snapshots__/PublicKudosCard.test.jsx.snap diff --git a/web-ui/src/components/kudos/PublicKudosCard.jsx b/web-ui/src/components/kudos/PublicKudosCard.jsx index dc554602d8..2ab878678f 100644 --- a/web-ui/src/components/kudos/PublicKudosCard.jsx +++ b/web-ui/src/components/kudos/PublicKudosCard.jsx @@ -17,6 +17,7 @@ import { DialogContentText, DialogActions, TextField, + Link, } from "@mui/material"; import { selectCsrfToken, selectProfile } from "../../context/selectors"; import { AppContext } from "../../context/AppContext"; @@ -51,6 +52,79 @@ const KudosCard = ({ kudos }) => { const sender = selectProfile(state, kudos.senderId); + const regexIndexOf = (text, regex, start) => { + const indexInSuffix = text.slice(start).search(regex); + return indexInSuffix < 0 ? indexInSuffix : indexInSuffix + start; + }; + + const linkMember = (member, name, message) => { + const components = []; + let index = 0; + do { + index = regexIndexOf(message, + new RegExp('\\b' + name + '\\b', 'i'), index); + if (index != -1) { + const link = + {name} + ; + if (index > 0) { + components.push(message.slice(0, index)); + } + components.push(link); + message = message.slice(index + name.length); + } + } while(index != -1); + components.push(message); + return components; + }; + + const searchNames = (member, members) => { + const names = []; + if (member.middleName) { + names.push(`${member.firstName} ${member.middleName} ${member.lastName}`); + } + const firstAndLast = `${member.firstName} ${member.lastName}`; + if (!members.some((k) => k.id != member.id && + firstAndLast != `${k.firstName} ${k.lastName}`)) { + names.push(firstAndLast); + } + if (!members.some((k) => k.id != member.id && + (member.lastName == k.lastName || + member.lastName == k.firstName))) { + // If there are no other recipients with a name that contains this + // member's last name, we can replace based on that. + names.push(member.lastName); + } + if (!members.some((k) => k.id != member.id && + (member.firstName == k.lastName || + member.firstName == k.firstName))) { + // If there are no other recipients with a name that contains this + // member's first name, we can replace based on that. + names.push(member.firstName); + } + return names; + }; + + const linkNames = (kudos) => { + const components = [ kudos.message ]; + for (let member of kudos.recipientMembers) { + const names = searchNames(member, kudos.recipientMembers); + for (let name of names) { + for (let i = 0; i < components.length; i++) { + const component = components[i]; + if (typeof(component) === "string") { + const built = linkMember(member, name, component); + if (built.length > 1) { + components.splice(i, 1, ...built); + } + } + } + } + } + return components; + }; + const getRecipientComponent = useCallback(() => { if (kudos.recipientTeam) { return ( @@ -98,7 +172,9 @@ const KudosCard = ({ kudos }) => { subheaderTypographyProps={{variant:"subtitle1"}} /> - {kudos.message} + + {linkNames(kudos)} + {kudos.recipientTeam && ( {kudos.recipientMembers.map((member) => ( diff --git a/web-ui/src/components/kudos/PublicKudosCard.test.jsx b/web-ui/src/components/kudos/PublicKudosCard.test.jsx new file mode 100644 index 0000000000..24215cf0c1 --- /dev/null +++ b/web-ui/src/components/kudos/PublicKudosCard.test.jsx @@ -0,0 +1,117 @@ +import React from 'react'; +import PublicKudosCard from './PublicKudosCard'; +import { AppContextProvider } from '../../context/AppContext'; + +const initialState = { + state: { + csrf: 'O_3eLX2-e05qpS_yOeg1ZVAs9nDhspEi', + teams: [], + userProfile: { + id: "1", + firstName: 'Jimmy', + lastName: 'Johnson', + role: ['MEMBER'], + }, + memberProfiles: [ + { + id: "1", + firstName: 'Jimmy', + lastName: 'Johnson', + role: ['MEMBER'], + }, + { + id: "2", + firstName: 'Jimmy', + lastName: 'Olsen', + role: ['MEMBER'], + }, + { + id: "3", + firstName: 'Clark', + lastName: 'Kent', + role: ['MEMBER'], + }, + { + id: "4", + firstName: 'Kent', + lastName: 'Brockman', + role: ['MEMBER'], + }, + { + id: "5", + firstName: 'Jerry', + lastName: 'Garcia', + role: ['MEMBER'], + }, + { + id: "6", + firstName: 'Brock', + lastName: 'Smith', + role: ['MEMBER'], + }, + { + id: "7", + firstName: 'Jimmy', + middleName: 'T.', + lastName: 'Olsen', + role: ['MEMBER'], + }, + ], + } +}; + +const kudos = { + id: 'test-kudos', + message: "Brock and Brockman did a great job helping Clark, Jimmy Olsen, Jimmy T. Olsen, and Johnson", + senderId: "5", + dateCreated: [ 2025, 2, 14 ], + recipientMembers: [ + { + id: "1", + firstName: 'Jimmy', + lastName: 'Johnson', + role: ['MEMBER'], + }, + { + id: "2", + firstName: 'Jimmy', + lastName: 'Olsen', + role: ['MEMBER'], + }, + { + id: "3", + firstName: 'Clark', + lastName: 'Kent', + role: ['MEMBER'], + }, + { + id: "6", + firstName: 'Brock', + lastName: 'Smith', + role: ['MEMBER'], + }, + { + id: "4", + firstName: 'Kent', + lastName: 'Brockman', + role: ['MEMBER'], + }, + { + id: "7", + firstName: 'Jimmy', + middleName: 'T.', + lastName: 'Olsen', + role: ['MEMBER'], + }, + ], +}; + +it('renders correctly', () => { + snapshot( + + + + ); +}); diff --git a/web-ui/src/components/kudos/__snapshots__/PublicKudosCard.test.jsx.snap b/web-ui/src/components/kudos/__snapshots__/PublicKudosCard.test.jsx.snap new file mode 100644 index 0000000000..bfbd6223c4 --- /dev/null +++ b/web-ui/src/components/kudos/__snapshots__/PublicKudosCard.test.jsx.snap @@ -0,0 +1,128 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`renders correctly 1`] = ` +
+
+
+
+
+
+ +3 +
+
+ +
+
+ +
+
+ +
+
+
+
+ + Kudos! + + + from +
+
+ +
+ +
+
+
+
+
+

+ + Brock + + and + + Brockman + + did a great job helping + + Clark + + , Jimmy Olsen, + + Jimmy T. Olsen + + , and + + Johnson + +

+
+
+
+`; From 32b36be1db945ba7de43d4b38a18f26a735294b5 Mon Sep 17 00:00:00 2001 From: Chad Elliott Date: Mon, 17 Feb 2025 09:48:02 -0600 Subject: [PATCH 2/2] Updated to have the tooltips. --- .../kudos/__snapshots__/PublicKudosCard.test.jsx.snap | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/web-ui/src/components/kudos/__snapshots__/PublicKudosCard.test.jsx.snap b/web-ui/src/components/kudos/__snapshots__/PublicKudosCard.test.jsx.snap index bfbd6223c4..1cc67a9fd2 100644 --- a/web-ui/src/components/kudos/__snapshots__/PublicKudosCard.test.jsx.snap +++ b/web-ui/src/components/kudos/__snapshots__/PublicKudosCard.test.jsx.snap @@ -17,7 +17,13 @@ exports[`renders correctly 1`] = `
- +3 +

+ +3 +