feat: Set a reminder to clear cache for dashboard templates (#550)
* feat: set a reminder to clear cache for dashboard templates
* fix: set time
* fix: remove unused imports
* fix: set first reminder
* fix: update reminder content
* fix: update modal style
* fix: code style
diff --git a/src/assets/lang/en.ts b/src/assets/lang/en.ts
index ce2cf26..f29b106 100644
--- a/src/assets/lang/en.ts
+++ b/src/assets/lang/en.ts
@@ -254,6 +254,10 @@
addExcludingKeywordsOfContent: 'Please input a keyword of excluding content',
noticeTag: 'Please press enter after inputting a tag.',
conditionNotice: 'Notice: Please press enter after inputting a tag, key of content, exclude key of content.',
+ cacheModalTitle: 'Clear cache reminder',
+ yes: 'Yes',
+ no: 'No',
+ cacheReminderContent: 'SkyWalking detected dashboard template updates, do you want to update?',
};
export default m;
diff --git a/src/assets/lang/zh.ts b/src/assets/lang/zh.ts
index c3725ff..3000465 100644
--- a/src/assets/lang/zh.ts
+++ b/src/assets/lang/zh.ts
@@ -252,6 +252,10 @@
addExcludingKeywordsOfContent: '请输入一个内容不包含的关键词',
NoticeTag: '请输入一个标签之后回车',
conditionNotice: '请输入一个标签、内容关键词或者内容不包含的关键词之后回车',
+ cacheModalTitle: '清除缓存提醒',
+ yes: '是的',
+ no: '不',
+ cacheReminderContent: 'SkyWalking检测到仪表板模板更新,是否需要更新?',
};
export default m;
diff --git a/src/components/rk-modal.vue b/src/components/rk-modal.vue
index 93357f2..0dd33c6 100644
--- a/src/components/rk-modal.vue
+++ b/src/components/rk-modal.vue
@@ -13,152 +13,152 @@
See the License for the specific language governing permissions and
limitations under the License. -->
<template>
- <div class="rk-modal-bg" v-show="show" @mousemove="modalMove" @mouseup="cancelMove">
- <div class="rk-modal-container">
- <div class="rk-modal-header" @mousedown="setStartingPoint">
- <span class="title">{{ this.title }}</span>
- <div class="r rk-modal-close" @click="cancel">
- <svg class="icon">
- <use xlink:href="#close"></use>
- </svg>
- </div>
- </div>
- <div class="rk-modal-main">
- <slot></slot>
- </div>
- <div v-if="showButton" class="rk-modal-footer">
- <rk-button class="cancel" @click="cancel">{{ $t('cancel') }}</rk-button>
- <rk-button @click="confirm">{{ $t('confirm') }}</rk-button>
- </div>
+ <div class="rk-modal-bg" v-show="show" @mousemove="modalMove" @mouseup="cancelMove">
+ <div class="rk-modal-container">
+ <div class="rk-modal-header" @mousedown="setStartingPoint">
+ <span class="title">{{ this.title }}</span>
+ <div class="r rk-modal-close" @click="cancel">
+ <svg class="icon">
+ <use xlink:href="#close"></use>
+ </svg>
</div>
+ </div>
+ <div class="rk-modal-main">
+ <slot></slot>
+ </div>
+ <div v-if="showButton" class="rk-modal-footer">
+ <rk-button class="cancel" @click="cancel">{{ $t('cancel') }}</rk-button>
+ <rk-button @click="confirm">{{ $t('confirm') }}</rk-button>
+ </div>
</div>
+ </div>
</template>
<script lang="js">
- import RkButton from '@/components/rk-button';
- export default {
- name: 'RkModal',
- components: {RkButton},
- props: {
- show: {
- type: Boolean,
- default: false,
- },
- showButton: {
- type: Boolean,
- default: false,
- },
- title: {
- type: String,
- default: '',
- },
- },
- data() {
- return {
- x: 0,
- y: 0,
- node: null,
- isCanMove: false,
- };
- },
- mounted() {
- this.node = document.querySelector('.rk-modal-container');
- },
- methods: {
- cancel() {
- this.$emit('update:show', false);
- this.$emit('cancelModalCallback');
- },
+ import RkButton from '@/components/rk-button';
+ export default {
+ name: 'RkModal',
+ components: {RkButton},
+ props: {
+ show: {
+ type: Boolean,
+ default: false,
+ },
+ showButton: {
+ type: Boolean,
+ default: false,
+ },
+ title: {
+ type: String,
+ default: '',
+ },
+ },
+ data() {
+ return {
+ x: 0,
+ y: 0,
+ node: null,
+ isCanMove: false,
+ };
+ },
+ mounted() {
+ this.node = document.querySelector('.rk-modal-container');
+ },
+ methods: {
+ cancel() {
+ this.$emit('update:show', false);
+ this.$emit('cancelModalCallback');
+ },
- confirm() {
- this.$emit('update:show', false);
- this.$emit('confirmModalCallback');
- },
+ confirm() {
+ this.$emit('update:show', false);
+ this.$emit('confirmModalCallback');
+ },
- setStartingPoint(e) {
- this.x = e.clientX - this.node.offsetLeft;
- this.y = e.clientY - this.node.offsetTop;
- this.isCanMove = true;
- },
+ setStartingPoint(e) {
+ this.x = e.clientX - this.node.offsetLeft;
+ this.y = e.clientY - this.node.offsetTop;
+ this.isCanMove = true;
+ },
- modalMove(e) {
- if (this.isCanMove) {
- this.node.style.left = e.clientX - this.x + 'px';
- this.node.style.top = e.clientY - this.y + 'px';
- }
- },
+ modalMove(e) {
+ if (this.isCanMove) {
+ this.node.style.left = e.clientX - this.x + 'px';
+ this.node.style.top = e.clientY - this.y + 'px';
+ }
+ },
- cancelMove() {
- this.isCanMove = false;
- },
- },
- };
+ cancelMove() {
+ this.isCanMove = false;
+ },
+ },
+ };
</script>
<style lang="scss">
- .rk-modal-bg {
- position: fixed;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background: rgba(0, 0, 0, .5);
- z-index: 10;
+ .rk-modal-bg {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: rgba(0, 0, 0, 0.5);
+ z-index: 10;
+ }
+
+ .rk-modal-container {
+ background: #fff;
+ border-radius: 10px;
+ overflow: hidden;
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ }
+
+ .rk-modal-header {
+ height: 35px;
+ background: #333840;
+ color: #efefef;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ cursor: move;
+ }
+
+ .rk-modal-close {
+ position: absolute;
+ right: 10px;
+ top: 5px;
+ cursor: pointer;
+ color: #d8d8d8;
+ transition: color 0.3s;
+
+ .icon {
+ width: 18px;
+ height: 20px;
}
- .rk-modal-container {
- background: #fff;
- border-radius: 10px;
- overflow: hidden;
- position: fixed;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
+ &:hover {
+ color: #3d92ff;
}
+ }
- .rk-modal-header {
- height: 35px;
- background: #333840;
- color: #efefef;
- display: flex;
- align-items: center;
- justify-content: center;
- cursor: move;
- }
+ .rk-modal-main {
+ padding: 15px;
+ }
- .rk-modal-close {
- position: absolute;
- right: 10px;
- top: 5px;
- cursor: pointer;
- color: #d8d8d8;
- transition: color 0.3s;
-
- .icon {
- width: 18px;
- height: 20px;
- }
-
- &:hover {
- color: #3d92ff;
- }
- }
-
- .rk-modal-main {
- padding: 15px 40px;
- }
-
- .rk-modal-footer {
- display: flex;
- align-items: center;
- justify-content: right;
- height: 35px;
- border-top: 1px solid #ddd;
- padding-right: 10px;
- }
- .rk-modal-footer .cancel{
- margin-right: 10px;
- border: 1px solid #ddd;
- color: #333;
- background-color: #fff;
- }
+ .rk-modal-footer {
+ display: flex;
+ align-items: center;
+ justify-content: right;
+ height: 35px;
+ border-top: 1px solid #ddd;
+ padding-right: 10px;
+ }
+ .rk-modal-footer .cancel {
+ margin-right: 10px;
+ border: 1px solid #ddd;
+ color: #333;
+ background-color: #fff;
+ }
</style>
diff --git a/src/store/modules/dashboard/dashboard-data-layout.ts b/src/store/modules/dashboard/dashboard-data-layout.ts
index bf69345..7e5da73 100644
--- a/src/store/modules/dashboard/dashboard-data-layout.ts
+++ b/src/store/modules/dashboard/dashboard-data-layout.ts
@@ -55,7 +55,8 @@
},
[types.IMPORT_TREE](state: State, data: CompsTree[]) {
state.tree.push(...data);
- window.localStorage.setItem('dashboard', JSON.stringify(state.tree));
+ localStorage.setItem('dashboard', JSON.stringify(state.tree));
+ localStorage.setItem('isUpdatedTemplates', 'true');
},
[types.SET_GROUP_QUERY](state: State, params: any) {
state.tree[state.group].query = params;
@@ -73,6 +74,7 @@
[types.SET_CURRENT_SERVICE_GROUP](state: State, serviceGroup: string) {
state.tree.splice(state.group, 1, Object.assign(state.tree[state.group], { serviceGroup }));
window.localStorage.setItem('dashboard', JSON.stringify(state.tree));
+ localStorage.setItem('isUpdatedTemplates', 'true');
},
[types.SET_CURRENT_GROUP_WITH_CURRENT](state: State, { index, current = 0 }: { index: number; current: number }) {
state.group = index;
@@ -91,6 +93,7 @@
state.tree.push(group);
window.localStorage.setItem('dashboard', JSON.stringify(state.tree));
+ localStorage.setItem('isUpdatedTemplates', 'true');
},
[types.ADD_COMPS_TREE](state: State, params: { name: string }) {
if (!params.name) {
@@ -98,10 +101,12 @@
}
state.tree[state.group].children.push({ name: params.name, children: [] });
window.localStorage.setItem('dashboard', JSON.stringify(state.tree));
+ localStorage.setItem('isUpdatedTemplates', 'true');
},
[types.IMPORT_COMPS_TREE](state: State, params: any) {
state.tree[state.group].children.push(params);
window.localStorage.setItem('dashboard', JSON.stringify(state.tree));
+ localStorage.setItem('isUpdatedTemplates', 'true');
},
[types.DELETE_COMPS_GROUP](state: State, index: number) {
state.tree.splice(index, 1);
@@ -109,6 +114,7 @@
state.group--;
}
window.localStorage.setItem('dashboard', JSON.stringify(state.tree));
+ localStorage.setItem('isUpdatedTemplates', 'true');
},
[types.DELETE_COMPS_TREE](state: State, index: number) {
state.tree[state.group].children.splice(index, 1);
@@ -116,6 +122,7 @@
state.current--;
}
window.localStorage.setItem('dashboard', JSON.stringify(state.tree));
+ localStorage.setItem('isUpdatedTemplates', 'true');
},
[types.ADD_COMP](state: State) {
const type = state.tree[state.group].type;
@@ -129,16 +136,19 @@
};
state.tree[state.group].children[state.current].children.push(comp);
window.localStorage.setItem('dashboard', JSON.stringify(state.tree));
+ localStorage.setItem('isUpdatedTemplates', 'true');
},
[types.DELETE_COMP](state: State, index: number) {
state.tree[state.group].children[state.current].children.splice(index, 1);
window.localStorage.setItem('dashboard', JSON.stringify(state.tree));
+ localStorage.setItem('isUpdatedTemplates', 'true');
},
[types.EDIT_COMP_CONFIG](state: State, params: { values: any; index: number }) {
const temp = state.tree[state.group].children[state.current].children[params.index];
state.tree[state.group].children[state.current].children[params.index] = { ...temp, ...params.values };
window.localStorage.setItem('dashboard', JSON.stringify(state.tree));
+ localStorage.setItem('isUpdatedTemplates', 'true');
},
[types.SET_TEMPLATES](state: State, templates) {
state.templates = templates;
diff --git a/src/store/modules/dashboard/dashboard-data.ts b/src/store/modules/dashboard/dashboard-data.ts
index da6054c..67c2310 100644
--- a/src/store/modules/dashboard/dashboard-data.ts
+++ b/src/store/modules/dashboard/dashboard-data.ts
@@ -19,7 +19,7 @@
import { CompsTree, Event } from '@/types/dashboard';
import { AxiosResponse } from 'axios';
import graph from '@/graph';
-import dashboardLayout from './dashboard-data-layout';
+import dashboardLayout, { State as layoutState } from './dashboard-data-layout';
import dashboardQuery from './dashboard-data-query';
import { QueryEventCondition } from '../../../types/dashboard';
import { dateFormatTime } from '@/utils/dateFormat';
diff --git a/src/views/containers/dashboard.vue b/src/views/containers/dashboard.vue
index b973bdc..3e9f2f5 100644
--- a/src/views/containers/dashboard.vue
+++ b/src/views/containers/dashboard.vue
@@ -40,6 +40,17 @@
+ Add An Item
</div>
</div>
+ <rk-modal :show.sync="showCacheModal" :title="$t('cacheModalTitle')">
+ <div class="reminder-content">{{ $t('cacheReminderContent') }}</div>
+ <div class="reminder-btns">
+ <a class="rk-cache-modal-btn bg-blue mr-10" @click="clearDashboardTemps">
+ {{ $t('yes') }}
+ </a>
+ <a class="rk-cache-modal-btn" @click="closeCacheModal">
+ {{ $t('no') }}
+ </a>
+ </div>
+ </rk-modal>
</div>
</template>
@@ -53,6 +64,7 @@
import { State as globalState } from '@/store/modules/global';
import { State as optionState } from '@/store/modules/global/selectors';
import { State as dataState } from '@/store/modules/dashboard/dashboard-data';
+ import { State as layoutState } from '@/store/modules/dashboard/dashboard-data-layout';
import { PageTypes } from '@/constants/constant';
interface ITemplate {
@@ -73,7 +85,7 @@
export default class Dashboard extends Vue {
@State('rocketbot') private rocketGlobal!: globalState;
@State('rocketOption') private stateDashboardOption!: optionState;
- @State('rocketData') private rocketComps!: dataState;
+ @State('rocketData') private rocketComps!: dataState & layoutState;
@Action('MIXHANDLE_GET_OPTION') private MIXHANDLE_GET_OPTION: any;
@Action('GET_ALL_TEMPLATES') private GET_ALL_TEMPLATES: any;
@Getter('durationTime') private durationTime: any;
@@ -81,9 +93,12 @@
@Mutation('ADD_COMP') private ADD_COMP: any;
@Mutation('SET_EDIT') private SET_EDIT: any;
@Mutation('SET_TEMPLATES') private SET_TEMPLATES: any;
+ @Mutation('UPDATE_DASHBOARD') private UPDATE_DASHBOARD: any;
private isRouterAlive: boolean = true;
private templatesErrors: boolean = false;
+ private showCacheModal: boolean = false;
+ private intervalCache: any;
public reload(): void {
this.isRouterAlive = false;
this.$nextTick(() => {
@@ -108,32 +123,59 @@
private beforeMount() {
this.GET_ALL_TEMPLATES().then((templateResp: ITemplate[]) => {
const dashboardTemplate = templateResp.filter((item: ITemplate) => item.type === 'DASHBOARD');
- const templatesConfig = dashboardTemplate.map((item: ITemplate) => JSON.parse(item.configuration)).flat(1);
+ const templatesConfig = dashboardTemplate.map((item: ITemplate) => {
+ return { ...JSON.parse(item.configuration)[0], activated: item.activated, disabled: item.disabled };
+ });
this.SET_TEMPLATES(templatesConfig);
- if (window.localStorage.getItem('version') !== '8.0') {
+ if (window.localStorage.getItem('version') === '8.0') {
+ const data: string = `${window.localStorage.getItem('dashboard')}`;
+ this.SET_COMPS_TREE(JSON.parse(data));
+ } else {
window.localStorage.removeItem('dashboard');
const template = templateResp.filter((item: ITemplate) => item.type === 'DASHBOARD' && item.activated);
const templatesConfiguration = template.map((item: ITemplate) => JSON.parse(item.configuration)).flat(1);
this.SET_COMPS_TREE(templatesConfiguration || []);
window.localStorage.setItem('version', '8.0');
window.localStorage.setItem('dashboard', JSON.stringify(templatesConfiguration));
- this.handleOption();
- } else {
- const data: string = `${window.localStorage.getItem('dashboard')}`;
- this.SET_COMPS_TREE(JSON.parse(data));
- this.handleOption();
}
+ this.handleOption();
+ this.checkCacheTime();
+ this.intervalCache = setInterval(() => {
+ this.checkCacheTime();
+ }, 3600000); // 1h
});
}
- private setDashboardTemplates(allTemplate: ITemplate[]) {
- const template = allTemplate.filter((item: ITemplate) => item.type === 'DASHBOARD' && item.activated);
- const templatesConfiguration = template.map((item: ITemplate) => JSON.parse(item.configuration)).flat(1);
+ private checkCacheTime() {
+ const templatesCacheTime = localStorage.getItem('templatesCacheTime');
+ if (templatesCacheTime) {
+ const diffTime = new Date().getTime() - Number(templatesCacheTime);
+ const diffDay = diffTime / 1000 / (60 * 60 * 24);
+ if (diffDay >= 3) {
+ const isUpdatedTemplates = localStorage.getItem('isUpdatedTemplates');
+ if (isUpdatedTemplates === 'true') {
+ this.showCacheModal = true;
+ }
+ }
+ } else {
+ this.showCacheModal = true;
+ localStorage.setItem('templatesCacheTime', String(new Date().getTime()));
+ }
+ }
+ private clearDashboardTemps() {
+ const templatesConfiguration = this.rocketComps.templates.filter((item: any) => item.activated);
this.SET_COMPS_TREE(templatesConfiguration || []);
- window.localStorage.setItem('version', '8.0');
- window.localStorage.setItem('dashboard', JSON.stringify(templatesConfiguration));
+ localStorage.setItem('dashboard', JSON.stringify(templatesConfiguration));
+ localStorage.setItem('templatesCacheTime', String(new Date().getTime()));
+ this.UPDATE_DASHBOARD();
+ this.showCacheModal = false;
+ }
+ private closeCacheModal() {
+ this.showCacheModal = false;
+ localStorage.setItem('templatesCacheTime', String(new Date().getTime()));
}
private beforeDestroy() {
this.SET_EDIT(false);
+ clearInterval(this.intervalCache);
}
}
</script>
@@ -162,4 +204,23 @@
display: inline-block;
font-size: 16px;
}
+ .reminder-btns {
+ margin-top: 15px;
+ text-align: right;
+ }
+ .rk-cache-modal-btn {
+ display: inline-block;
+ height: 30px;
+ width: 80px;
+ text-align: center;
+ line-height: 26px;
+ border-radius: 3px;
+ border: 1px solid #ddd;
+ color: #333;
+ outline: none;
+ cursor: pointer;
+ }
+ .bg-blue {
+ color: #fff;
+ }
</style>