Browse Source

feat(gui): new release info

Signed-off-by: Pranav C <61551451+pranavxc@users.noreply.github.com>
pull/362/head
Pranav C 3 years ago
parent
commit
66926c838e
  1. 58
      packages/nc-gui/components/releaseInfo.vue
  2. 8
      packages/nc-gui/components/utils/language.vue
  3. 4
      packages/nc-gui/layouts/default.vue
  4. 107
      packages/nc-gui/plugins/localStorage.js
  5. 16
      packages/nc-gui/plugins/projectLoader.js
  6. 36
      packages/nc-gui/store/app.js

58
packages/nc-gui/components/releaseInfo.vue

@ -0,0 +1,58 @@
<template>
<transition name="release">
<v-alert
v-if="releaseAlert"
class="mb-0"
border="left"
colored-border
outlined
type="info"
:icon="false"
dense
>
<a href="https://github.com/nocodb/nocodb/releases" target="_blank" class="white--text text-decoration-none"><span class="caption">New version is available (<strong>{{
releaseVersion
}}</strong>)</span></a>
<x-icon x-small :color="['grey lighten-2']" btnclass="mr-n2" @click="releaseAlert =false">
mdi-close
</x-icon>
</v-alert>
</transition>
</template>
<script>
export default {
name: 'ReleaseInfo',
data: () => ({
loading: true
}),
computed: {
releaseAlert: {
get() {
return !this.loading && this.$store.state.app.releaseVersion && this.$store.state.app.releaseVersion !== this.$store.state.app.hiddenRelease
},
set(val) {
return this.$store.commit('app/MutHiddenRelease', val ? null : this.$store.state.app.releaseVersion)
}
},
releaseVersion() {
return this.$store.state.app.releaseVersion
}
},
mounted() {
setTimeout(() => {
this.loading = false
}, 1000)
}
}
</script>
<style scoped>
.release-enter-active, .release-leave-active {
transition: opacity .5s;
}
.release-enter, .release-leave-to {
opacity: 0;
}
</style>

8
packages/nc-gui/components/utils/language.vue

@ -2,11 +2,9 @@
<div> <div>
<v-menu bottom offset-y> <v-menu bottom offset-y>
<template #activator="{on}"> <template #activator="{on}">
<v-btn small class="text-capitalize caption font-weight-bold" text v-on="on"> <v-icon size="20" class="ml-2" v-on="on">
<v-icon small class=""> mdi-translate
mdi-translate </v-icon>
</v-icon>
</v-btn>
</template> </template>
<v-list dense> <v-list dense>
<v-list-item-group <v-list-item-group

4
packages/nc-gui/layouts/default.vue

@ -96,6 +96,8 @@
<v-spacer /> <v-spacer />
<v-toolbar-items class="hidden-sm-and-down"> <v-toolbar-items class="hidden-sm-and-down">
<release-info class="mr-2 py-0" />
<template v-if="isDashboard"> <template v-if="isDashboard">
<div> <div>
<x-btn v-if="_isUIAllowed('add-user')" small color="white" btn-class="primary--text" @click="rolesTabAdd"> <x-btn v-if="_isUIAllowed('add-user')" small color="white" btn-class="primary--text" @click="rolesTabAdd">
@ -544,6 +546,7 @@
</template> </template>
<script> <script>
import ReleaseInfo from '@/components/releaseInfo'
import { mapGetters, mapActions, mapMutations } from 'vuex' import { mapGetters, mapActions, mapMutations } from 'vuex'
import 'splitpanes/dist/splitpanes.css' import 'splitpanes/dist/splitpanes.css'
import { copyTextToClipboard } from '@/helpers/xutils' import { copyTextToClipboard } from '@/helpers/xutils'
@ -558,6 +561,7 @@ import Language from '~/components/utils/language'
export default { export default {
components: { components: {
ReleaseInfo,
Language, Language,
ChangeEnv, ChangeEnv,
XBtn, XBtn,

107
packages/nc-gui/plugins/localStorage.js

@ -1,66 +1,10 @@
import createPersistedState from 'vuex-persistedstate' import createPersistedState from 'vuex-persistedstate'
// var authRoute = require('../components/auth.routes');
// var pollStarted = false;
import SecureLS from 'secure-ls' import SecureLS from 'secure-ls'
import isDev from '../helpers/xutils' import isDev from '../helpers/xutils'
// const jExcelDark = {
// '--jexcel_header_color': '#888',
// '--jexcel_header_color_highlighted': '#444',
// '--jexcel_header_background': '#313131',
// '--jexcel_header_background_highlighted': '#777',
// '--jexcel_content_color': '#777',
// '--jexcel_content_color_highlighted': '#333',
// '--jexcel_content_background': '#3e3e3e',
// '--jexcel_content_background_highlighted': '#333',
// '--jexcel_menu_background': '#7e7e7e',
// '--jexcel_menu_background_highlighted': '#ebebeb',
// '--jexcel_menu_color': '#ddd',
// '--jexcel_menu_color_highlighted': '#222',
// '--jexcel_menu_box_shadow': 'unset',
// '--jexcel_border_color': '#5f5f5f',
// '--jexcel_border_color_highlighted': '#999',
// '--jexcel_cursor': '#333',
// '--active_color': '#eee'
// };
//
//
// const jExcelLight = {
// '--jexcel_header_color': '#000',
// '--jexcel_header_color_highlighted': '#000',
// '--jexcel_header_background': '#f3f3f3',
// '--jexcel_header_background_highlighted': '#dcdcdc',
// '--jexcel_content_color': '#000',
// '--jexcel_content_color_highlighted': '#000',
// '--jexcel_content_background': '#fff',
// '--jexcel_content_background_highlighted': 'rgba(0,0,0,0.05)',
// '--jexcel_menu_background': '#fff',
// '--jexcel_menu_background_highlighted': '#ebebeb',
// '--jexcel_menu_color': '#555',
// '--jexcel_menu_color_highlighted': '#555',
// '--jexcel_menu_box_shadow': '2px 2px 2px 0px rgba(143, 144, 145, 1)',
// '--jexcel_border_color': '#ccc',
// '--jexcel_border_color_highlighted': '#000',
// '--jexcel_cursor': '#eee',
// '--active_color': '#007aff'
// };
const ls = new SecureLS({ isCompression: false }) const ls = new SecureLS({ isCompression: false })
// function toggleJexcelTheme(isDark) {
// const bodyStyles = document.body.style;
// if (isDark) {
// Object.entries(jExcelDark).forEach(([k, v]) => {
// bodyStyles.setProperty(k, v);
// })
// } else {
// Object.entries(jExcelLight).forEach(([k, v]) => {
// bodyStyles.setProperty(k, v);
// })
// }
// }
export default async({ store, $vuetify: { theme } }) => { export default async({ store, $vuetify: { theme } }) => {
/** /**
* *
@ -68,8 +12,6 @@ export default async({ store, $vuetify: { theme } }) => {
store.watch( store.watch(
state => state.windows.theme, state => state.windows.theme,
(c) => { (c) => {
// console.log(JSON.stringify(themes.dark,0,3))
// console.log(JSON.stringify(themes.light,0,3))
theme.themes.dark = { ...theme.themes.dark, ...c } theme.themes.dark = { ...theme.themes.dark, ...c }
theme.themes.light = { ...theme.themes.light, ...c } theme.themes.light = { ...theme.themes.light, ...c }
} }
@ -77,16 +19,13 @@ export default async({ store, $vuetify: { theme } }) => {
store.watch( store.watch(
state => state.windows.darkTheme, state => state.windows.darkTheme,
(isDark) => { (isDark) => {
// if (isDark && !store.state.users.ui_ability.rules.darkTheme) setTimeout(() => store.commit('windows/MutToggleDarkMode', false), 10000)
theme.dark = isDark theme.dark = isDark
// toggleJexcelTheme(isDark);;
document.body.classList.add(isDark ? 'dark' : 'light') document.body.classList.add(isDark ? 'dark' : 'light')
document.body.classList.remove(isDark ? 'light' : 'dark') document.body.classList.remove(isDark ? 'light' : 'dark')
} }
) )
document.body.classList.add(store.state.windows.darkTheme ? 'dark' : 'light') document.body.classList.add(store.state.windows.darkTheme ? 'dark' : 'light')
document.body.classList.remove(store.state.windows.darkTheme ? 'light' : 'dark') document.body.classList.remove(store.state.windows.darkTheme ? 'light' : 'dark')
// toggleJexcelTheme(store.state.windows.darkTheme);
// In case of HMR, mutation occurs before nuxReady, so previously saved state // In case of HMR, mutation occurs before nuxReady, so previously saved state
// gets replaced with original state received from server. So, we've to skip HMR. // gets replaced with original state received from server. So, we've to skip HMR.
@ -105,7 +44,7 @@ export default async({ store, $vuetify: { theme } }) => {
console.log(store.state.windows) console.log(store.state.windows)
console.log('Date difference ', await store.dispatch('windows/ActGetExpiryDate')) console.log('Date difference ', await store.dispatch('windows/ActGetExpiryDate'))
}, },
paths: ['users', 'sqlClient', 'apiClient', 'panelSize', 'windows', 'graphqlClient', 'apiClientSwagger'], paths: ['users', 'sqlClient', 'apiClient', 'panelSize', 'windows', 'graphqlClient', 'apiClientSwagger', 'app'],
...( ...(
isDev() isDev()
? {} ? {}
@ -118,50 +57,6 @@ export default async({ store, $vuetify: { theme } }) => {
} }
) )
})(store) // vuex plugins can be connected to store, even after creation })(store) // vuex plugins can be connected to store, even after creation
// POLLING
// // console.log(pollStarted)
// if (!pollStarted) {
// console.log('Starting poll action')
// await store.dispatch('users/ActPollSession');
// console.log('updating polling state')
// pollStarted = true;
// }
//
//
// if (process.client && store.getters['users/GtrUser'] === null) {
//
// console.log('Plugin in client: user data is null');
//
// //if (authRoute.allowed(store, store.$router.history.current.path) === true) {
// if (1) {
// console.log('Plugin in client: URL has free access - do nothing');
// } else {
//
// console.log('Plugin in client: URL has auth access - get user since sometimes its not filled in');
//
// let user = await store.$axios.get('/users/me');
//
// if (user && user.data) {
// console.log('setting user data + + + + +', user);
// store.commit('MutSetUser', user.data);
// } else {
// console.log('User is null - should not have occured', user);
// }
//
// if (authRoute.allowed(store, store.$router.history.current.path) === false) {
// //console.log(store.$router.history.current.path, 'not allowed without login - redirecting to /');
// store.$router.push('/');
// }
// }
//
// } else {
// console.log('Plugin in client: user is present');
// }
//
// })
// }
} }
/** /**

16
packages/nc-gui/plugins/projectLoader.js

@ -59,6 +59,22 @@ export default async({ store, redirect, $axios, $toast }) => {
redirect('/') redirect('/')
} }
// }) // })
// fetch latest release info
const fetchReleaseInfo = async() => {
try {
const releaseInfo = await store.dispatch('sqlMgr/ActSqlOp', [null, 'xcRelease'])
if (releaseInfo && releaseInfo.docker && releaseInfo.docker.upgrade) {
store.commit('app/MutReleaseVersion', releaseInfo.docker.name)
}
} catch (e) {
// ignore
}
}
fetchReleaseInfo().then(() => {
})
setInterval(fetchReleaseInfo, 10 * 60 * 1000)
} }
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd

36
packages/nc-gui/store/app.js

@ -0,0 +1,36 @@
export const state = () => ({
releaseVersion: null,
hiddenRelease: null
})
export const mutations = {
MutReleaseVersion(state, releaseVersion) {
state.releaseVersion = releaseVersion
},
MutHiddenRelease(state, hiddenRelease) {
state.hiddenRelease = hiddenRelease
}
}
/**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd
*
* @author Naveen MR <oof1lab@gmail.com>
* @author Pranav C Balan <pranavxc@gmail.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
Loading…
Cancel
Save