diff --git a/package.json b/package.json index f009d84f0..1fbf0c207 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "glific-frontend", - "version": "1.2.1", + "version": "1.3.0", "private": true, "dependencies": { "@absinthe/socket": "^0.2.1", diff --git a/src/common/utils.ts b/src/common/utils.ts index efcad60c3..91bd5a261 100644 --- a/src/common/utils.ts +++ b/src/common/utils.ts @@ -60,3 +60,10 @@ export const copyToClipboardMethod = (client: any, text: string) => { }; export { copyToClipboardMethod as copyToClipboard }; + +export const addLogsMethod = (event: string, logData: any) => { + setLogs(event, 'info'); + setLogs(`variables-${logData}`, 'info'); +}; + +export { addLogsMethod as addLogs }; diff --git a/src/containers/BlockContact/BlockContactList/BlockContactList.tsx b/src/containers/BlockContact/BlockContactList/BlockContactList.tsx index 21b7e7322..1e3b5c1cf 100644 --- a/src/containers/BlockContact/BlockContactList/BlockContactList.tsx +++ b/src/containers/BlockContact/BlockContactList/BlockContactList.tsx @@ -11,6 +11,7 @@ import { SEARCH_QUERY_VARIABLES } from '../../../common/constants'; import { CONTACT_SEARCH_QUERY, GET_CONTACT_COUNT } from '../../../graphql/queries/Contact'; import { DELETE_CONTACT, UPDATE_CONTACT } from '../../../graphql/mutations/Contact'; import { SEARCH_QUERY } from '../../../graphql/queries/Search'; +import { addLogs } from '../../../common/utils'; export interface BlockContactListProps {} @@ -76,13 +77,17 @@ export const BlockContactList: React.SFC = () => { }; const handleUnblock = () => { - unblockContact({ - variables: { - id: contactId, - input: { - status: 'VALID', - }, + const variables = { + id: contactId, + input: { + status: 'VALID', }, + }; + + addLogs(`Unblock contact-${contactId}`, variables); + + unblockContact({ + variables, }); }; diff --git a/src/containers/Chat/Chat.test.tsx b/src/containers/Chat/Chat.test.tsx index 854d6321d..ccdf07d9e 100644 --- a/src/containers/Chat/Chat.test.tsx +++ b/src/containers/Chat/Chat.test.tsx @@ -109,7 +109,9 @@ describe('', () => { }); test('check condition when no subscription data provided', async () => { - const { findByTestId } = render(wrapper); + const { getByText, findByTestId } = render(wrapper); + + expect(getByText('Loading...')).toBeInTheDocument(); const ChatConversation = await findByTestId('beneficiaryName'); expect(ChatConversation).toHaveTextContent('Effie Cormier'); diff --git a/src/containers/Chat/ChatConversations/ConversationList/ConversationList.tsx b/src/containers/Chat/ChatConversations/ConversationList/ConversationList.tsx index 7770539dc..f522949c2 100644 --- a/src/containers/Chat/ChatConversations/ConversationList/ConversationList.tsx +++ b/src/containers/Chat/ChatConversations/ConversationList/ConversationList.tsx @@ -23,6 +23,7 @@ import { } from '../../../../common/constants'; import { updateConversations } from '../../../../services/ChatService'; import { showMessages } from '../../../../common/responsive'; +import { addLogs } from '../../../../common/utils'; interface ConversationListProps { searchVal: string; @@ -214,12 +215,14 @@ export const ConversationList: React.SFC = (props) => { useEffect(() => { // Use multi search when has search value and when there is no collection id if (searchVal && Object.keys(searchParam).length === 0 && !selectedCollectionId) { + addLogs(`Use multi search when has search value`, filterSearch()); getFilterSearch({ variables: filterSearch(), }); } else { // This is used for filtering the searches, when you click on it, so only call it // when user clicks and savedSearchCriteriaId is set. + addLogs(`filtering the searches`, filterVariables()); getFilterConvos({ variables: filterVariables(), }); diff --git a/src/containers/Chat/ChatMessages/ChatMessages.test.tsx b/src/containers/Chat/ChatMessages/ChatMessages.test.tsx index a0be9917f..c9c800a44 100644 --- a/src/containers/Chat/ChatMessages/ChatMessages.test.tsx +++ b/src/containers/Chat/ChatMessages/ChatMessages.test.tsx @@ -295,3 +295,68 @@ test('Collection: if cache', async () => { fireEvent.click(getByTestId('jumpToLatest')); }); }); + +test('click on Clear conversation', async () => { + const chatMessages = ( + + + + ); + const { getByTestId } = render(chatMessages); + await waitFor(() => { + fireEvent.click(getByTestId('dropdownIcon')); + fireEvent.click(getByTestId('clearChatButton')); + // need to check this + // fireEvent.click(getByTestId('ok-button')); + // expect(getByTestId('app')).toHaveTextContent('Conversation cleared for this contact'); + }); +}); + +test('Load more messages', async () => { + const searchQuery = { + query: SEARCH_QUERY, + variables: { + filter: {}, + contactOpts: { limit: DEFAULT_CONTACT_LIMIT }, + messageOpts: { limit: DEFAULT_MESSAGE_LIMIT }, + }, + data: { + search: [ + { + group: null, + contact: { + id: '2', + name: 'Effie Cormier', + phone: '987654321', + maskedPhone: '98****321', + lastMessageAt: '2020-06-29T09:31:47Z', + status: 'VALID', + bspStatus: 'SESSION_AND_HSM', + isOrgRead: true, + }, + messages: new Array(20).fill(body), + }, + ], + }, + }; + + cache.writeQuery(searchQuery); + const client = new ApolloClient({ + cache: cache, + assumeImmutableResults: true, + }); + + const chatMessages = ( + + + + ); + + const { getByTestId } = render(chatMessages); + + await waitFor(() => { + const container: any = document.querySelector('.messageContainer'); + fireEvent.scroll(container, { target: { scrollY: 0 } }); + fireEvent.click(getByTestId('loadMoreMessages')); + }); +}); diff --git a/src/containers/Chat/ChatMessages/ChatMessages.tsx b/src/containers/Chat/ChatMessages/ChatMessages.tsx index 775bdfbe7..9868d9435 100644 --- a/src/containers/Chat/ChatMessages/ChatMessages.tsx +++ b/src/containers/Chat/ChatMessages/ChatMessages.tsx @@ -30,6 +30,8 @@ import { import { FILTER_TAGS_NAME } from '../../../graphql/queries/Tag'; import { ReactComponent as TagIcon } from '../../../assets/images/icons/Tags/Selected.svg'; import { getCachedConverations, updateConversationsCache } from '../../../services/ChatService'; +import { addLogs } from '../../../common/utils'; +import { CollectionInformation } from '../../Collection/CollectionInformation/CollectionInformation'; export interface ChatMessagesProps { contactId?: number | string | null; @@ -57,7 +59,7 @@ export const ChatMessages: React.SFC = ({ contactId, collecti } const [editTagsMessageId, setEditTagsMessageId] = useState(null); - const [dialog, setDialogbox] = useState(false); + const [dialog, setDialogbox] = useState(); const [selectedMessageTags, setSelectedMessageTags] = useState(null); const [previousMessageTags, setPreviousMessageTags] = useState(null); const [showDropdown, setShowDropdown] = useState(null); @@ -67,6 +69,8 @@ export const ChatMessages: React.SFC = ({ contactId, collecti const [showJumpToLatest, setShowJumpToLatest] = useState(true); const [defaultJumpToLatest, setDefaultShowJumpToLatest] = useState(true); const [conversationInfo, setConversationInfo] = useState({}); + const [collectionVariables, setCollectionVariables] = useState({}); + let dialogBox; useEffect(() => { setShowLoadMore(true); @@ -251,7 +255,7 @@ export const ChatMessages: React.SFC = ({ contactId, collecti const [createMessageTag] = useMutation(UPDATE_MESSAGE_TAGS, { onCompleted: () => { setNotification(client, 'Tags added successfully'); - setDialogbox(false); + setDialogbox(''); }, }); @@ -270,6 +274,13 @@ export const ChatMessages: React.SFC = ({ contactId, collecti return payloadCopy; }; + const handleSendMessage = () => { + setDialogbox(''); + sendMessageToCollection({ + variables: collectionVariables, + }); + }; + // this function is called when the message is sent collection const sendCollectionMessageHandler = ( body: string, @@ -278,6 +289,9 @@ export const ChatMessages: React.SFC = ({ contactId, collecti selectedTemplate: any, variableParam: any ) => { + // display collection info popup + setDialogbox('collection'); + const payload: any = { body, senderId: 1, @@ -286,11 +300,16 @@ export const ChatMessages: React.SFC = ({ contactId, collecti flow: 'OUTBOUND', }; - sendMessageToCollection({ - variables: { - groupId: collectionId, - input: updatePayload(payload, selectedTemplate, variableParam), - }, + const variables = { + groupId: collectionId, + input: updatePayload(payload, selectedTemplate, variableParam), + }; + + addLogs(`send Message To Collection-${collectionId}`, variables); + + setCollectionVariables({ + groupId: collectionId, + input: updatePayload(payload, selectedTemplate, variableParam), }); }; @@ -354,21 +373,32 @@ export const ChatMessages: React.SFC = ({ contactId, collecti const findContactInAllConversations = () => { if (allConversations && allConversations.search) { // loop through the cached conversations and find if contact exists - updateConversationInfo('contact', contactId); + // need to check - updateConversationInfo('contact', contactId); + allConversations.search.map((conversation: any, index: any) => { + if (conversation.contact.id === contactId?.toString()) { + conversationIndex = index; + setConversationInfo(conversation); + } + return null; + }); } // if conversation is not present then fetch for contact if (conversationIndex < 0) { if ((!loading && !called) || (data && data.search[0].contact.id !== contactId)) { - getSearchQuery({ - variables: { - filter: { id: contactId }, - contactOpts: { limit: 1 }, - messageOpts: { - limit: DEFAULT_MESSAGE_LIMIT, - offset: messageParameterOffset, - }, + const variables = { + filter: { id: contactId }, + contactOpts: { limit: 1 }, + messageOpts: { + limit: DEFAULT_MESSAGE_LIMIT, + offset: messageParameterOffset, }, + }; + + addLogs(`if conversation is not present then search for contact-${contactId}`, variables); + + getSearchQuery({ + variables, }); } // lets not get from cache if parameter is present @@ -377,15 +407,19 @@ export const ChatMessages: React.SFC = ({ contactId, collecti (!parameterLoading && !parameterCalled) || (parameterdata && parameterdata.search[0].contact.id !== contactId) ) { - getSearchParameterQuery({ - variables: { - filter: { id: contactId }, - contactOpts: { limit: 1 }, - messageOpts: { - limit: DEFAULT_MESSAGE_LIMIT, - offset: messageParameterOffset, - }, + const variables = { + filter: { id: contactId }, + contactOpts: { limit: 1 }, + messageOpts: { + limit: DEFAULT_MESSAGE_LIMIT, + offset: messageParameterOffset, }, + }; + + addLogs(`if search message is not present then search for contact-${contactId}`, variables); + + getSearchParameterQuery({ + variables, }); } } @@ -405,12 +439,19 @@ export const ChatMessages: React.SFC = ({ contactId, collecti // if conversation is not present then fetch the collection if (conversationIndex < 0) { if (!loading && !data) { + const variables = { + filter: { id: collectionId, searchGroup: true }, + contactOpts: { limit: DEFAULT_CONTACT_LIMIT }, + messageOpts: { limit: DEFAULT_MESSAGE_LIMIT, offset: 0 }, + }; + + addLogs( + `if conversation is not present then search for collection-${collectionId}`, + variables + ); + getSearchQuery({ - variables: { - filter: { id: collectionId, searchGroup: true }, - contactOpts: { limit: DEFAULT_CONTACT_LIMIT }, - messageOpts: { limit: DEFAULT_MESSAGE_LIMIT, offset: 0 }, - }, + variables, }); } } @@ -426,7 +467,7 @@ export const ChatMessages: React.SFC = ({ contactId, collecti }, [contactId, collectionId, allConversations]); const closeDialogBox = () => { - setDialogbox(false); + setDialogbox(''); setShowDropdown(null); }; /* istanbul ignore next */ @@ -435,7 +476,7 @@ export const ChatMessages: React.SFC = ({ contactId, collecti unselectedTags = previousMessageTags.filter((tag: any) => !tags.includes(tag)); if (selectedTags.length === 0 && unselectedTags.length === 0) { - setDialogbox(false); + setDialogbox(''); setShowDropdown(null); } else { createMessageTag({ @@ -450,11 +491,9 @@ export const ChatMessages: React.SFC = ({ contactId, collecti } }; - let dialogBox; - const tags = allTags.data ? allTags.data.tags : []; - if (dialog) { + if (dialog === 'tag') { dialogBox = ( = ({ contactId, collecti const messageTagId = messageTags.map((tag: any) => tag.id); setSelectedMessageTags(messageTagId); setPreviousMessageTags(messageTagId); - setDialogbox(!dialog); + setDialogbox('tag'); }} focus={index === 0} showMessage={ @@ -513,7 +552,6 @@ export const ChatMessages: React.SFC = ({ contactId, collecti .reverse(); } - /* istanbul ignore next */ const loadMoreMessages = () => { const { messageNumber } = conversationInfo.messages[conversationInfo.messages.length - 1]; const variables: any = { @@ -535,6 +573,8 @@ export const ChatMessages: React.SFC = ({ contactId, collecti variables.filter = { id: collectionId.toString(), searchGroup: true }; } + addLogs(`load More Messages-${collectionId}`, variables); + getSearchQuery({ variables, }); @@ -593,8 +633,8 @@ export const ChatMessages: React.SFC = ({ contactId, collecti conversationInfoCopy.messages = []; let allConversationsCopy: any = []; allConversationsCopy = JSON.parse(JSON.stringify(allConversations)); - allConversationsCopy.search[conversationIndex] = conversationInfoCopy; - + const index = conversationIndex === -1 ? 0 : conversationIndex; + allConversationsCopy.search[index] = conversationInfoCopy; // update allConversations in the cache updateConversationsCache(allConversationsCopy, client, queryVariables); }; @@ -623,7 +663,7 @@ export const ChatMessages: React.SFC = ({ contactId, collecti lastMessageTime={conversationInfo.contact.lastMessageAt} contactStatus={conversationInfo.contact.status} contactBspStatus={conversationInfo.contact.bspStatus} - handleAction={handleChatClearedAction} + handleAction={() => handleChatClearedAction()} /> ); @@ -675,6 +715,8 @@ export const ChatMessages: React.SFC = ({ contactId, collecti variables.filter = { id: collectionId.toString(), searchGroup: true }; } + addLogs(`show Latest Message for contact-${contactId}`, variables); + getSearchParameterQuery({ variables, }); @@ -702,6 +744,14 @@ export const ChatMessages: React.SFC = ({ contactId, collecti return ( {dialogBox} + {dialog === 'collection' ? ( + setDialogbox('')} + handleSendMessage={() => handleSendMessage()} + /> + ) : null} {topChatBar} {messageListContainer} {conversationInfo.messages.length && (showJumpToLatest || defaultJumpToLatest) diff --git a/src/containers/Chat/ChatMessages/ContactBar/ContactBar.tsx b/src/containers/Chat/ChatMessages/ContactBar/ContactBar.tsx index 780d206f6..1f8969ef7 100644 --- a/src/containers/Chat/ChatMessages/ContactBar/ContactBar.tsx +++ b/src/containers/Chat/ChatMessages/ContactBar/ContactBar.tsx @@ -47,6 +47,7 @@ import { Tooltip } from '../../../../components/UI/Tooltip/Tooltip'; import { CLEAR_MESSAGES } from '../../../../graphql/mutations/Chat'; import { showChats } from '../../../../common/responsive'; import { CollectionInformation } from '../../../Collection/CollectionInformation/CollectionInformation'; +import { addLogs } from '../../../../common/utils'; import AddContactsToCollection from '../AddContactsToCollection/AddContactsToCollection'; const status = ['SESSION', 'SESSION_AND_HSM', 'HSM']; @@ -293,6 +294,7 @@ export const ContactBar: React.SFC = (props) => { } const handleBlock = () => { + addLogs(`refetch after block Contact`, SEARCH_QUERY_VARIABLES); blockContact({ variables: { id: contactId, @@ -544,8 +546,14 @@ export const ContactBar: React.SFC = (props) => {
setAnchorEl(null)}> -
- +
+
= ({ // it to the cached conversations // let's also skip fetching contact when we trigger this via group subscriptions if (!conversationFound && newMessage && !newMessage.groupId) { - getContactQuery({ - variables: { - contactOpts: { - limit: DEFAULT_CONTACT_LIMIT, - }, - filter: { id: contactId }, - messageOpts: { - limit: DEFAULT_MESSAGE_LIMIT, - }, + const variables = { + contactOpts: { + limit: DEFAULT_CONTACT_LIMIT, + }, + filter: { id: contactId }, + messageOpts: { + limit: DEFAULT_MESSAGE_LIMIT, }, + }; + + addLogs( + `contact is not cached, so we need to fetch the conversations and add to cache`, + variables + ); + + getContactQuery({ + variables, }); return cachedConversations; @@ -384,6 +392,7 @@ export const ChatSubscription: React.SFC = ({ if (triggerRefetch) { // lets refetch here if (refetch) { + addLogs('refetch for subscription', queryVariables); refetch(); } setTriggerRefetch(false); diff --git a/src/containers/Collection/CollectionInformation/CollectionInformation.module.css b/src/containers/Collection/CollectionInformation/CollectionInformation.module.css index d3eac9069..cdb12b9eb 100644 --- a/src/containers/Collection/CollectionInformation/CollectionInformation.module.css +++ b/src/containers/Collection/CollectionInformation/CollectionInformation.module.css @@ -37,3 +37,14 @@ align-items: flex-end; flex-direction: column; } + +.Message { + width: 331px; + line-height: 20px; + text-align: center; + color: #073f24; +} + +.Count:not(:empty) ~ .Count:not(:empty):before { + content: ', '; +} diff --git a/src/containers/Collection/CollectionInformation/CollectionInformation.test.tsx b/src/containers/Collection/CollectionInformation/CollectionInformation.test.tsx index 89f98ae64..dbace2c86 100644 --- a/src/containers/Collection/CollectionInformation/CollectionInformation.test.tsx +++ b/src/containers/Collection/CollectionInformation/CollectionInformation.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { render, screen, waitFor } from '@testing-library/react'; +import { fireEvent, render, screen, waitFor } from '@testing-library/react'; import '@testing-library/jest-dom/extend-expect'; import { CollectionInformation } from './CollectionInformation'; import { MockedProvider } from '@apollo/client/testing'; @@ -55,7 +55,7 @@ describe('render SessionInfo', () => { test('it should have session data', () => { const { getByText } = render(wrapper); - const SessionInfo = getByText('In-session:'); + const SessionInfo = getByText('Session messages:'); expect(SessionInfo).toBeInTheDocument(); }); @@ -84,3 +84,45 @@ describe('render SessionInfo', () => { }); }); }); + +describe('render collection info popup', () => { + const wrapper = ( + + Function} + handleSendMessage={() => Function} + /> + + ); + test('it should display popup', async () => { + const { getAllByText } = render(wrapper); + + await waitFor(() => { + const SessionInfo = getAllByText('1'); + + expect(SessionInfo); + }); + }); + + test('click on ok', async () => { + const { findByTestId } = render(wrapper); + + await waitFor(async () => { + const Ok = findByTestId('ok-button'); + + fireEvent.click(await Ok); + }); + }); + + test('click on cancel', async () => { + const { findByTestId } = render(wrapper); + + await waitFor(async () => { + const cancel = findByTestId('cancel-button'); + + fireEvent.click(await cancel); + }); + }); +}); diff --git a/src/containers/Collection/CollectionInformation/CollectionInformation.tsx b/src/containers/Collection/CollectionInformation/CollectionInformation.tsx index d231e45b2..712bde391 100644 --- a/src/containers/Collection/CollectionInformation/CollectionInformation.tsx +++ b/src/containers/Collection/CollectionInformation/CollectionInformation.tsx @@ -1,19 +1,27 @@ import { useLazyQuery } from '@apollo/client'; -import React, { useEffect } from 'react'; +import React, { useEffect, useState } from 'react'; import styles from './CollectionInformation.module.css'; import { GET_COLLECTION_INFO, GET_COLLECTION_USERS } from '../../../graphql/queries/Collection'; +import { DialogBox } from '../../../components/UI/DialogBox/DialogBox'; export interface CollectionInformationProps { collectionId: any; staff?: boolean; + displayPopup?: boolean; + setDisplayPopup?: any; + handleSendMessage?: any; } -let display: any = { 'In-session': 0, 'Session expired': 0, 'Opted-out': 0 }; +const displayObj: any = { 'Session messages': 0, 'Only templates': 0, 'No messages': 0 }; export const CollectionInformation: React.SFC = ({ collectionId, staff = true, + displayPopup, + setDisplayPopup, + handleSendMessage, }) => { + const [display, setDisplay] = useState(displayObj); const [getCollectionInfo, { data: collectionInfo }] = useLazyQuery(GET_COLLECTION_INFO); const [selectedUsers, { data: collectionUsers }] = useLazyQuery(GET_COLLECTION_USERS, { @@ -24,24 +32,30 @@ export const CollectionInformation: React.SFC = ({ if (collectionId) { getCollectionInfo({ variables: { id: collectionId } }); selectedUsers({ variables: { id: collectionId } }); + // reset to zero on collection change + setDisplay({ 'Session messages': 0, 'Only templates': 0, 'No messages': 0 }); } - // reset to zero on collection change - display = { 'In-session': 0, 'Session expired': 0, 'Opted-out': 0 }; }, [collectionId]); - if (collectionInfo) { - const info = JSON.parse(collectionInfo.groupInfo); - - Object.keys(info).forEach((key) => { - if (key === 'session_and_hsm') { - display['In-session'] = info[key]; - } else if (key === 'session') { - display['Session expired'] = info[key]; - } else if (key === 'none') { - display['Opted-out'] = info[key]; - } - }); - } + useEffect(() => { + if (collectionInfo) { + const info = JSON.parse(collectionInfo.groupInfo); + const displayCopy = { ...displayObj }; + Object.keys(info).forEach((key) => { + if (key === 'session_and_hsm') { + displayCopy['Session messages'] += info[key]; + displayCopy['Only templates'] += info[key]; + } else if (key === 'session') { + displayCopy['Session messages'] += info[key]; + } else if (key === 'hsm') { + displayCopy['Only templates'] += info[key]; + } else if (key === 'none') { + displayCopy['No messages'] = info[key]; + } + }); + setDisplay(displayCopy); + } + }, [collectionInfo]); let assignedToCollection: any = []; if (collectionUsers) { @@ -57,9 +71,44 @@ export const CollectionInformation: React.SFC = ({ } } + // display collection contact status before sending message to a collection + if (displayPopup) { + const dialogBox = ( + handleSendMessage()} + handleCancel={() => setDisplayPopup()} + buttonOk="Ok, Send" + alignButtons="center" + > +
+
+ Custom messages will not be sent to the opted out/session expired contacts. +
+
+ Only HSM template can be sent to the session expired contacts.{' '} +
+
+ Total Contacts: {collectionInfo ? JSON.parse(collectionInfo.groupInfo).total : 0} +
+ Contacts qualified for- + {Object.keys(display).map((data: any) => ( + + {data}: {display[data]} + + ))} +
+
+
+
+ ); + return dialogBox; + } + return (
+
Contacts qualified for-
{Object.keys(display).map((data: any) => (
{data}: {display[data]} diff --git a/src/containers/Flow/FlowList/FlowList.module.css b/src/containers/Flow/FlowList/FlowList.module.css index 003719dcf..a1afed155 100644 --- a/src/containers/Flow/FlowList/FlowList.module.css +++ b/src/containers/Flow/FlowList/FlowList.module.css @@ -38,10 +38,16 @@ height: 29px; } -.LastModified { - width: 185px; +.LastPublished { + width: 250px; padding-top: 12px; + margin-right: 23px; + text-align: left; + font-size: 16px; color: #93a29b; + line-height: 1.25; + white-space: pre-line; + margin: 0; } .Webhook { diff --git a/src/containers/Flow/FlowList/FlowList.tsx b/src/containers/Flow/FlowList/FlowList.tsx index 0ed95e5f4..3dc5f0f5e 100644 --- a/src/containers/Flow/FlowList/FlowList.tsx +++ b/src/containers/Flow/FlowList/FlowList.tsx @@ -27,18 +27,21 @@ const getName = (text: string, keywordsList: any) => { ); }; -const getUpdatedAt = (date: string) => ( -
{moment(date).format(DATE_TIME_FORMAT)}
+const getDate = (date: string, fallback: string = '') => ( +
+ {date ? moment(date).format(DATE_TIME_FORMAT) : fallback} +
); -const getColumns = ({ name, updatedAt, keywords }: any) => ({ +const getColumns = ({ name, keywords, lastChangedAt, lastPublishedAt }: any) => ({ name: getName(name, keywords), - updatedAt: getUpdatedAt(updatedAt), + lastPublishedAt: getDate(lastPublishedAt, 'Not published yet'), + lastChangedAt: getDate(lastChangedAt, 'Nothing in draft'), }); -const columnNames = ['NAME', 'LAST MODIFIED', 'ACTIONS']; +const columnNames = ['NAME', 'LAST PUBLISHED', 'LAST SAVED IN DRAFT', 'ACTIONS']; const dialogMessage = "You won't be able to use this flow."; -const columnStyles = [styles.Name, styles.LastModified, styles.Actions]; +const columnStyles = [styles.Name, styles.LastPublished, styles.LastDraft, styles.Actions]; const flowIcon = ; const queries = { @@ -90,6 +93,7 @@ export const FlowList: React.SFC = () => { {...queries} {...columnAttributes} searchParameter="name" + removeSortBy={['LAST PUBLISHED', 'LAST SAVED IN DRAFT']} additionalAction={additionalAction} button={{ show: true, label: '+ CREATE FLOW' }} /> diff --git a/src/graphql/queries/Flow.ts b/src/graphql/queries/Flow.ts index e56c5bd55..78f52550f 100644 --- a/src/graphql/queries/Flow.ts +++ b/src/graphql/queries/Flow.ts @@ -37,6 +37,8 @@ export const FILTER_FLOW = gql` name uuid keywords + lastChangedAt + lastPublishedAt ignoreKeywords updatedAt } diff --git a/src/mocks/Collection.tsx b/src/mocks/Collection.tsx index ee3907446..bcefe27c6 100644 --- a/src/mocks/Collection.tsx +++ b/src/mocks/Collection.tsx @@ -166,7 +166,7 @@ export const getCollectionInfo = { }, result: { data: { - groupInfo: '{"total":3,"session_and_hsm":1,"session":1,"none":1}', + groupInfo: '{"total":3,"session_and_hsm":1,"session":1,"none":1, "hsm":0}', }, }, }; diff --git a/src/mocks/Flow.tsx b/src/mocks/Flow.tsx index 5b49a8d38..a96cd568d 100644 --- a/src/mocks/Flow.tsx +++ b/src/mocks/Flow.tsx @@ -87,6 +87,8 @@ export const filterFlowQuery = { id: '1', ignoreKeywords: true, keywords: ['help', 'मदद'], + lastChangedAt: '2021-03-05T04:32:23Z', + lastPublishedAt: null, name: 'Help Workflow', updatedAt: '2021-03-05T04:32:23Z', uuid: '3fa22108-f464-41e5-81d9-d8a298854429',