Skip to content

Commit

Permalink
feat: Add inbox view under feature flag on the sidebar (#9049)
Browse files Browse the repository at this point in the history
Co-authored-by: Pranav <pranav@chatwoot.com>
  • Loading branch information
iamsivin and pranavrajs committed Mar 8, 2024
1 parent b6bf6bd commit 0685e04
Show file tree
Hide file tree
Showing 18 changed files with 337 additions and 253 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
v-on-clickaway="closeDropdown"
class="dropdown-pane dropdown-pane--open"
>
<woot-dropdown-menu>
<woot-dropdown-menu class="mb-0">
<woot-dropdown-item v-if="!isPending">
<woot-button
variant="clear"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@ import { FEATURE_FLAGS } from '../../../../featureFlags';
import { frontendURL } from '../../../../helper/URLHelper';

const primaryMenuItems = accountId => [
{
icon: 'mail-inbox',
key: 'inboxView',
label: 'INBOX_VIEW',
featureFlag: FEATURE_FLAGS.INBOX_VIEW,
toState: frontendURL(`accounts/${accountId}/inbox-view`),
toStateName: 'inbox_view',
roles: ['administrator', 'agent'],
},
{
icon: 'chat',
key: 'conversations',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
:chat="currentChat"
:is-inbox-view="isInboxView"
:is-contact-panel-open="isContactPanelOpen"
:show-back-button="isOnExpandedLayout"
:show-back-button="isOnExpandedLayout && !isInboxView"
@contact-panel-toggle="onToggleContactPanel"
/>
<woot-tabs
Expand All @@ -35,7 +35,10 @@
:is-contact-panel-open="isContactPanelOpen"
@contact-panel-toggle="onToggleContactPanel"
/>
<empty-state v-else :is-on-expanded-layout="isOnExpandedLayout" />
<empty-state
v-if="!currentChat.id && !isInboxView"
:is-on-expanded-layout="isOnExpandedLayout"
/>
<div
v-show="showContactPanel"
class="conversation-sidebar-wrap basis-full sm:basis-[17.5rem] md:basis-[18.75rem] lg:basis-[19.375rem] xl:basis-[20.625rem] 2xl:basis-[25rem] rtl:border-r border-slate-50 dark:border-slate-700 h-auto overflow-auto z-10 flex-shrink-0 flex-grow-0"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
class="bg-white dark:bg-slate-900 flex justify-between items-center py-2 px-4 border-b border-slate-50 dark:border-slate-800/50 flex-col md:flex-row"
>
<div
class="flex-1 w-full min-w-0 flex flex-col md:flex-row items-center justify-center"
class="flex-1 w-full min-w-0 flex flex-col items-center justify-center"
:class="isInboxView ? 'sm:flex-row' : 'md:flex-row'"
>
<div class="flex justify-start items-center min-w-0 w-fit max-w-full">
<back-button
Expand Down Expand Up @@ -87,7 +88,6 @@ import Thumbnail from '../Thumbnail.vue';
import wootConstants from 'dashboard/constants/globals';
import { conversationListPageURL } from 'dashboard/helper/URLHelper';
import { snoozedReopenTime } from 'dashboard/helper/snoozeHelpers';
import { frontendURL } from 'dashboard/helper/URLHelper';
export default {
components: {
Expand Down Expand Up @@ -128,9 +128,6 @@ export default {
params: { accountId, inbox_id: inboxId, label, teamId },
name,
} = this.$route;
if (this.isInboxView) {
return frontendURL(`accounts/${accountId}/inbox`);
}
return conversationListPageURL({
accountId,
inboxId,
Expand Down
5 changes: 3 additions & 2 deletions app/javascript/dashboard/i18n/locale/en/inbox.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@
"TITLE": "Inbox",
"DISPLAY_DROPDOWN": "Display",
"LOADING": "Fetching notifications",
"EOF": "All notifications loaded 馃帀",
"404": "There are no active notifications in this group.",
"NO_NOTIFICATIONS": "No notifications",
"NOTE": "Notifications from all subscribed inboxes",
"NO_MESSAGES_AVAILABLE": "Oops! Not able to fetch messages",
"SNOOZED_UNTIL": "Snoozed until",
"SNOOZED_UNTIL_TOMORROW": "Snoozed until tomorrow",
"SNOOZED_UNTIL_NEXT_WEEK": "Snoozed until next week"
},
"ACTION_HEADER": {
"SNOOZE": "Snooze notification",
"DELETE": "Delete notification"
"DELETE": "Delete notification",
"BACK": "Back"
},
"TYPES": {
"CONVERSATION_MENTION": "You have been mentioned in a conversation",
Expand Down
1 change: 1 addition & 0 deletions app/javascript/dashboard/i18n/locale/en/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@
"SIDEBAR": {
"CURRENTLY_VIEWING_ACCOUNT": "Currently viewing:",
"SWITCH": "Switch",
"INBOX_VIEW": "Inbox View",
"CONVERSATIONS": "Conversations",
"INBOX": "Inbox",
"ALL_CONVERSATIONS": "All Conversations",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,28 +1,9 @@
/* eslint arrow-body-style: 0 */
import { frontendURL } from '../../../helper/URLHelper';
const ConversationView = () => import('./ConversationView');
const InboxView = () => import('../inbox/InboxView.vue');

export default {
routes: [
{
path: frontendURL('accounts/:accountId/inbox-view'),
name: 'inbox_view',
roles: ['administrator', 'agent'],
component: InboxView,
props: () => {
return { inboxId: 0 };
},
},
{
path: frontendURL('accounts/:accountId/inbox-view/:conversation_id'),
name: 'inbox_view_conversation',
roles: ['administrator', 'agent'],
component: InboxView,
props: route => {
return { inboxId: 0, conversationId: route.params.conversation_id };
},
},
{
path: frontendURL('accounts/:accountId/dashboard'),
name: 'home',
Expand Down
2 changes: 2 additions & 0 deletions app/javascript/dashboard/routes/dashboard/dashboard.routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import conversation from './conversation/conversation.routes';
import { routes as searchRoutes } from '../../modules/search/search.routes';
import { routes as contactRoutes } from './contacts/routes';
import { routes as notificationRoutes } from './notifications/routes';
import { routes as inboxRoutes } from './inbox/routes';
import { frontendURL } from '../../helper/URLHelper';
import helpcenterRoutes from './helpcenter/helpcenter.routes';

Expand All @@ -16,6 +17,7 @@ export default {
path: frontendURL('accounts/:account_id'),
component: AppContainer,
children: [
...inboxRoutes,
...conversation.routes,
...settings.routes,
...contactRoutes,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<template>
<div
class="text-center bg-slate-25 dark:bg-slate-800 justify-center w-full h-full hidden md:flex items-center"
>
<span v-if="uiFlags.isFetching" class="spinner my-4" />
<div v-else class="flex flex-col items-center gap-2">
<fluent-icon
icon="mail-inbox"
size="40"
class="text-slate-600 dark:text-slate-400"
/>
<span class="text-slate-500 text-sm font-medium dark:text-slate-300">
{{ emptyMessage }}
</span>
</div>
</div>
</template>

<script>
import { mapGetters } from 'vuex';
export default {
props: {
emptyStateMessage: {
type: String,
default: '',
},
},
computed: {
...mapGetters({
uiFlags: 'notifications/getUIFlags',
}),
emptyMessage() {
if (this.emptyStateMessage) {
return this.emptyStateMessage;
}
return this.$t('INBOX.LIST.NOTE');
},
},
};
</script>
102 changes: 49 additions & 53 deletions app/javascript/dashboard/routes/dashboard/inbox/InboxList.vue
Original file line number Diff line number Diff line change
@@ -1,43 +1,47 @@
<template>
<div
class="flex flex-col h-full w-full ltr:border-r border-slate-50 dark:border-slate-800/50"
:class="isOnExpandedLayout ? '' : 'min-w-[360px] max-w-[360px]'"
>
<inbox-list-header @filter="onFilterChange" />
<section class="flex w-full h-full bg-white dark:bg-slate-900">
<div
ref="notificationList"
class="flex flex-col w-full h-[calc(100%-56px)] overflow-x-hidden overflow-y-auto"
class="flex flex-col h-full w-full md:min-w-[360px] md:max-w-[360px] ltr:border-r border-slate-50 dark:border-slate-800/50"
:class="!currentNotificationId ? 'flex' : 'hidden md:flex'"
>
<inbox-card
v-for="notificationItem in notifications"
:key="notificationItem.id"
:notification-item="notificationItem"
@mark-notification-as-read="markNotificationAsRead"
@mark-notification-as-unread="markNotificationAsUnRead"
@delete-notification="deleteNotification"
<inbox-list-header
:is-context-menu-open="isInboxContextMenuOpen"
@filter="onFilterChange"
@redirect="redirectToInbox"
/>
<div v-if="uiFlags.isFetching" class="text-center">
<span class="spinner mt-4 mb-4" />
</div>
<p
v-if="showEmptyState"
class="text-center text-slate-400 text-sm dark:text-slate-400 p-4 font-medium"
>
{{ $t('INBOX.LIST.NO_NOTIFICATIONS') }}
</p>
<p
v-if="showEndOfListMessage"
class="text-center text-slate-400 dark:text-slate-400 p-4"
<div
ref="notificationList"
class="flex flex-col w-full h-[calc(100%-56px)] overflow-x-hidden overflow-y-auto"
>
{{ $t('INBOX.LIST.EOF') }}
</p>
<intersection-observer
v-if="!showEndOfList && !uiFlags.isFetching"
:options="infiniteLoaderOptions"
@observed="loadMoreNotifications"
/>
<inbox-card
v-for="notificationItem in notifications"
:key="notificationItem.id"
:active="currentNotificationId === notificationItem.id"
:notification-item="notificationItem"
@mark-notification-as-read="markNotificationAsRead"
@mark-notification-as-unread="markNotificationAsUnRead"
@delete-notification="deleteNotification"
@context-menu-open="isInboxContextMenuOpen = true"
@context-menu-close="isInboxContextMenuOpen = false"
/>
<div v-if="uiFlags.isFetching" class="text-center">
<span class="spinner mt-4 mb-4" />
</div>
<p
v-if="showEmptyState"
class="text-center text-slate-400 text-sm dark:text-slate-400 p-4 font-medium"
>
{{ $t('INBOX.LIST.NO_NOTIFICATIONS') }}
</p>
<intersection-observer
v-if="!showEndOfList && !uiFlags.isFetching"
:options="infiniteLoaderOptions"
@observed="loadMoreNotifications"
/>
</div>
</div>
</div>
<router-view />
</section>
</template>

<script>
Expand All @@ -49,23 +53,14 @@ import { INBOX_EVENTS } from 'dashboard/helper/AnalyticsHelper/events';
import IntersectionObserver from 'dashboard/components/IntersectionObserver.vue';
import alertMixin from 'shared/mixins/alertMixin';
import uiSettingsMixin from 'dashboard/mixins/uiSettings';
export default {
components: {
InboxCard,
InboxListHeader,
IntersectionObserver,
},
mixins: [alertMixin, uiSettingsMixin],
props: {
conversationId: {
type: [String, Number],
default: 0,
},
isOnExpandedLayout: {
type: Boolean,
default: false,
},
},
data() {
return {
infiniteLoaderOptions: {
Expand All @@ -76,6 +71,8 @@ export default {
status: '',
type: '',
sortOrder: wootConstants.INBOX_SORT_BY.NEWEST,
isInboxContextMenuOpen: false,
notificationIdToSnooze: null,
};
},
computed: {
Expand All @@ -85,6 +82,9 @@ export default {
uiFlags: 'notifications/getUIFlags',
notification: 'notifications/getFilteredNotifications',
}),
currentNotificationId() {
return Number(this.$route.params.notification_id);
},
inboxFilters() {
return {
page: this.page,
Expand All @@ -102,9 +102,6 @@ export default {
showEmptyState() {
return !this.uiFlags.isFetching && !this.notifications.length;
},
showEndOfListMessage() {
return this.showEndOfList && this.notifications.length;
},
},
mounted() {
this.setSavedFilter();
Expand All @@ -115,13 +112,11 @@ export default {
this.page = 1;
this.$store.dispatch('notifications/clear');
const filter = this.inboxFilters;
this.$store.dispatch('notifications/index', filter);
},
redirectToInbox() {
if (!this.conversationId) return;
if (this.$route.name === 'inbox_view') return;
this.$router.push({ name: 'inbox_view' });
this.$router.replace({ name: 'inbox_view' });
},
loadMoreNotifications() {
if (this.uiFlags.isAllNotificationsLoaded) return;
Expand Down Expand Up @@ -177,13 +172,14 @@ export default {
});
},
onFilterChange(option) {
if (option.type === wootConstants.INBOX_FILTER_TYPE.STATUS) {
const { STATUS, TYPE, SORT_ORDER } = wootConstants.INBOX_FILTER_TYPE;
if (option.type === STATUS) {
this.status = option.selected ? option.key : '';
}
if (option.type === wootConstants.INBOX_FILTER_TYPE.TYPE) {
if (option.type === TYPE) {
this.type = option.selected ? option.key : '';
}
if (option.type === wootConstants.INBOX_FILTER_TYPE.SORT_ORDER) {
if (option.type === SORT_ORDER) {
this.sortOrder = option.key;
}
this.fetchNotifications();
Expand Down
Loading

0 comments on commit 0685e04

Please sign in to comment.