Skip to content

Commit 9193bcf

Browse files
authored
Merge pull request #3185 from glific/feat/wa_polls
WA Polls: Create and manage polls
2 parents 6d381d2 + c247dd1 commit 9193bcf

File tree

34 files changed

+1534
-83
lines changed

34 files changed

+1534
-83
lines changed

src/assets/images/Polls.svg

+6
Loading

src/assets/images/icons/Poll.svg

+3
Loading
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
const SvgComponent = ({ color }: { color: string }) => (
2+
<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
3+
<path
4+
d="M13 7C13.2833 7 13.5208 6.90417 13.7125 6.7125C13.9042 6.52083 14 6.28333 14 6C14 5.71667 13.9042 5.47917 13.7125 5.2875C13.5208 5.09583 13.2833 5 13 5H10C9.71667 5 9.47917 5.09583 9.2875 5.2875C9.09583 5.47917 9 5.71667 9 6C9 6.28333 9.09583 6.52083 9.2875 6.7125C9.47917 6.90417 9.71667 7 10 7H13ZM13 13C13.2833 13 13.5208 12.9042 13.7125 12.7125C13.9042 12.5208 14 12.2833 14 12C14 11.7167 13.9042 11.4792 13.7125 11.2875C13.5208 11.0958 13.2833 11 13 11H10C9.71667 11 9.47917 11.0958 9.2875 11.2875C9.09583 11.4792 9 11.7167 9 12C9 12.2833 9.09583 12.5208 9.2875 12.7125C9.47917 12.9042 9.71667 13 10 13H13ZM6 8C6.55 8 7.02083 7.80417 7.4125 7.4125C7.80417 7.02083 8 6.55 8 6C8 5.45 7.80417 4.97917 7.4125 4.5875C7.02083 4.19583 6.55 4 6 4C5.45 4 4.97917 4.19583 4.5875 4.5875C4.19583 4.97917 4 5.45 4 6C4 6.55 4.19583 7.02083 4.5875 7.4125C4.97917 7.80417 5.45 8 6 8ZM6 14C6.55 14 7.02083 13.8042 7.4125 13.4125C7.80417 13.0208 8 12.55 8 12C8 11.45 7.80417 10.9792 7.4125 10.5875C7.02083 10.1958 6.55 10 6 10C5.45 10 4.97917 10.1958 4.5875 10.5875C4.19583 10.9792 4 11.45 4 12C4 12.55 4.19583 13.0208 4.5875 13.4125C4.97917 13.8042 5.45 14 6 14ZM2 18C1.45 18 0.979167 17.8042 0.5875 17.4125C0.195833 17.0208 0 16.55 0 16V2C0 1.45 0.195833 0.979167 0.5875 0.5875C0.979167 0.195833 1.45 0 2 0H16C16.55 0 17.0208 0.195833 17.4125 0.5875C17.8042 0.979167 18 1.45 18 2V16C18 16.55 17.8042 17.0208 17.4125 17.4125C17.0208 17.8042 16.55 18 16 18H2ZM2 16H16V2H2V16Z"
5+
fill={color}
6+
/>
7+
</svg>
8+
);
9+
export default SvgComponent;

src/common/HelpData.tsx

+5
Original file line numberDiff line numberDiff line change
@@ -129,3 +129,8 @@ export const templateStatusInfo: HelpDataProps = {
129129
),
130130
link: 'https://docs.gupshup.io/docs/message-template-approvals-statuses',
131131
};
132+
133+
export const pollsInfo: HelpDataProps = {
134+
heading: 'An overview of all the polls created to date',
135+
link: 'https://glific.github.io/docs/docs/WhatsApp%20Groups%20Automation/Sending%20Polls%20To%20WhatsApp%20Groups',
136+
};

src/components/UI/ListIcon/ListIcon.tsx

+2
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import WaChatIcon from 'assets/images/icons/SideDrawer/WaGroupChat';
2828
import WaCollectionIcon from 'assets/images/icons/SideDrawer/WaGroupCollection';
2929
import WaGroupIcon from 'assets/images/icons/SideDrawer/WhatsAppGroupIcon';
3030
import Assistant from 'assets/images/icons/SideDrawer/Assistant';
31+
import WaPolls from 'assets/images/icons/SideDrawer/WaPolls';
3132
import styles from './ListIcon.module.css';
3233
import FiberNewIcon from '@mui/icons-material/FiberNew';
3334
import { Badge } from '@mui/material';
@@ -74,6 +75,7 @@ export const ListIcon = ({ icon = '', selected = false, count }: ListIconProps)
7475
waGroup: WaGroupIcon,
7576
assistant: Assistant,
7677
discord: DiscordIcon,
78+
waPolls: WaPolls,
7779
};
7880

7981
const iconImage = stringsToIcons[icon] && (

src/components/simulator/Simulator.module.css

+1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
background: white;
3030
width: 200px;
3131
margin-top: 4px;
32+
overflow-x: hidden;
3233
}
3334

3435
.StickerReceivedMessage {

src/components/simulator/Simulator.tsx

+38-18
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ import styles from './Simulator.module.css';
5252
import { LocationRequestTemplate } from 'containers/Chat/ChatMessages/ChatMessage/LocationRequestTemplate/LocationRequestTemplate';
5353
import { BackdropLoader } from 'containers/Flow/FlowTranslation';
5454
import { SIMULATOR_RELEASE_SUBSCRIPTION } from 'graphql/subscriptions/PeriodicInfo';
55+
import { PollMessage } from 'containers/Chat/ChatMessages/ChatMessage/PollMessage/PollMessage';
5556

5657
export interface SimulatorProps {
5758
setShowSimulator?: any;
@@ -63,6 +64,7 @@ export interface SimulatorProps {
6364
interactiveMessage?: any;
6465
showHeader?: boolean;
6566
hasResetButton?: boolean;
67+
pollContent?: any;
6668
}
6769

6870
interface Sender {
@@ -124,6 +126,7 @@ const Simulator = ({
124126
interactiveMessage,
125127
showHeader = true,
126128
hasResetButton = false,
129+
pollContent,
127130
}: SimulatorProps) => {
128131
const [inputMessage, setInputMessage] = useState('');
129132
const [simulatedMessages, setSimulatedMessage] = useState<any>();
@@ -268,7 +271,13 @@ const Simulator = ({
268271
});
269272
};
270273

271-
const renderMessage = (messageObject: any, direction: string, index: number, isInteractive: boolean = false) => {
274+
const renderMessage = (
275+
messageObject: any,
276+
direction: string,
277+
index: number,
278+
isInteractive: boolean,
279+
isPollContent: boolean = false
280+
) => {
272281
const { insertedAt, type, media, location, interactiveContent, bspMessageId, templateType } = messageObject;
273282

274283
const messageType = isInteractive ? templateType : type;
@@ -320,26 +329,31 @@ const Simulator = ({
320329
}
321330
}
322331

332+
let messageBody: any = (
333+
<>
334+
<ChatMessageType
335+
type={messageType}
336+
media={media}
337+
body={body}
338+
location={location}
339+
isSimulatedMessage={isSimulatedMessage}
340+
/>
341+
<TimeComponent direction={direction} insertedAt={insertedAt} />
342+
</>
343+
);
344+
if (isInteractiveContentPresent && direction !== 'send') {
345+
messageBody = template;
346+
} else if (isPollContent) {
347+
messageBody = <PollMessage pollContent={pollContent} isSimulator />;
348+
}
349+
323350
return (
324351
<div key={index}>
325352
<div
326353
className={getStyleForDirection(direction, isInteractiveContentPresent, messageType)}
327354
data-testid="simulatorMessage"
328355
>
329-
{isInteractiveContentPresent && direction !== 'send' ? (
330-
template
331-
) : (
332-
<>
333-
<ChatMessageType
334-
type={messageType}
335-
media={media}
336-
body={body}
337-
location={location}
338-
isSimulatedMessage={isSimulatedMessage}
339-
/>
340-
<TimeComponent direction={direction} insertedAt={insertedAt} />
341-
</>
342-
)}
356+
{messageBody}
343357
</div>
344358
<div className={styles.TemplateButtons}>
345359
<TemplateButtons
@@ -356,17 +370,17 @@ const Simulator = ({
356370
const chatMessage = messages
357371
.map((simulatorMessage: any, index: number) => {
358372
if (simulatorMessage.receiver.id === simulatorId) {
359-
return renderMessage(simulatorMessage, 'received', index);
373+
return renderMessage(simulatorMessage, 'received', index, false);
360374
}
361-
return renderMessage(simulatorMessage, 'send', index);
375+
return renderMessage(simulatorMessage, 'send', index, false);
362376
})
363377
.reverse();
364378
setSimulatedMessage(chatMessage);
365379
};
366380

367381
const getPreviewMessage = () => {
368382
if (message && message.type) {
369-
const previewMessage = renderMessage(message, 'received', 0);
383+
const previewMessage = renderMessage(message, 'received', 0, false);
370384
if (['STICKER', 'AUDIO'].includes(message.type)) {
371385
setSimulatedMessage(previewMessage);
372386
} else if (message.body || message.media?.caption) {
@@ -380,6 +394,7 @@ const Simulator = ({
380394
if (interactiveMessage) {
381395
const { templateType, interactiveContent } = interactiveMessage;
382396
const previewMessage = renderMessage(interactiveMessage, 'received', 0, true);
397+
383398
setSimulatedMessage(previewMessage);
384399
if (templateType === LIST) {
385400
const { items } = JSON.parse(interactiveContent);
@@ -388,6 +403,11 @@ const Simulator = ({
388403
setIsDrawerOpen(false);
389404
}
390405
}
406+
407+
if (pollContent) {
408+
const previewMessage = renderMessage(pollContent, 'received', 0, false, true);
409+
setSimulatedMessage(previewMessage);
410+
}
391411
};
392412

393413
useEffect(() => {

src/config/menu.ts

+7
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ const menus = (): Menu[] => [
5151
type: 'sideDrawer',
5252
roles: allRoles,
5353
},
54+
{
55+
title: 'Group Polls',
56+
path: '/group/polls',
57+
icon: 'waPolls',
58+
type: 'sideDrawer',
59+
roles: allRoles,
60+
},
5461
],
5562
},
5663
{

src/containers/Chat/ChatConversations/MessageType/MessageType.tsx

+3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import AudioIconDark from 'assets/images/icons/Audio/Dark.svg?react';
1010
import DocumentIconDark from 'assets/images/icons/Document/Dark.svg?react';
1111
import StickerIconDark from 'assets/images/icons/Sticker/Dark.svg?react';
1212
import LocationIconDark from 'assets/images/icons/Location/Dark.svg?react';
13+
import PollIcon from 'assets/images/icons/Poll.svg?react';
1314

1415
import styles from './MessageType.module.css';
1516

@@ -26,6 +27,7 @@ const lightIcons: any = {
2627
DOCUMENT: <DocumentIcon />,
2728
STICKER: <StickerIcon />,
2829
LOCATION: <LocationIcon />,
30+
POLL: <PollIcon />,
2931
};
3032

3133
const darkIcons: any = {
@@ -51,6 +53,7 @@ export const MessageType = ({ type, body = '', color = 'light' }: MessageTypePro
5153
QUICK_REPLY: 'Quick Reply',
5254
LIST: 'List',
5355
LOCATION_REQUEST_MESSAGE: 'Location Request',
56+
POLL: body,
5457
};
5558

5659
const option = (

src/containers/Chat/ChatMessages/ChatMessage/ChatMessage.module.css

+5
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@
150150
.Inline {
151151
display: flex;
152152
}
153+
153154
.SendBy {
154155
display: flex;
155156
align-items: flex-end;
@@ -298,3 +299,7 @@
298299
padding-bottom: 8px;
299300
font-weight: bold;
300301
}
302+
303+
.NoIcon {
304+
margin: 0 1rem;
305+
}

0 commit comments

Comments
 (0)