Skip to content

Commit 20556db

Browse files
authored
Merge pull request #2004 from Sandeep-FED/feat-listitemcomments-insights
feat[ListItemComments]: implement reaction insights
2 parents d449c59 + 4bb6dbe commit 20556db

File tree

4 files changed

+158
-7
lines changed

4 files changed

+158
-7
lines changed
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import * as React from 'react';
2+
import {
3+
DialogType,
4+
FontWeights,
5+
getTheme,
6+
IButtonStyles,
7+
IconButton,
8+
IIconProps,
9+
IStackProps,
10+
mergeStyleSets,
11+
Modal,
12+
Persona,
13+
PersonaSize,
14+
Stack,
15+
} from '@fluentui/react';
16+
import { AppContext } from '../../common';
17+
import { useListItemCommentsStyles } from './useListItemCommentsStyles';
18+
19+
interface ILikedUserListProps {
20+
isDialogOpen: boolean;
21+
setShowDialog: React.Dispatch<React.SetStateAction<boolean>>;
22+
likedBy: any;
23+
}
24+
25+
export const LikedUserList = ({
26+
isDialogOpen,
27+
setShowDialog,
28+
likedBy,
29+
}: ILikedUserListProps) => {
30+
const { iconButtonStyles, contentStyles } = useListItemCommentsStyles();
31+
32+
const PHOTO_URL = '/_layouts/15/userphoto.aspx?size=M&accountname=';
33+
34+
return (
35+
<Modal
36+
isOpen={isDialogOpen}
37+
onDismiss={() => setShowDialog(false)}
38+
styles={{ main: { width: '480px' } }}
39+
>
40+
<div className={contentStyles.header}>
41+
<h2 className={contentStyles.heading}>Liked by</h2>
42+
<IconButton
43+
styles={iconButtonStyles}
44+
iconProps={cancelIcon}
45+
ariaLabel="Close popup modal"
46+
onClick={() => setShowDialog(false)}
47+
/>
48+
</div>
49+
<Stack
50+
tokens={{ childrenGap: 12 }}
51+
style={{
52+
height: 'auto',
53+
maxHeight: '450px',
54+
overflowY: 'auto',
55+
padding: '0 1.5rem 1.5rem 1.5rem',
56+
}}
57+
>
58+
{likedBy.map((user: any, index: number) => (
59+
<>
60+
<Persona
61+
key={index}
62+
text={user.name}
63+
secondaryText={user.email}
64+
size={PersonaSize.size40}
65+
imageUrl={`${PHOTO_URL}${user.email}`}
66+
/>
67+
</>
68+
))}
69+
</Stack>
70+
</Modal>
71+
);
72+
};
73+
const cancelIcon: IIconProps = { iconName: 'Cancel' };

src/controls/listItemComments/components/Comments/RenderComments.tsx

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import {
55
} from '@fluentui/react/lib/DocumentCard';
66
import { Stack } from '@fluentui/react/lib/Stack';
77
import * as React from 'react';
8-
import { useCallback } from 'react';
8+
import { useCallback, useState } from 'react';
99
import { useContext } from 'react';
1010
import { ConfirmDelete } from '../ConfirmDelete/ConfirmDelete';
1111
import {
@@ -17,8 +17,9 @@ import { IComment } from './IComment';
1717
import { RenderSpinner } from './RenderSpinner';
1818
import { useListItemCommentsStyles } from './useListItemCommentsStyles';
1919
import { useBoolean } from '@fluentui/react-hooks';
20-
import { List, Text } from '@fluentui/react';
20+
import { Link, List, Text } from '@fluentui/react';
2121
import { AppContext, ECommentAction } from '../..';
22+
import { LikedUserList } from './LikedUserList';
2223

2324
export interface IRenderCommentsProps {}
2425

@@ -38,6 +39,8 @@ export const RenderComments: React.FunctionComponent<
3839
const { comments, isLoading } = listItemCommentsState;
3940

4041
const [hideDialog, { toggle: setHideDialog }] = useBoolean(true);
42+
const [showDialog, setShowDialog] = useState(false);
43+
const [selectedLikedBy, setSelectedLikedBy] = useState<any>([]);
4144

4245
const _likeComment = useCallback(() => {
4346
setlistItemCommentsState({
@@ -70,7 +73,19 @@ export const RenderComments: React.FunctionComponent<
7073
styles={buttonsContainerStyles}
7174
>
7275
<div style={{ display: 'flex', alignItems: 'center' }}>
73-
<Text>{comment.likeCount}</Text>
76+
{comment.likeCount > 0 ? (
77+
<Link
78+
onClick={() => {
79+
setSelectedLikedBy(comment.likedBy);
80+
setShowDialog(true);
81+
}}
82+
>
83+
{comment.likeCount}
84+
</Link>
85+
) : (
86+
<Text>{comment.likeCount}</Text>
87+
)}
88+
7489
<IconButton
7590
iconProps={{
7691
iconName: `${comment.isLikedByUser ? 'LikeSolid' : 'Like'}`,
@@ -136,6 +151,11 @@ export const RenderComments: React.FunctionComponent<
136151
setHideDialog();
137152
}}
138153
/>
154+
<LikedUserList
155+
isDialogOpen={showDialog}
156+
setShowDialog={setShowDialog}
157+
likedBy={selectedLikedBy}
158+
/>
139159
</>
140160
);
141161
};

src/controls/listItemComments/components/Comments/useListItemCommentsStyles.ts

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@ import * as React from "react";
22
import { IDocumentCardStyles } from "@fluentui/react/lib/DocumentCard";
33
import { IStackStyles } from "@fluentui/react/lib/Stack";
44
import {
5+
FontWeights,
6+
getTheme,
57
IStyle,
68
mergeStyles,
79
mergeStyleSets,
8-
} from "@fluentui/react/lib/Styling";
9-
import { AppContext } from "../../common";
10-
import { TILE_HEIGHT } from "../../common/constants";
10+
} from '@fluentui/react/lib/Styling';
11+
import { AppContext } from '../../common';
12+
import { TILE_HEIGHT } from '../../common/constants';
13+
import { IButtonStyles } from '@fluentui/react';
1114

1215
interface returnObjectStyles {
1316
itemContainerStyles: IStackStyles;
@@ -19,10 +22,14 @@ interface returnObjectStyles {
1922
documentCardHighlightedStyles: Partial<IDocumentCardStyles>;
2023
documentCardUserStyles: Partial<IDocumentCardStyles>;
2124
configurationListClasses: any; // eslint-disable-line @typescript-eslint/no-explicit-any
25+
contentStyles: any; // eslint-disable-line @typescript-eslint/no-explicit-any
26+
iconButtonStyles: Partial<IButtonStyles>;
2227
}
2328

2429
export const useListItemCommentsStyles = (): returnObjectStyles => {
2530
const { theme, numberCommentsPerPage } = React.useContext(AppContext);
31+
const fluentTheme = getTheme();
32+
2633
// Calc Height List tiles Container Based on number Items per Page
2734
const tilesHeight: number = numberCommentsPerPage
2835
? (numberCommentsPerPage < 5 ? 5 : numberCommentsPerPage) * TILE_HEIGHT + 35
@@ -140,6 +147,55 @@ export const useListItemCommentsStyles = (): returnObjectStyles => {
140147
} as IStyle,
141148
});
142149

150+
const contentStyles = mergeStyleSets({
151+
container: {
152+
display: 'flex',
153+
flexFlow: 'column nowrap',
154+
alignItems: 'stretch',
155+
},
156+
header: [
157+
// eslint-disable-next-line @typescript-eslint/no-deprecated
158+
fluentTheme.fonts.xLargePlus,
159+
{
160+
flex: '1 1 auto',
161+
borderTop: `4px solid ${theme.themePrimary}`,
162+
color: theme.neutralPrimary,
163+
display: 'flex',
164+
alignItems: 'center',
165+
fontWeight: FontWeights.semibold,
166+
padding: '12px 12px 14px 24px',
167+
},
168+
],
169+
heading: {
170+
color: theme.neutralPrimary,
171+
fontWeight: FontWeights.semibold,
172+
fontSize: 'inherit',
173+
margin: '0',
174+
},
175+
body: {
176+
flex: '4 4 auto',
177+
padding: '0 24px 24px 24px',
178+
overflowY: 'hidden',
179+
selectors: {
180+
p: { margin: '14px 0' },
181+
'p:first-child': { marginTop: 0 },
182+
'p:last-child': { marginBottom: 0 },
183+
},
184+
},
185+
});
186+
187+
const iconButtonStyles: Partial<IButtonStyles> = {
188+
root: {
189+
color: theme.neutralPrimary,
190+
marginLeft: 'auto',
191+
marginTop: '4px',
192+
marginRight: '2px',
193+
},
194+
rootHovered: {
195+
color: theme.neutralDark,
196+
},
197+
};
198+
143199
return {
144200
itemContainerStyles,
145201
buttonsContainerStyles,
@@ -150,5 +206,7 @@ export const useListItemCommentsStyles = (): returnObjectStyles => {
150206
documentCardHighlightedStyles,
151207
documentCardUserStyles,
152208
configurationListClasses,
209+
contentStyles,
210+
iconButtonStyles,
153211
};
154212
};

src/controls/listItemComments/hooks/useSpAPI.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ export const useSpAPI = (): returnObject => {
120120
webUrl ?? _webUrl
121121
}/_api/web/lists(@a1)/GetItemById(@a2)/GetComments()?@a1='${listId}'&@a2='${itemId}'&$top=${
122122
numberCommentsPerPage ?? 10
123-
}`;
123+
}&$expand=likedBy`;
124124
const _listResults: SPHttpClientResponse = await spHttpClient.get(
125125
`${_endPointUrl}`,
126126
SPHttpClient.configurations.v1

0 commit comments

Comments
 (0)