chore: Cleanup update banner with localstorage updates (#5209)

Co-authored-by: Aswin Dev P.S <aswindevps@gmail.com>
This commit is contained in:
Pranav Raj S 2022-08-05 13:46:12 +05:30 committed by GitHub
parent fc9699d993
commit 124390a019
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 104 additions and 63 deletions

View file

@ -12,33 +12,26 @@
</template>
<script>
import Banner from 'dashboard/components/ui/Banner.vue';
import LocalStorage from '../../helper/localStorage';
import { LocalStorage, LOCAL_STORAGE_KEYS } from '../../helper/localStorage';
import { mapGetters } from 'vuex';
import adminMixin from 'dashboard/mixins/isAdmin';
const semver = require('semver');
const dismissedUpdates = new LocalStorage('dismissedUpdates');
import { hasAnUpdateAvailable } from './versionCheckHelper';
export default {
components: {
Banner,
},
components: { Banner },
mixins: [adminMixin],
props: {
latestChatwootVersion: {
type: String,
default: '',
latestChatwootVersion: { type: String, default: '' },
},
data() {
return { userDismissedBanner: false };
},
computed: {
...mapGetters({ globalConfig: 'globalConfig/get' }),
hasAnUpdateAvailable() {
if (!semver.valid(this.latestChatwootVersion)) {
return false;
}
return semver.lt(
this.globalConfig.appVersion,
this.latestChatwootVersion
updateAvailable() {
return hasAnUpdateAvailable(
this.latestChatwootVersion,
this.globalConfig.appVersion
);
},
bannerMessage() {
@ -48,8 +41,9 @@ export default {
},
shouldShowBanner() {
return (
!this.userDismissedBanner &&
this.globalConfig.displayManifest &&
this.hasAnUpdateAvailable &&
this.updateAvailable &&
!this.isVersionNotificationDismissed(this.latestChatwootVersion) &&
this.isAdmin
);
@ -57,17 +51,23 @@ export default {
},
methods: {
isVersionNotificationDismissed(version) {
return dismissedUpdates.get().includes(version);
const dismissedVersions =
LocalStorage.get(LOCAL_STORAGE_KEYS.DISMISSED_UPDATES) || [];
return dismissedVersions.includes(version);
},
dismissUpdateBanner() {
let updatedDismissedItems = dismissedUpdates.get();
let updatedDismissedItems =
LocalStorage.get(LOCAL_STORAGE_KEYS.DISMISSED_UPDATES) || [];
if (updatedDismissedItems instanceof Array) {
updatedDismissedItems.push(this.latestChatwootVersion);
} else {
updatedDismissedItems = [this.latestChatwootVersion];
}
dismissedUpdates.store(updatedDismissedItems);
this.latestChatwootVersion = this.globalConfig.appVersion;
LocalStorage.set(
LOCAL_STORAGE_KEYS.DISMISSED_UPDATES,
updatedDismissedItems
);
this.userDismissedBanner = true;
},
},
};

View file

@ -0,0 +1,15 @@
import { hasAnUpdateAvailable } from '../versionCheckHelper';
describe('#hasAnUpdateAvailable', () => {
it('return false if latest version is invalid', () => {
expect(hasAnUpdateAvailable('invalid', '1.0.0')).toBe(false);
expect(hasAnUpdateAvailable(null, '1.0.0')).toBe(false);
expect(hasAnUpdateAvailable(undefined, '1.0.0')).toBe(false);
expect(hasAnUpdateAvailable('', '1.0.0')).toBe(false);
});
it('return correct value if latest version is valid', () => {
expect(hasAnUpdateAvailable('1.1.0', '1.0.0')).toBe(true);
expect(hasAnUpdateAvailable('0.1.0', '1.0.0')).toBe(false);
});
});

View file

@ -0,0 +1,8 @@
const semver = require('semver');
export const hasAnUpdateAvailable = (latestVersion, currentVersion) => {
if (!semver.valid(latestVersion)) {
return false;
}
return semver.lt(currentVersion, latestVersion);
};

View file

@ -1,17 +1,32 @@
class LocalStorage {
constructor(key) {
this.key = key;
}
export const LOCAL_STORAGE_KEYS = {
DISMISSED_UPDATES: 'dismissedUpdates',
WIDGET_BUILDER: 'widgetBubble_',
};
store(allItems) {
localStorage.setItem(this.key, JSON.stringify(allItems));
localStorage.setItem(this.key + ':ts', Date.now());
}
export const LocalStorage = {
clearAll() {
window.localStorage.clear();
},
get() {
let stored = localStorage.getItem(this.key);
return JSON.parse(stored) || [];
get(key) {
const value = window.localStorage.getItem(key);
try {
return typeof value === 'string' ? JSON.parse(value) : value;
} catch (error) {
return value;
}
},
set(key, value) {
if (typeof value === 'object') {
window.localStorage.setItem(key, JSON.stringify(value));
} else {
window.localStorage.setItem(key, value);
}
window.localStorage.setItem(key + ':ts', Date.now());
},
export default LocalStorage;
remove(key) {
window.localStorage.removeItem(key);
window.localStorage.removeItem(key + ':ts');
},
};

View file

@ -158,7 +158,10 @@ import Widget from 'dashboard/modules/widget-preview/components/Widget';
import InputRadioGroup from './components/InputRadioGroup';
import alertMixin from 'shared/mixins/alertMixin';
import { required } from 'vuelidate/lib/validators';
import LocalStorage from 'dashboard/helper/localStorage';
import {
LocalStorage,
LOCAL_STORAGE_KEYS,
} from 'dashboard/helper/localStorage';
export default {
components: {
@ -225,6 +228,9 @@ export default {
...mapGetters({
uiFlags: 'inboxes/getUIFlags',
}),
storageKey() {
return `${LOCAL_STORAGE_KEYS.WIDGET_BUILDER}${this.inbox.id}`;
},
widgetScript() {
let options = {
position: this.widgetBubblePosition,
@ -313,24 +319,25 @@ export default {
this.replyTime = reply_time;
this.avatarUrl = avatar_url;
// Widget Bubble Settings
const { key, storage } = this.getLocalStorageWithKey(this.inbox.id);
const savedInformation = this.getSavedInboxInformation();
if (savedInformation) {
this.widgetBubblePositions = this.widgetBubblePositions.map(item => {
if (item.id === storage.get(key).position) {
if (item.id === savedInformation.position) {
item.checked = true;
this.widgetBubblePosition = item.id;
}
return item;
});
this.widgetBubbleTypes = this.widgetBubbleTypes.map(item => {
if (item.id === storage.get(key).type) {
if (item.id === savedInformation.type) {
item.checked = true;
this.widgetBubbleType = item.id;
}
return item;
});
this.widgetBubbleLauncherTitle =
storage.get(key).launcherTitle || 'Chat with us';
savedInformation.launcherTitle || 'Chat with us';
}
},
handleWidgetBubblePositionChange(item) {
this.widgetBubblePosition = item.id;
@ -372,7 +379,7 @@ export default {
type: this.widgetBubbleType,
};
this.getLocalStorageWithKey(this.inbox.id).storage.store(bubbleSettings);
LocalStorage.set(this.storageKey, bubbleSettings);
try {
const payload = {
@ -403,12 +410,8 @@ export default {
);
}
},
getLocalStorageWithKey(id) {
const storageKey = `widgetBubble_${id}`;
return {
key: storageKey,
storage: new LocalStorage(storageKey),
};
getSavedInboxInformation() {
return LocalStorage.get(this.storageKey);
},
},
};