feat: dismiss label suggestions only for 24 hours (#7579)
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
This commit is contained in:
@@ -119,11 +119,13 @@ import aiMixin from 'dashboard/mixins/aiMixin';
|
|||||||
import { getTypingUsersText } from '../../../helper/commons';
|
import { getTypingUsersText } from '../../../helper/commons';
|
||||||
import { calculateScrollTop } from './helpers/scrollTopCalculationHelper';
|
import { calculateScrollTop } from './helpers/scrollTopCalculationHelper';
|
||||||
import { isEscape } from 'shared/helpers/KeyboardHelpers';
|
import { isEscape } from 'shared/helpers/KeyboardHelpers';
|
||||||
|
import { LocalStorage } from 'shared/helpers/localStorage';
|
||||||
|
|
||||||
// constants
|
// constants
|
||||||
import { BUS_EVENTS } from 'shared/constants/busEvents';
|
import { BUS_EVENTS } from 'shared/constants/busEvents';
|
||||||
import { REPLY_POLICY } from 'shared/constants/links';
|
import { REPLY_POLICY } from 'shared/constants/links';
|
||||||
import wootConstants from 'dashboard/constants/globals';
|
import wootConstants from 'dashboard/constants/globals';
|
||||||
|
import { LOCAL_STORAGE_KEYS } from 'dashboard/constants/localStorage';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
@@ -392,8 +394,11 @@ export default {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
isLabelSuggestionDismissed() {
|
isLabelSuggestionDismissed() {
|
||||||
const dismissed = this.getDismissedConversations(this.currentAccountId);
|
return LocalStorage.getFlag(
|
||||||
return dismissed[this.currentAccountId].includes(this.conversationId);
|
LOCAL_STORAGE_KEYS.DISMISSED_LABEL_SUGGESTIONS,
|
||||||
|
this.currentAccountId,
|
||||||
|
this.currentChat.id
|
||||||
|
);
|
||||||
},
|
},
|
||||||
fetchAllAttachmentsFromCurrentChat() {
|
fetchAllAttachmentsFromCurrentChat() {
|
||||||
this.$store.dispatch('fetchAllAttachments', this.currentChat.id);
|
this.$store.dispatch('fetchAllAttachments', this.currentChat.id);
|
||||||
|
|||||||
@@ -190,12 +190,10 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
dismissSuggestions() {
|
dismissSuggestions() {
|
||||||
const dismissed = this.getDismissedConversations(this.currentAccountId);
|
LocalStorage.setFlag(
|
||||||
dismissed[this.currentAccountId].push(this.conversationId);
|
|
||||||
|
|
||||||
LocalStorage.set(
|
|
||||||
LOCAL_STORAGE_KEYS.DISMISSED_LABEL_SUGGESTIONS,
|
LOCAL_STORAGE_KEYS.DISMISSED_LABEL_SUGGESTIONS,
|
||||||
dismissed
|
this.currentAccountId,
|
||||||
|
this.conversationId
|
||||||
);
|
);
|
||||||
|
|
||||||
// dismiss this once the values are set
|
// dismiss this once the values are set
|
||||||
@@ -203,8 +201,11 @@ export default {
|
|||||||
this.trackLabelEvent(OPEN_AI_EVENTS.DISMISS_LABEL_SUGGESTION);
|
this.trackLabelEvent(OPEN_AI_EVENTS.DISMISS_LABEL_SUGGESTION);
|
||||||
},
|
},
|
||||||
isConversationDismissed() {
|
isConversationDismissed() {
|
||||||
const dismissed = this.getDismissedConversations(this.currentAccountId);
|
return LocalStorage.getFlag(
|
||||||
return dismissed[this.currentAccountId].includes(this.conversationId);
|
LOCAL_STORAGE_KEYS.DISMISSED_LABEL_SUGGESTIONS,
|
||||||
|
this.currentAccountId,
|
||||||
|
this.conversationId
|
||||||
|
);
|
||||||
},
|
},
|
||||||
addAllLabels() {
|
addAllLabels() {
|
||||||
let labelsToAdd = this.selectedLabels;
|
let labelsToAdd = this.selectedLabels;
|
||||||
|
|||||||
@@ -3,5 +3,5 @@ export const LOCAL_STORAGE_KEYS = {
|
|||||||
WIDGET_BUILDER: 'widgetBubble_',
|
WIDGET_BUILDER: 'widgetBubble_',
|
||||||
DRAFT_MESSAGES: 'draftMessages',
|
DRAFT_MESSAGES: 'draftMessages',
|
||||||
COLOR_SCHEME: 'color_scheme',
|
COLOR_SCHEME: 'color_scheme',
|
||||||
DISMISSED_LABEL_SUGGESTIONS: 'dismissedLabelSuggestions',
|
DISMISSED_LABEL_SUGGESTIONS: 'labelSuggestionsDismissed',
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
import { OPEN_AI_EVENTS } from '../helper/AnalyticsHelper/events';
|
import { OPEN_AI_EVENTS } from '../helper/AnalyticsHelper/events';
|
||||||
import { LOCAL_STORAGE_KEYS } from '../constants/localStorage';
|
|
||||||
import { LocalStorage } from '../../shared/helpers/localStorage';
|
|
||||||
import OpenAPI from '../api/integrations/openapi';
|
import OpenAPI from '../api/integrations/openapi';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@@ -66,29 +64,6 @@ export default {
|
|||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
getDismissedConversations(accountId) {
|
|
||||||
const suggestionKey = LOCAL_STORAGE_KEYS.DISMISSED_LABEL_SUGGESTIONS;
|
|
||||||
|
|
||||||
// fetch the value from Storage
|
|
||||||
const valueFromStorage = LocalStorage.get(suggestionKey);
|
|
||||||
|
|
||||||
// Case 1: the key is not initialized
|
|
||||||
if (!valueFromStorage) {
|
|
||||||
LocalStorage.set(suggestionKey, {
|
|
||||||
[accountId]: [],
|
|
||||||
});
|
|
||||||
return LocalStorage.get(suggestionKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Case 2: the key is initialized, but account ID is not present
|
|
||||||
if (!valueFromStorage[accountId]) {
|
|
||||||
valueFromStorage[accountId] = [];
|
|
||||||
LocalStorage.set(suggestionKey, valueFromStorage);
|
|
||||||
return LocalStorage.get(suggestionKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
return valueFromStorage;
|
|
||||||
},
|
|
||||||
cleanLabels(labels) {
|
cleanLabels(labels) {
|
||||||
return labels
|
return labels
|
||||||
.toLowerCase() // Set it to lowercase
|
.toLowerCase() // Set it to lowercase
|
||||||
|
|||||||
@@ -88,47 +88,6 @@ describe('aiMixin', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('gets dismissed conversations', () => {
|
|
||||||
const getSpy = jest.spyOn(LocalStorage, 'get');
|
|
||||||
const setSpy = jest.spyOn(LocalStorage, 'set');
|
|
||||||
|
|
||||||
const accountId = 123;
|
|
||||||
const valueFromStorage = { [accountId]: ['conv1', 'conv2'] };
|
|
||||||
|
|
||||||
// in case key is not initialized
|
|
||||||
getSpy.mockReturnValueOnce(null);
|
|
||||||
wrapper.vm.getDismissedConversations(accountId);
|
|
||||||
|
|
||||||
expect(getSpy).toHaveBeenCalledWith('dismissedLabelSuggestions');
|
|
||||||
expect(setSpy).toHaveBeenCalledWith('dismissedLabelSuggestions', {
|
|
||||||
[accountId]: [],
|
|
||||||
});
|
|
||||||
|
|
||||||
// rest spy
|
|
||||||
getSpy.mockReset();
|
|
||||||
setSpy.mockReset();
|
|
||||||
|
|
||||||
// in case we get the value from storage
|
|
||||||
getSpy.mockReturnValueOnce(valueFromStorage);
|
|
||||||
const result = wrapper.vm.getDismissedConversations(accountId);
|
|
||||||
expect(result).toEqual(valueFromStorage);
|
|
||||||
expect(getSpy).toHaveBeenCalledWith('dismissedLabelSuggestions');
|
|
||||||
expect(setSpy).not.toHaveBeenCalled();
|
|
||||||
|
|
||||||
// rest spy
|
|
||||||
getSpy.mockReset();
|
|
||||||
setSpy.mockReset();
|
|
||||||
|
|
||||||
// in case we get the value from storage but accountId is not present
|
|
||||||
getSpy.mockReturnValueOnce(valueFromStorage);
|
|
||||||
wrapper.vm.getDismissedConversations(234);
|
|
||||||
expect(getSpy).toHaveBeenCalledWith('dismissedLabelSuggestions');
|
|
||||||
expect(setSpy).toHaveBeenCalledWith('dismissedLabelSuggestions', {
|
|
||||||
...valueFromStorage,
|
|
||||||
234: [],
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('cleans labels', () => {
|
it('cleans labels', () => {
|
||||||
const labels = 'label1, label2, label1';
|
const labels = 'label1, label2, label1';
|
||||||
expect(wrapper.vm.cleanLabels(labels)).toEqual(['label1', 'label2']);
|
expect(wrapper.vm.cleanLabels(labels)).toEqual(['label1', 'label2']);
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ export const LocalStorage = {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
set(key, value) {
|
set(key, value) {
|
||||||
if (typeof value === 'object') {
|
if (typeof value === 'object') {
|
||||||
window.localStorage.setItem(key, JSON.stringify(value));
|
window.localStorage.setItem(key, JSON.stringify(value));
|
||||||
@@ -21,6 +22,26 @@ export const LocalStorage = {
|
|||||||
window.localStorage.setItem(key + ':ts', Date.now());
|
window.localStorage.setItem(key + ':ts', Date.now());
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setFlag(store, accountId, key, expiry = 24 * 60 * 60 * 1000) {
|
||||||
|
const storeName = accountId ? `${store}::${accountId}` : store;
|
||||||
|
|
||||||
|
const rawValue = window.localStorage.getItem(storeName);
|
||||||
|
const parsedValue = rawValue ? JSON.parse(rawValue) : {};
|
||||||
|
|
||||||
|
parsedValue[key] = Date.now() + expiry;
|
||||||
|
|
||||||
|
window.localStorage.setItem(storeName, JSON.stringify(parsedValue));
|
||||||
|
},
|
||||||
|
|
||||||
|
getFlag(store, accountId, key) {
|
||||||
|
const storeName = store ? `${store}::${accountId}` : store;
|
||||||
|
|
||||||
|
const rawValue = window.localStorage.getItem(storeName);
|
||||||
|
const parsedValue = rawValue ? JSON.parse(rawValue) : {};
|
||||||
|
|
||||||
|
return parsedValue[key] && parsedValue[key] > Date.now();
|
||||||
|
},
|
||||||
|
|
||||||
remove(key) {
|
remove(key) {
|
||||||
window.localStorage.removeItem(key);
|
window.localStorage.removeItem(key);
|
||||||
window.localStorage.removeItem(key + ':ts');
|
window.localStorage.removeItem(key + ':ts');
|
||||||
|
|||||||
Reference in New Issue
Block a user