Browse Source

feat: Add dropdown for language switch

Signed-off-by: Pranav C <61551451+pranavxc@users.noreply.github.com>
pull/350/head
Pranav C 3 years ago
parent
commit
2542e79f9e
  1. 2
      packages/nc-gui/components/project/settings/appearance.vue
  2. 47
      packages/nc-gui/components/utils/language.vue
  3. 319
      packages/nc-gui/layouts/default.vue
  4. 12
      packages/nc-gui/mixins/device.js
  5. 2
      packages/nc-gui/pages/index.vue
  6. 10
      packages/nc-gui/plugins/i18n.js
  7. 9
      packages/nc-gui/store/windows.js

2
packages/nc-gui/components/project/settings/appearance.vue

@ -184,7 +184,7 @@ export default {
get() {
return this.$store.state.windows.language;
}, set(val) {
this.$store.commit('windows/MutSetLanguage', val);
this.$store.commit('windows/MutLanguage', val);
}
},
showMetatable: {

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

@ -0,0 +1,47 @@
<template>
<div>
<v-menu bottom offset-y>
<template #activator="{on}">
<v-btn v-on="on" small class="text-capitalize caption font-weight-bold" text>
<v-icon small class="">mdi-translate</v-icon>
</v-btn>
</template>
<v-list dense >
<v-list-item-group
v-model="language">
<v-list-item
dense
v-for="lan in languages" :key="lan.value"
:value="lan"
@click="language = lan"
color="primary"
>
<v-list-item-subtitle class="text-capitalize">{{ lan }}</v-list-item-subtitle>
</v-list-item>
</v-list-item-group>
</v-list>
</v-menu>
</div>
</template>
<script>
export default {
name: "language",
computed: {
languages() {
return this.$i18n && this.$i18n.availableLocales || ['en'];
},
language: {
get() {
return this.$store.state.windows.language;
}, set(val) {
this.$store.commit('windows/MutLanguage', val);
}
},
}
}
</script>
<style scoped>
</style>

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

@ -65,36 +65,6 @@
</v-toolbar-items>-->
<span class="caption grey--text ml-3" v-show="$nuxt.$loading.show">Loading <v-icon small color="grey">mdi-spin mdi-loading</v-icon></span>
<!-- <gh-btns-star-->
<!-- @click.native="githubClickHandler"-->
<!-- class="black&#45;&#45;text"-->
<!-- icon="mark-github" slug="nocodb/nocodb" show-count></gh-btns-star>-->
<!--
<x-icon key="discord-dash" iconClass="ml-4" @click="openDiscord" tooltip="Discord Chat (^⇧D)">mdi-discord
</x-icon>
<a href="https://twitter.com/xgenecloud" target="_blank">
<x-icon key="twitter-dash" iconClass="ml-4" tooltip="Twitter">
mdi-twitter
</x-icon>
</a>
<a href="https://calendly.com/nocodb" target="_blank">
<x-icon iconClass="ml-4" tooltip="Book a demo">
mdi-video-outline
</x-icon>
</a>-->
<!-- <x-btn btn.class=" mr-4" small text-->
<!-- tooltip="We'll help you get started over a video call"-->
<!-- @click="openUrl('https://calendly.com/nocodb')">-->
<!-- <v-icon-->
<!-- color="">-->
<!-- mdi-video-outline-->
<!-- </v-icon> &nbsp; Free Demo-->
<!-- </x-btn>-->
<span v-shortkey="[ 'ctrl','shift', 'd']"
@shortkey="openDiscord"></span>
@ -125,33 +95,6 @@
<v-toolbar-items class="hidden-sm-and-down">
<!-- <x-icon iconClass="mr-4" v-if="isDashboard"-->
<!-- @click="codeGenerateMvc()"-->
<!-- tooltip="Generate REST Code (^⇧G)"-->
<!-- color="success success">-->
<!-- mdi-language-javascript-->
<!-- </x-icon>-->
<!-- <span v-shortkey="['ctrl','shift','m']" v-if="isDashboard" @shortkey="codeGenerateMvc()"></span>-->
<!-- <x-icon iconClass="mr-4"-->
<!-- v-if="isDashboard"-->
<!-- @click="codeGenerateMvcGql()"-->
<!-- color="accent accent"-->
<!-- tooltip="Generate GraphQL Code (^⇧G)">-->
<!-- mdi-language-javascript-->
<!-- </x-icon>-->
<!-- <span v-shortkey="['ctrl','shift','q']" v-if="isDashboard" @shortkey="codeGenerateMvcGql()"></span>-->
<!-- <x-icon iconClass="mr-4"-->
<!-- v-if="isDashboard"-->
<!-- @click="codeClear()"-->
<!-- color="error error"-->
<!-- tooltip="Delete all code (^⇧G)">-->
<!-- mdi-delete-variant-->
<!-- </x-icon>-->
<!-- <span v-shortkey="['ctrl','shift','c']" v-if="isDashboard" @shortkey="codeClear()"></span>-->
<template v-if="isDashboard">
<div>
@ -160,68 +103,6 @@
Share
</x-btn>
</div>
<!-- <github-button v-show="$store.state.isLoaded" class="mt-2 mr-md-2" href="https://github.com/nocodb/nocodb"-->
<!-- data-color-scheme="no-preference: light; light: light; dark: light;" data-size="large"-->
<!-- data-show-count="true" aria-label="Star nocodb/nocodb on GitHub">Star-->
<!-- </github-button>-->
<!-- <v-menu offset-y>
<template v-slot:activator="{on}">
<div class="align-self-center" v-on="on">
<v-icon small color="" class="mr-1 heart-anim">mdi-heart</v-icon>
<span class="body-2">Community</span>
<v-icon small>mdi-menu-down</v-icon>
</div>
</template>
<v-list dense>
<v-list-item>
<v-icon small class="mr-1">mdi-github</v-icon>
<span class="caption text-capitalize">Github</span>
</v-list-item>
<v-list-item>
<v-icon small class="mr-1">mdi-discord</v-icon>
<span class="caption text-capitalize">Discord</span>
</v-list-item>
<v-list-item>
<v-icon small class="mr-1">mdi-discord</v-icon>
<span class="caption text-capitalize">Discord</span>
</v-list-item>
</v-list>
</v-menu>
-->
<!--
<v-menu offset-y v-if="rolesList">
<template v-slot:activator="{on}">
<div class="d-flex align-center">
<v-btn small outlined v-on="on">
<v-icon small class="mr-1">mdi-drama-masks</v-icon>
<span>Preview as</span>
<v-icon small>mdi-menu-down</v-icon>
</v-btn>
</div>
</template>
<v-list dense>
<v-list-item v-for="role in rolesList" @click="setPreviewUSer(role.title)" :key="role.title">
<v-icon small class="mr-1">{{ roleIcon[role.title] }}</v-icon>
<span class="caption text-capitalize">{{ role.title }}</span>
</v-list-item>
<template v-if="previewAs">
<v-divider></v-divider>
<v-list-item @click="setPreviewUSer(null)">
<v-icon small class="mr-1">mdi-close</v-icon>
<span class="caption">Reset Preview</span>
</v-list-item>
</template>
</v-list>
</v-menu>
-->
<v-tooltip bottom>
<template v-slot:activator="{ on }">
@ -247,28 +128,6 @@
</v-tooltip>
<!-- <template v-if="isDocker">-->
<!-- <x-btn text btn.class="caption font-weight-bold px-2" tooltip="Metadata Operations"-->
<!-- @click="xcMetaTabAdd">-->
<!-- <v-icon class="mt-n1">-->
<!-- mdi-file-table-box-multiple-outline-->
<!-- </v-icon> &nbsp;-->
<!-- Meta-->
<!-- </x-btn>-->
<!-- <x-btn text btn.class="caption font-weight-bold px-2" tooltip="Change Environment"-->
<!-- @click="showChangeEnv = true">-->
<!-- <v-icon>-->
<!-- mdi-test-tube-->
<!-- </v-icon> &nbsp;-->
<!-- Change Env-->
<!-- </x-btn>-->
<!-- </template>-->
<span v-shortkey="[ 'ctrl','shift', 'd']"
@shortkey="$router.push('/')"></span>
@ -282,35 +141,6 @@
Data
</x-btn>
<!-- v-if="showAppStore"-->
<!-- <x-btn text btn.class="caption font-weight-bold px-2 text-capitalize"
tooltip="App store"
@click="appsTabAdd()">
<v-icon size="16" class="mt-n1">
mdi-storefront-outline
</v-icon> &nbsp;
App Store
</x-btn>-->
<!-- <x-btn text btn.class="caption font-weight-bold px-2 text-capitalize" tooltip="Meta Management"-->
<!-- @dblclick="showAppStoreIcon"-->
<!-- @click="disableOrEnableModelTabAdd()">-->
<!-- <v-icon size="20">mdi-table-multiple-->
<!-- </v-icon> &nbsp;-->
<!-- Meta-->
<!-- </x-btn>-->
<!-- <x-btn text btn.class="caption font-weight-bold px-2 text-capitalize" tooltip="Roles & Users Management"-->
<!-- @click="rolesTabAdd()">-->
<!-- <v-icon size="20">-->
<!-- mdi-account-group-->
<!-- </v-icon> &nbsp;-->
<!-- Team-->
<!-- </x-btn>-->
<x-btn
v-if="!$store.state.windows.nc"
@ -321,146 +151,33 @@
</v-icon> &nbsp;
Crons
</x-btn>
<!-- <x-btn text btn.class="caption font-weight-bold px-2" tooltip="ACL Management"-->
<!-- @click="aclTabAdd()">-->
<!-- <v-icon>-->
<!-- mdi-shield-edit-outline-->
<!-- </v-icon> &nbsp;-->
<!-- ACL-->
<!-- </x-btn>-->
<!-- <span v-shortkey="['ctrl','shift','g']" @shortkey="graphqlClientTabAdd()"></span>-->
<!-- <x-btn v-if="isGql" text btn.class="caption font-weight-bold px-2" tooltip="GraphQL Client (^⇧G)"-->
<!-- @click="graphqlClientTabAdd()">-->
<!-- <v-icon tooltip="GraphQL Client (^⇧G)"-->
<!-- v-if="!$store.state.windows.nc && isGql"-->
<!-- @click="graphqlClientTabAdd()" class="ml-3 " size="20">-->
<!-- mdi-graphql-->
<!-- </v-icon>-->
<!-- <v-icon tooltip="GraphQL Client (^⇧G)"-->
<!-- v-if="isRest"-->
<!-- @click="swaggerClientTabAdd()" class="ml-3 " size="20">-->
<!-- mdi-code-json-->
<!-- </v-icon>-->
<!-- &nbsp;-->
<!-- GraphiQL-->
<!-- </x-btn>-->
<span v-shortkey="['ctrl','shift','g']" @shortkey="graphqlClientTabAdd()"></span>
<!-- <x-btn v-if="isGrpc" text btn.class="caption font-weight-bold px-2" tooltip="GraphQL Client (^⇧G)"-->
<!-- @click="grpcTabAdd()">-->
<v-icon
v-if="!$store.state.windows.nc && isGrpc"
size="20" class="ml-3 " tooltip="GraphQL Client (^⇧G)"
@click="grpcTabAdd()">
mdi-alpha-g-circle-outline
</v-icon>
<!-- &nbsp;-->
<!-- gRPC-->
<!-- </x-btn>-->
<!-- <x-icon iconClass="mr-4" @click="apiClientTabAdd()" tooltip="API Client (^⇧A)">mdi-send-->
<!-- </x-icon>-->
<!-- <x-btn text @click="apiClientSwaggerTabAdd()" tooltip="API Client (^⇧A)"-->
<!-- btn.class="caption font-weight-bold px-2">-->
<v-icon class="ml-3 "
v-if="!$store.state.windows.nc" size="20" @click="apiClientSwaggerTabAdd()"
tooltip="API Client (^⇧A)">mdi-code-json
</v-icon>
<!-- &nbsp; REST Client-->
<!-- </x-btn>-->
<!-- <x-icon iconClass="mr-4" tooltip="Feed (^⇧F)" @click="feedDialog = true">mdi-glasses</x-icon>-->
<!-- <span v-shortkey="['ctrl','shift','f']" @shortkey="feedDialog = true"></span>-->
<span v-shortkey="['ctrl','shift','a']" @shortkey="apiClientTabAdd()"></span>
<!-- <x-btn text btn.class="caption font-weight-bold px-2" @click="terminalTabAdd()"-->
<!-- tooltip="API Generator Console (^⇧T)">-->
<!-- <v-icon key="terminal-dash">-->
<!-- mdi-console-->
<!-- </v-icon>&nbsp;-->
<!-- {{ isDocker ? 'Docker Console' : 'API Generator' }}-->
<!-- </x-btn>-->
<span v-shortkey="[ 'ctrl','shift', 'c']"
@shortkey="settingsDialog = true"></span>
<!-- <span v-shortkey="[ 'ctrl','shift', 'd']"-->
<!-- @shortkey="openDiscord"></span>-->
<!-- <x-icon key="discord-dash" iconClass="mr-4" @click="openDiscord" tooltip="Discord Chat (^⇧D)">mdi-discord-->
<!-- </x-icon>-->
<!-- <x-icon key="github-dash" iconClass="mr-4" @click="openGithub" tooltip="Github">mdi-github-circle-->
<!-- </x-icon>-->
<!-- <span v-shortkey="[ 'ctrl','shift', 'm']"
@shortkey="$store.commit('windows/MutToggleTheme')"></span>
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-icon v-on="on" class="mt-1 ml-3" size="22" @click="$store.commit('windows/MutToggleTheme')">
mdi-format-color-fill
</v-icon>
</template>
Change theme (^M)
</v-tooltip>
<span v-shortkey="[ 'ctrl','shift', 'b']"
@shortkey="changeTheme"></span>
<v-tooltip bottom>
<template v-slot:activator="{ on }">
<v-icon @dblclick="showAppStore=true" @click="changeTheme" v-on="on" size="23"
:style="$vuetify.theme.dark ? {}:{color:'lightgrey'}"
class="ml-3">mdi-bat
</v-icon>
</template>
<h3 class="pa-3">
{{ $vuetify.theme.dark ? 'It does come in Black (^⇧B)' : 'Does it come in Black ? (^⇧B)' }}
<i></i>
</h3>
</v-tooltip>-->
<!-- <v-tooltip bottom>-->
<!-- <template v-slot:activator="{ on }">-->
<!-- <v-icon @click="toggleOutputWindow" class=" ml-3"-->
<!-- v-on="on"-->
<!-- :style="$store.state.windows.outputWindow ? {}:{color:'lightgrey'}">-->
<!-- mdi-page-layout-body-->
<!-- </v-icon>-->
<!-- </template>-->
<!-- <span>Toggle output window (^O)</span>-->
<!-- </v-tooltip>-->
<span v-shortkey="[ 'ctrl','shift', 'o']"
@shortkey="toggleOutputWindow"></span>
<!-- <v-tooltip bottom>-->
<!-- <template v-slot:activator="{ on }">-->
<!-- <v-icon @click="toggleLogWindow" class="ml-4 "-->
<!-- v-on="on"-->
<!-- :style="$store.state.windows.logWindow ? {}:{color:'lightgrey'}">-->
<!-- mdi-page-layout-footer-->
<!-- </v-icon>-->
<!-- </template>-->
<!-- <span>Toggle log window (^L)</span>-->
<!-- </v-tooltip>-->
<span v-shortkey="[ 'ctrl','shift', 'l']"
@shortkey="toggleLogWindow"></span>
@ -552,6 +269,7 @@
<notification class="mx-2"></notification>
<language class="ml-3"/>
<v-menu offset-y open-on-hover
v-if="isAuthenticated">
@ -566,12 +284,6 @@
</template>
<v-list dense>
<v-list-item dense to="/user/settings" v-if="userAuthIsEmail">
<v-list-item-title v-ge="['Settings','']">
<v-icon small>mdi-cog</v-icon> &nbsp; <span class="font-weight-regular">Settings</span>
</v-list-item-title>
</v-list-item>
<v-divider v-if="userAuthIsEmail"></v-divider>
<template v-if="isDocker">
@ -836,9 +548,11 @@ import XBtn from "../components/global/xBtn";
import ChangeEnv from "../components/changeEnv";
import Discord from "@/components/discord";
import {copyTextToClipboard} from "@/helpers/xutils";
import Language from "~/components/utils/language";
export default {
components: {
Language,
Discord,
ChangeEnv,
XBtn,
@ -904,42 +618,16 @@ export default {
isGrpc: 'project/GtrProjectIsGrpc',
role: 'users/GtrRole'
}),
// previewAs: {
// get() {
// return this.$store.state.users.previewAs
// }, set(previewAs) {
// this.$store.commit('users/MutPreviewAs', previewAs);
// }
// },
user() {
// console.log(this.$store);
return this.$store.getters['users/GtrUser'];
},
paidUser() {
},
project() {
},
userAuthIsEmail() {
},
isThisMobile() { // just an example, could be one specific value if that's all you need
return this.isHydrated ? this.$vuetify.breakpoint.smAndDown : false;
},
drawer_status() {
// return this.$store.getters['users/GtrUser'] && this.drawer;
},
},
mounted() {
this.selectedEnv = this.$store.getters['project/GtrActiveEnv'];
this.loadProjectInfo();
// this.checkInactiveState();
},
watch: {
'$route.path': function (path, oldPath) {
@ -1373,6 +1061,7 @@ a {
}
</style>

12
packages/nc-gui/mixins/device.js

@ -1,6 +1,4 @@
import rolePermissions from "@/helpers/rolePermissions";
import {mapGetters} from "vuex";
import browserLang from 'browser-lang';
export default {
data() {
@ -17,16 +15,6 @@ export default {
isLight() {
return this.$vuetify && this.$vuetify.theme && this.$vuetify.theme.light;
},
language() {
// const dummy = new Date();
// const offset = -dummy.getTimezoneOffset();
return browserLang({
languages: ["en", "ar", "nl", "fr", "de", "it", "ja", "ru", "es", "ca", "cs", "et", "lt", "no", "te", "ur", "zh-cn", "da", "tl", "el", "ms", "pl", "sr", "sv", "th", "bn", "zh-tw", "fi", "ko", "iw", "ml", "pt", "sk", "tg", "tr", "vi", "bg", "hr", "eo", "id", "lv", "mr", "ro", "sl", "ta", "uk", "kn", "hi"],
fallback: 'en',
});
},
isThisMobile() { // just an example, could be one specific value if that's all you need
return this.isHydrated ? this.$vuetify && this.$vuetify.breakpoint && this.$vuetify.breakpoint.smAndDown : false;
},

2
packages/nc-gui/pages/index.vue

@ -437,7 +437,7 @@ export default {
},
computed: {
text() {
const text = this.lang.find(it => it.symbol === this.language);
const text = this.lang.find(it => it.symbol === this.$store.state.windows.language);
return text ? text.text : 'default';
},
projectInfo() {

10
packages/nc-gui/plugins/i18n.js

@ -11,7 +11,7 @@ export default ({app, store}) => {
// This way we can use it globally in our components through this.$i18n
app.i18n = new VueI18n({
// Set the initial locale
locale: "en",
locale: store.state.windows.language,
// Set the fallback locale in case the current locale can't be found
fallbackLocale: "en",
@ -20,14 +20,18 @@ export default ({app, store}) => {
messages: {
en: require("~/static/lang/en.json"),
zh: require("~/static/lang/zh.json"),
ja: require("~/static/lang/ja.json"),
// ja: require("~/static/lang/ja.json"),
fr: require("~/static/lang/fr.json")
}
});
store.watch(
(state) => state.windows.language,
(language) => app.i18n.locale = language
(language) => {
if (app.i18n.availableLocales.includes(language)) {
app.i18n.locale = language
}
}
);
};
/**

9
packages/nc-gui/store/windows.js

@ -1,7 +1,7 @@
// import moment from 'moment';
import themes from "../helpers/themes";
import browserLang from "browser-lang";
// const {machineId} = require('electron').remote.require('./libs');
const defaultTheme = {
"primary": "#0989ff",
@ -24,7 +24,10 @@ export const state = () => ({
isGaEnabled: true,
isErrorReportingEnabled: true,
customTheme: {},
language: 'en',
language: browserLang({
languages: ["en", "ar", "nl", "fr", "de", "it", "ja", "ru", "es", "ca", "cs", "et", "lt", "no", "te", "ur", "zh-cn", "da", "tl", "el", "ms", "pl", "sr", "sv", "th", "bn", "zh-tw", "fi", "ko", "iw", "ml", "pt", "sk", "tg", "tr", "vi", "bg", "hr", "eo", "id", "lv", "mr", "ro", "sl", "ta", "uk", "kn", "hi"],
fallback: 'en',
}),
showTour: {
home: true,
dashboard: true
@ -79,7 +82,7 @@ export const mutations = {
state.theme = themes[state.themeName];
}, MutSetCustomTheme(state, theme) {
state.customTheme = theme;
}, MutSetLanguage(state, language) {
}, MutLanguage(state, language) {
state.language = language;
},
MutToggleTreeviewWindow(state, show) {

Loading…
Cancel
Save