feat: Update notifications and unread count in real time (#4261)
This commit is contained in:
parent
ec0ea0b1dc
commit
ccf52a620b
11 changed files with 78 additions and 6 deletions
|
@ -22,6 +22,7 @@ class ActionCableConnector extends BaseActionCableConnector {
|
||||||
'contact.deleted': this.onContactDelete,
|
'contact.deleted': this.onContactDelete,
|
||||||
'contact.updated': this.onContactUpdate,
|
'contact.updated': this.onContactUpdate,
|
||||||
'conversation.mentioned': this.onConversationMentioned,
|
'conversation.mentioned': this.onConversationMentioned,
|
||||||
|
'notification.created': this.onNotificationCreated,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,6 +135,10 @@ class ActionCableConnector extends BaseActionCableConnector {
|
||||||
onContactUpdate = data => {
|
onContactUpdate = data => {
|
||||||
this.app.$store.dispatch('contacts/updateContact', data);
|
this.app.$store.dispatch('contacts/updateContact', data);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
onNotificationCreated = data => {
|
||||||
|
this.app.$store.dispatch('notifications/addNotification', data);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
|
|
@ -52,4 +52,8 @@ export const actions = {
|
||||||
throw new Error(error);
|
throw new Error(error);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
addNotification({ commit }, data) {
|
||||||
|
commit(types.ADD_NOTIFICATION, data);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -45,4 +45,14 @@ export const mutations = {
|
||||||
Vue.set($state.records[item.id], 'read_at', true);
|
Vue.set($state.records[item.id], 'read_at', true);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
[types.ADD_NOTIFICATION]($state, data) {
|
||||||
|
const { notification, unread_count: unreadCount, count } = data;
|
||||||
|
Vue.set($state.records, notification.id, {
|
||||||
|
...($state.records[notification.id] || {}),
|
||||||
|
...notification,
|
||||||
|
});
|
||||||
|
Vue.set($state.meta, 'unreadCount', unreadCount);
|
||||||
|
Vue.set($state.meta, 'count', count);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -90,4 +90,12 @@ describe('#actions', () => {
|
||||||
await expect(actions.readAll({ commit })).rejects.toThrow(Error);
|
await expect(actions.readAll({ commit })).rejects.toThrow(Error);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
describe('#addNotification', () => {
|
||||||
|
it('sends correct actions if API is success', async () => {
|
||||||
|
await actions.addNotification({ commit }, { data: 1 });
|
||||||
|
expect(commit.mock.calls).toEqual([
|
||||||
|
[types.ADD_NOTIFICATION, { data: 1 }],
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -93,4 +93,29 @@ describe('#mutations', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('#ADD_NOTIFICATION', () => {
|
||||||
|
it('add notification', () => {
|
||||||
|
const state = {
|
||||||
|
meta: { unreadCount: 4, count: 231 },
|
||||||
|
records: {
|
||||||
|
1: { id: 1, primary_actor_id: 1 },
|
||||||
|
2: { id: 2, primary_actor_id: 2 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const data = {
|
||||||
|
notification: { id: 3, primary_actor_id: 3 },
|
||||||
|
unread_count: 5,
|
||||||
|
count: 232,
|
||||||
|
};
|
||||||
|
mutations[types.ADD_NOTIFICATION](state, data);
|
||||||
|
expect(state.records).toEqual({
|
||||||
|
1: { id: 1, primary_actor_id: 1 },
|
||||||
|
2: { id: 2, primary_actor_id: 2 },
|
||||||
|
3: { id: 3, primary_actor_id: 3 },
|
||||||
|
});
|
||||||
|
expect(state.meta.unreadCount).toEqual(5);
|
||||||
|
expect(state.meta.count).toEqual(232);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -116,6 +116,7 @@ export default {
|
||||||
SET_NOTIFICATIONS_UNREAD_COUNT: 'SET_NOTIFICATIONS_UNREAD_COUNT',
|
SET_NOTIFICATIONS_UNREAD_COUNT: 'SET_NOTIFICATIONS_UNREAD_COUNT',
|
||||||
SET_NOTIFICATIONS_UI_FLAG: 'SET_NOTIFICATIONS_UI_FLAG',
|
SET_NOTIFICATIONS_UI_FLAG: 'SET_NOTIFICATIONS_UI_FLAG',
|
||||||
UPDATE_NOTIFICATION: 'UPDATE_NOTIFICATION',
|
UPDATE_NOTIFICATION: 'UPDATE_NOTIFICATION',
|
||||||
|
ADD_NOTIFICATION: 'ADD_NOTIFICATION',
|
||||||
UPDATE_ALL_NOTIFICATIONS: 'UPDATE_ALL_NOTIFICATIONS',
|
UPDATE_ALL_NOTIFICATIONS: 'UPDATE_ALL_NOTIFICATIONS',
|
||||||
SET_NOTIFICATIONS_ITEM: 'SET_NOTIFICATIONS_ITEM',
|
SET_NOTIFICATIONS_ITEM: 'SET_NOTIFICATIONS_ITEM',
|
||||||
SET_NOTIFICATIONS: 'SET_NOTIFICATIONS',
|
SET_NOTIFICATIONS: 'SET_NOTIFICATIONS',
|
||||||
|
|
|
@ -2,9 +2,9 @@ class ActionCableListener < BaseListener
|
||||||
include Events::Types
|
include Events::Types
|
||||||
|
|
||||||
def notification_created(event)
|
def notification_created(event)
|
||||||
notification, account = extract_notification_and_account(event)
|
notification, account, unread_count, count = extract_notification_and_account(event)
|
||||||
tokens = [event.data[:notification].user.pubsub_token]
|
tokens = [event.data[:notification].user.pubsub_token]
|
||||||
broadcast(account, tokens, NOTIFICATION_CREATED, notification.push_event_data)
|
broadcast(account, tokens, NOTIFICATION_CREATED, { notification: notification.push_event_data, unread_count: unread_count, count: count })
|
||||||
end
|
end
|
||||||
|
|
||||||
def message_created(event)
|
def message_created(event)
|
||||||
|
|
|
@ -8,7 +8,9 @@ class BaseListener
|
||||||
|
|
||||||
def extract_notification_and_account(event)
|
def extract_notification_and_account(event)
|
||||||
notification = event.data[:notification]
|
notification = event.data[:notification]
|
||||||
[notification, notification.account]
|
unread_count = notification.user.notifications_meta[:unread_count]
|
||||||
|
count = notification.user.notifications_meta[:count]
|
||||||
|
[notification, notification.account, unread_count, count]
|
||||||
end
|
end
|
||||||
|
|
||||||
def extract_message_and_account(event)
|
def extract_message_and_account(event)
|
||||||
|
|
|
@ -72,6 +72,7 @@ class Account < ApplicationRecord
|
||||||
has_many :sms_channels, dependent: :destroy_async, class_name: '::Channel::Sms'
|
has_many :sms_channels, dependent: :destroy_async, class_name: '::Channel::Sms'
|
||||||
has_many :working_hours, dependent: :destroy_async
|
has_many :working_hours, dependent: :destroy_async
|
||||||
has_many :automation_rules, dependent: :destroy
|
has_many :automation_rules, dependent: :destroy
|
||||||
|
has_many :notifications, dependent: :destroy
|
||||||
|
|
||||||
has_flags ACCOUNT_SETTINGS_FLAGS.merge(column: 'settings_flags').merge(DEFAULT_QUERY_SETTING)
|
has_flags ACCOUNT_SETTINGS_FLAGS.merge(column: 'settings_flags').merge(DEFAULT_QUERY_SETTING)
|
||||||
|
|
||||||
|
|
|
@ -52,15 +52,24 @@ class Notification < ApplicationRecord
|
||||||
notification_type: notification_type,
|
notification_type: notification_type,
|
||||||
primary_actor_type: primary_actor_type,
|
primary_actor_type: primary_actor_type,
|
||||||
primary_actor_id: primary_actor_id,
|
primary_actor_id: primary_actor_id,
|
||||||
primary_actor: primary_actor.push_event_data,
|
primary_actor: primary_actor_data,
|
||||||
read_at: read_at,
|
read_at: read_at,
|
||||||
secondary_actor: secondary_actor&.push_event_data,
|
secondary_actor: secondary_actor&.push_event_data,
|
||||||
user: user&.push_event_data,
|
user: user&.push_event_data,
|
||||||
created_at: created_at,
|
created_at: created_at.to_i,
|
||||||
account_id: account_id
|
account_id: account_id,
|
||||||
|
push_message_title: push_message_title
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def primary_actor_data
|
||||||
|
if %w[assigned_conversation_new_message conversation_mention].include? notification_type
|
||||||
|
primary_actor.conversation.push_event_data
|
||||||
|
else
|
||||||
|
primary_actor.push_event_data
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def fcm_push_data
|
def fcm_push_data
|
||||||
{
|
{
|
||||||
id: id,
|
id: id,
|
||||||
|
|
|
@ -187,4 +187,11 @@ class User < ApplicationRecord
|
||||||
def will_save_change_to_email?
|
def will_save_change_to_email?
|
||||||
mutations_from_database.changed?('email')
|
mutations_from_database.changed?('email')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def notifications_meta
|
||||||
|
{
|
||||||
|
unread_count: notifications.where(read_at: nil).count,
|
||||||
|
count: notifications.count
|
||||||
|
}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue