diff --git a/package.json b/package.json
index 278fcacce..378e3540f 100644
--- a/package.json
+++ b/package.json
@@ -17,7 +17,7 @@
"@emoji-mart/react": "^1.1.1",
"@emotion/react": "^11.13.3",
"@emotion/styled": "^11.13.0",
- "@glific/flow-editor": "^1.26.3-17",
+ "@glific/flow-editor": "^1.26.3-18",
"@lexical/react": "^0.17.1",
"@mui/icons-material": "^6.1.1",
"@mui/material": "^6.1.1",
diff --git a/src/assets/images/icons/Discord/DiscordIcon.tsx b/src/assets/images/icons/Discord/DiscordIcon.tsx
new file mode 100644
index 000000000..a6ca1edcb
--- /dev/null
+++ b/src/assets/images/icons/Discord/DiscordIcon.tsx
@@ -0,0 +1,14 @@
+const SvgComponent = ({ color }: any) => (
+
+ );
+ export default SvgComponent;
+
\ No newline at end of file
diff --git a/src/components/UI/ListIcon/ListIcon.tsx b/src/components/UI/ListIcon/ListIcon.tsx
index 27f909353..d99110857 100644
--- a/src/components/UI/ListIcon/ListIcon.tsx
+++ b/src/components/UI/ListIcon/ListIcon.tsx
@@ -32,7 +32,7 @@ import Assistant from 'assets/images/icons/SideDrawer/Assistant';
import styles from './ListIcon.module.css';
import FiberNewIcon from '@mui/icons-material/FiberNew';
import { Badge } from '@mui/material';
-
+import DiscordIcon from 'assets/images/icons/Discord/DiscordIcon'
export interface ListIconProps {
icon: string | undefined;
count?: number;
@@ -75,6 +75,7 @@ export const ListIcon = ({ icon = '', selected = false, count }: ListIconProps)
waGroup: WaGroupIcon,
knowledgeBase: KnowledgeBaseIcon,
assistant: Assistant,
+ discord:DiscordIcon
};
const iconImage = stringsToIcons[icon] && (
diff --git a/src/components/floweditor/FlowEditor.helper.ts b/src/components/floweditor/FlowEditor.helper.ts
index c510ba13a..87cf411cc 100644
--- a/src/components/floweditor/FlowEditor.helper.ts
+++ b/src/components/floweditor/FlowEditor.helper.ts
@@ -52,7 +52,8 @@ export const setConfig = (uuid: any, isTemplate: boolean) => {
simulateResume: false,
globals: `${glificBase}globals`,
groups: `${glificBase}groups`,
- fields: `${glificBase}fields`,
+ fields: `${glificBase}fields?scope=contact`,
+ waGroupFields: `${glificBase}fields?scope=wa_group`,
labels: `${glificBase}labels`,
channels: `${glificBase}channels`,
classifiers: `${glificBase}classifiers`,
@@ -98,6 +99,9 @@ export const setConfig = (uuid: any, isTemplate: boolean) => {
config.filters.push('ticketer');
}
+ if (services.whatsappGroupEnabled) {
+ config.filters.push('groups');
+ }
return config;
};
diff --git a/src/config/index.ts b/src/config/index.ts
index 674be5f80..3aa63e38e 100644
--- a/src/config/index.ts
+++ b/src/config/index.ts
@@ -53,8 +53,11 @@ export const ONBOARD_URL_UPDATE = `${GLIFIC_API_URL}/v1/onboard/update-registrat
export const ONBOARD_URL_REACT_OUT = `${GLIFIC_API_URL}/v1/onboard/reachout`;
export const ONBOARD_URL = `${GLIFIC_API_URL}/v1/onboard/setup`;
export const RECAPTCHA_CLIENT_KEY = envVariables.VITE_RECAPTCHA_CLIENT_KEY;
-export const UPLOAD_CONTACTS_SAMPLE = 'https://storage.googleapis.com/cc-tides/sample_contacts_import.csv';
-export const UPLOAD_CONTACTS_ADMIN_SAMPLE = 'https://storage.googleapis.com/cc-tides/sample_import_admin.csv';
+export const DISCORD_URL='https://discord.gg/kyqsZAJEPK';
+export const UPLOAD_CONTACTS_SAMPLE =
+ 'https://storage.googleapis.com/cc-tides/sample_contacts_import.csv';
+export const UPLOAD_CONTACTS_ADMIN_SAMPLE =
+ 'https://storage.googleapis.com/cc-tides/sample_import_admin.csv';
export const REGISTRATION_HELP_LINK =
'https://glific.slab.com/public/posts/02-managing-staff-members-creating-account-on-glific-gg6fkw8h';
export const CONTACT_MANAGE_HELP_LINK =
diff --git a/src/config/menu.ts b/src/config/menu.ts
index 3ca3334d2..24245f506 100644
--- a/src/config/menu.ts
+++ b/src/config/menu.ts
@@ -1,5 +1,5 @@
import { organizationHasDynamicRole } from 'common/utils';
-import { ANALYTICS_URL, GLIFIC_DOCS_URL } from 'config';
+import { ANALYTICS_URL, GLIFIC_DOCS_URL, DISCORD_URL } from 'config';
import { getOrganizationServices } from 'services/AuthService';
const allRoles = ['Staff', 'Manager', 'Admin', 'Dynamic', 'Glific_admin'];
@@ -279,14 +279,22 @@ const menus = (): Menu[] => [
roles: staffLevel,
},
- // {
- // title: "What's new",
- // path: '/changelog',
- // url: NEW_UI_BLOG,
- // icon: 'new',
- // type: 'sideDrawer',
- // roles: staffLevel,
- // },
+ // {
+ // title: "What's new",
+ // path: '/changelog',
+ // url: NEW_UI_BLOG,
+ // icon: 'new',
+ // type: 'sideDrawer',
+ // roles: staffLevel,
+ // },
+ {
+ title: "Discord",
+ path: '/discord',
+ url: DISCORD_URL,
+ icon: 'discord',
+ type: 'sideDrawer',
+ roles: staffLevel,
+ },
];
export const getMenus = (menuType = 'sideDrawer', role = 'Staff') =>
diff --git a/src/containers/List/List.module.css b/src/containers/List/List.module.css
index 36d76cad8..fc9b32761 100644
--- a/src/containers/List/List.module.css
+++ b/src/containers/List/List.module.css
@@ -274,6 +274,10 @@
background-color: #f8faf5;
}
+.FullHeight {
+ height: 100vh;
+}
+
.Checkbox {
min-width: 50px;
padding: 1rem;
diff --git a/src/containers/List/List.tsx b/src/containers/List/List.tsx
index 06367391e..54742b58e 100644
--- a/src/containers/List/List.tsx
+++ b/src/containers/List/List.tsx
@@ -790,7 +790,7 @@ export const List = ({
) : null;
return (
-
+
{showHeader && (
<>
diff --git a/src/containers/Profile/Contact/ContactDescription/ContactDescription.tsx b/src/containers/Profile/Contact/ContactDescription/ContactDescription.tsx
index 8c8fc0718..29e798c29 100644
--- a/src/containers/Profile/Contact/ContactDescription/ContactDescription.tsx
+++ b/src/containers/Profile/Contact/ContactDescription/ContactDescription.tsx
@@ -9,12 +9,14 @@ import styles from './ContactDescription.module.css';
export interface ContactDescriptionProps {
fields: any;
- settings: any;
- phone: string;
- maskedPhone: string;
+ settings?: any;
+ phone?: string;
+ maskedPhone?: string;
collections: any;
- lastMessage: string;
- statusMessage: string;
+ lastMessage?: string;
+ statusMessage?: string;
+ groups?: boolean;
+ customStyles?: string;
}
export const ContactDescription = ({
@@ -25,6 +27,8 @@ export const ContactDescription = ({
statusMessage,
fields,
settings,
+ groups = false,
+ customStyles,
}: ContactDescriptionProps) => {
const [showPlainPhone, setShowPlainPhone] = useState(false);
const { t } = useTranslation();
@@ -45,16 +49,19 @@ export const ContactDescription = ({
// list of collections that the contact belongs
const collectionList = collections.map((collection: any) => collection.label).join(', ');
- const collectionDetails = [
- { label: t('Collections'), value: collectionList || t('None') },
- {
- label: t('Assigned to'),
- value: assignedToCollection || t('None'),
- },
- ];
+ let collectionDetails = [{ label: t('Collections'), value: collectionList || t('None') }];
+ if (!groups) {
+ collectionDetails = [
+ ...collectionDetails,
+ {
+ label: t('Assigned to'),
+ value: assignedToCollection || t('None'),
+ },
+ ];
+ }
let settingsValue: any = '';
- if (typeof settings === 'string') {
+ if (settings && typeof settings === 'string') {
settingsValue = JSON.parse(settings);
}
@@ -106,23 +113,30 @@ export const ContactDescription = ({
);
}
- return (
-
-
-
- Number
-
-
- {phoneDisplay}
-
-
{t('Session Timer')}
-
+ const numberBlock = (
+ <>
+ {!groups && (
+ <>
+
+
+ Number
+
+
+ {phoneDisplay}
+
+ {t('Session Timer')}
+
+
+
-
-
-
-
+
+ >
+ )}
+ >
+ );
+ const collectionBlock = (
+ <>
{collectionDetails.map((collectionItem: any) => (
@@ -135,38 +149,65 @@ export const ContactDescription = ({
+ >
+ );
-
-
-
Status
-
{statusMessage}
-
-
- {settingsValue &&
- typeof settingsValue === 'object' &&
- Object.keys(settingsValue).map((key) => (
-
-
{key}
-
- {Object.keys(settingsValue[key])
- .filter((settingKey) => settingsValue[key][settingKey] === true)
- .join(', ')}
-
-
+ const settingsBlock = (
+ <>
+ {settingsValue &&
+ !groups &&
+ typeof settingsValue === 'object' &&
+ Object.keys(settingsValue).map((key) => (
+
+
{key}
+
+ {Object.keys(settingsValue[key])
+ .filter((settingKey) => settingsValue[key][settingKey] === true)
+ .join(', ')}
- ))}
- {fieldsValue &&
- typeof fieldsValue === 'object' &&
- Object.keys(fieldsValue).map((key) => (
-
-
- {fieldsValue[key].label ? fieldsValue[key].label : key.replace('_', ' ')}
-
-
{fieldsValue[key].value}
-
+
+
+ ))}
+ >
+ );
+
+ const statusBlock = (
+ <>
+ {!groups && (
+
+
+
Status
+
{statusMessage}
+
+
+
+ )}
+ >
+ );
+
+ const fieldsBlock = (
+
+ {fieldsValue &&
+ typeof fieldsValue === 'object' &&
+ Object.keys(fieldsValue).map((key) => (
+
+
+ {fieldsValue[key].label ? fieldsValue[key].label : key.replace('_', ' ')}
- ))}
-
+
{fieldsValue[key].value}
+
+
+ ))}
+
+ );
+
+ return (
+
+ {numberBlock}
+ {collectionBlock}
+ {settingsBlock}
+ {statusBlock}
+ {fieldsBlock}
);
};
diff --git a/src/containers/WaGroups/GroupDetails.tsx/GroupDetails.module.css b/src/containers/WaGroups/GroupDetails.tsx/GroupDetails.module.css
index f1cf10b2f..13327581a 100644
--- a/src/containers/WaGroups/GroupDetails.tsx/GroupDetails.module.css
+++ b/src/containers/WaGroups/GroupDetails.tsx/GroupDetails.module.css
@@ -65,3 +65,77 @@
padding: 2px 8px;
border-radius: 8px;
}
+
+.Container {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ background-color: #f8faf5;
+}
+
+.RightContainer {
+ height: 100%;
+ width: 100%;
+}
+
+.Drawer {
+ width: fit-content;
+ border-right: 1px solid #efefef;
+ height: calc(100vh - 110px) !important;
+}
+
+.Tab {
+ border-radius: 10px;
+ width: 200px;
+ height: 34px;
+ display: flex;
+ align-items: center;
+ margin: 2px 0;
+ padding: 0px !important;
+ font-weight: 400;
+ font-size: 14px;
+ color: #717971;
+ padding-left: 16px !important;
+}
+
+.Tab:hover {
+ background-color: #71797123;
+ cursor: pointer !important;
+}
+
+.ActiveTab {
+ font-weight: 700 !important;
+ color: #073f24 !important;
+ background-color: #cce6d0 !important;
+}
+
+.GroupHeader {
+ display: flex;
+ box-shadow: 0px 1px 1px 0px #00000029;
+ padding: 15px;
+ align-items: center;
+ gap: 1rem;
+}
+
+.GroupHeaderTitle {
+ font-size: 16px;
+ font-weight: 500;
+ color: #717971;
+ display: flex;
+ align-items: center;
+ gap: 10px;
+}
+
+.GroupHeaderElements {
+ padding: 0.5rem 1rem;
+}
+
+.Table {
+ display: flex;
+}
+
+.BackGround {
+ background-color: #f8faf5 !important;
+ width: 100%;
+ height: 100%;
+}
diff --git a/src/containers/WaGroups/GroupDetails.tsx/GroupDetails.tsx b/src/containers/WaGroups/GroupDetails.tsx/GroupDetails.tsx
index 4cd745d9c..e73cc46f1 100644
--- a/src/containers/WaGroups/GroupDetails.tsx/GroupDetails.tsx
+++ b/src/containers/WaGroups/GroupDetails.tsx/GroupDetails.tsx
@@ -1,16 +1,20 @@
+import { useMutation, useQuery } from '@apollo/client';
+import { useState } from 'react';
import { useParams } from 'react-router-dom';
-import { List } from 'containers/List/List';
import { useTranslation } from 'react-i18next';
+
import CollectionIcon from 'assets/images/icons/Collection/Dark.svg?react';
-import styles from './GroupDetails.module.css';
-import { UPDATE_GROUP_CONTACT } from 'graphql/mutations/Group';
-import { COUNT_COUNTACTS_WA_GROUPS, GET_WA_GROUP, LIST_CONTACTS_WA_GROUPS } from 'graphql/queries/WaGroups';
import DeleteIcon from 'assets/images/icons/Delete/Red.svg?react';
-import { useState } from 'react';
-import { useMutation, useQuery } from '@apollo/client';
import { setNotification } from 'common/notification';
import { DialogBox } from 'components/UI/DialogBox/DialogBox';
+import { Heading } from 'components/UI/Heading/Heading';
import { Loading } from 'components/UI/Layout/Loading/Loading';
+import { AvatarDisplay } from 'components/UI/AvatarDisplay/AvatarDisplay';
+import { List } from 'containers/List/List';
+import { ContactDescription } from 'containers/Profile/Contact/ContactDescription/ContactDescription';
+import { UPDATE_GROUP_CONTACT } from 'graphql/mutations/Group';
+import { COUNT_COUNTACTS_WA_GROUPS, GET_WA_GROUP, LIST_CONTACTS_WA_GROUPS } from 'graphql/queries/WaGroups';
+import styles from './GroupDetails.module.css';
export const GroupDetails = () => {
const params = useParams();
@@ -18,18 +22,24 @@ export const GroupDetails = () => {
const [showDeleteDialog, setShowDeleteDialog] = useState(false);
const [deleteVariables, setDeleteVariables] = useState
();
-
- const { loading: groupDataLoading, data: groupData } = useQuery(GET_WA_GROUP, {
- variables: {
- waGroupId: params.id,
- },
- });
+ const [contentToShow, setContentToShow] = useState('members');
const dialogTitle = 'Are you sure you want to remove this contact from the group?';
const dialogMessage = 'The contact will no longer receive messages sent to this group';
const columnNames = [{ label: t('Contact') }, { label: 'All WhatsApp Groups' }, { label: t('Actions') }];
+ const list = [
+ {
+ name: t('Members'),
+ section: 'members',
+ },
+ {
+ name: t('Details'),
+ section: 'details',
+ },
+ ];
+
const [removeContact, { loading }] = useMutation(UPDATE_GROUP_CONTACT, {
onCompleted: () => {
setNotification('Removed Contact from Group', 'success');
@@ -37,6 +47,14 @@ export const GroupDetails = () => {
},
});
+ const { loading: groupDataLoading, data } = useQuery(GET_WA_GROUP, {
+ variables: {
+ waGroupId: params.id,
+ },
+ });
+
+ const groupData = data?.waGroup?.waGroup;
+
const queries = {
countQuery: COUNT_COUNTACTS_WA_GROUPS,
filterItemsQuery: LIST_CONTACTS_WA_GROUPS,
@@ -138,17 +156,14 @@ export const GroupDetails = () => {
);
}
- if (groupDataLoading) {
- return ;
- }
-
- return (
- <>
+ let contentBody;
+ if (contentToShow === 'members') {
+ contentBody = (
{
{...queries}
{...columnAttributes}
showSearch={false}
+ showHeader={false}
+ customStyles={styles.Table}
+ />
+ );
+ } else {
+ contentBody = (
+
+ );
+ }
+
+ const drawer = (
+
+
+
+
+
{groupData?.label}
+
+
+ {list.map((data: any, index: number) => {
+ return (
+
setContentToShow(data.section)}
+ className={`${styles.Tab} ${contentToShow === data.section ? styles.ActiveTab : ''}`}
+ >
+ {data.name}
+
+ );
+ })}
+
+
+ );
+
+ if (groupDataLoading) {
+ return ;
+ }
+
+ return (
+ <>
+
+
+
+ {drawer}
+
{contentBody}
+
{dialog}
>
);
diff --git a/src/graphql/queries/WaGroups.ts b/src/graphql/queries/WaGroups.ts
index 8977f35f7..11727ffca 100644
--- a/src/graphql/queries/WaGroups.ts
+++ b/src/graphql/queries/WaGroups.ts
@@ -169,10 +169,18 @@ export const GET_WA_GROUP = gql`
id
lastCommunicationAt
bspId
+ fields
waManagedPhone {
phone
id
}
+ groups {
+ id
+ label
+ users {
+ name
+ }
+ }
}
}
}
diff --git a/src/i18n/en/en.json b/src/i18n/en/en.json
index 6d041df3c..99e5e250c 100644
--- a/src/i18n/en/en.json
+++ b/src/i18n/en/en.json
@@ -531,5 +531,6 @@
"Add files to file search": "Add files to file search",
"First name is required.": "First Name is required.",
"Last name is required.": "Last name is required.",
- "Failed": "Failed"
+ "Failed": "Failed",
+ "Members": "Members"
}
diff --git a/yarn.lock b/yarn.lock
index da6de02f3..b2f0ab3ab 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -652,10 +652,10 @@
resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.23.1.tgz#81fd50d11e2c32b2d6241470e3185b70c7b30699"
integrity sha512-BHpFFeslkWrXWyUPnbKm+xYYVYruCinGcftSBaa8zoF9hZO4BcSCFUvHVTtzpIY6YzUnYtuEhZ+C9iEXjxnasg==
-"@glific/flow-editor@^1.26.3-17":
- version "1.26.3-17"
- resolved "https://registry.yarnpkg.com/@glific/flow-editor/-/flow-editor-1.26.3-17.tgz#4b38c37f908345dc77459e3cce09aca7182d43d0"
- integrity sha512-438aIjOHmr2eE1icABebtKCh+g5Dd3FGlcs26PgtElu4mZVlJp+8T7wsU3N/B5Vvx5nkbL6RAMk7jxtVL9yCNQ==
+"@glific/flow-editor@^1.26.3-18":
+ version "1.26.3-18"
+ resolved "https://registry.yarnpkg.com/@glific/flow-editor/-/flow-editor-1.26.3-18.tgz#b00eb188bf1070903ae7d50a785d8ace76d97f35"
+ integrity sha512-DtC6LSkUqJg9Y1DlBvy9lVndd6raxTO9rSciec0X5wgVNxBnf7BoCJTA5wy3JkpY4jD3Xb9yPFUkz+1R/vFHcA==
dependencies:
react "^16.8.6"
react-dom "^16.8.6"