Browse Source

Merge branch 'master' of github.com:nocodb/nocodb

pull/301/head
Pranav C 3 years ago
parent
commit
bd9e24b146
  1. 2
      README.md
  2. 4
      packages/nc-gui/components/changeEnv.vue
  3. 2
      packages/nc-gui/components/createOrEditProject.vue
  4. 2
      packages/nc-gui/components/project/graphqlClient.vue
  5. 4
      packages/nc-gui/components/project/settings/env.vue
  6. 2
      packages/nc-gui/components/project/spreadsheet/apis/gqlApi.js
  7. 2
      packages/nc-gui/components/project/swaggerClient.vue
  8. 5
      packages/nc-gui/components/project/xcInfo.vue
  9. 4
      packages/nc-gui/layouts/default.vue
  10. 29
      packages/nc-gui/nuxt.config.js
  11. 3
      packages/nc-gui/pages/nc/_project_id.vue
  12. 4
      packages/nc-gui/pages/project/id.vue
  13. 12
      packages/nc-gui/pages/user/authentication/signin.vue
  14. 5
      packages/nc-gui/pages/user/authentication/signup/_token.vue
  15. 3
      packages/nc-gui/pages/user/authentication/signup/index.vue
  16. 27
      packages/nc-gui/plugins/projectLoader.js
  17. 5
      packages/nc-gui/store/graphqlClient.js
  18. 5
      packages/nc-gui/store/project.js
  19. 10
      packages/nc-gui/store/sqlMgr.js
  20. 5
      packages/nc-gui/store/users.js

2
README.md

@ -154,6 +154,7 @@ docker run -d -p 8080:8080 \
## Docker Compose ## Docker Compose
``` ```
git clone https://github.com/nocodb/nocodb
cd docker-compose cd docker-compose
cd mysql or pg or mssql cd mysql or pg or mssql
docker-compose up docker-compose up
@ -170,6 +171,7 @@ docker-compose up
| NC_SENTRY_DSN | No | For Sentry monitoring | | | NC_SENTRY_DSN | No | For Sentry monitoring | |
| NC_CONNECT_TO_EXTERNAL_DB_DISABLED | No | Disable Project creation with external database | | | NC_CONNECT_TO_EXTERNAL_DB_DISABLED | No | Disable Project creation with external database | |
| NC_DISABLE_TELE | No | Disable telemetry | | | NC_DISABLE_TELE | No | Disable telemetry | |
| NC_BACKEND_URL | No | Custom Backend URL | ``http://localhost:8080`` will be used |
# Running locally # Running locally
``` ```

4
packages/nc-gui/components/changeEnv.vue

@ -72,8 +72,7 @@
await new Promise(resolve => { await new Promise(resolve => {
const interv = setInterval(() => { const interv = setInterval(() => {
axios.create({ axios.create({
baseURL: process.env.NODE_ENV === 'production' ? './' : 'http://localhost:8080/dashboard', baseURL: `${this.$axios.defaults.baseURL}/dashboard`,
// baseURL: 'http://localhost:8080/dashboard',
}).get('').then(() => { }).get('').then(() => {
this.projectReloading = false; this.projectReloading = false;
clearInterval(interv); clearInterval(interv);
@ -105,6 +104,7 @@
* *
* @author Naveen MR <oof1lab@gmail.com> * @author Naveen MR <oof1lab@gmail.com>
* @author Pranav C Balan <pranavxc@gmail.com> * @author Pranav C Balan <pranavxc@gmail.com>
* @author Wing-Kam Wong <wingkwong.code@gmail.com>
* *
* @license GNU AGPL version 3 or any later version * @license GNU AGPL version 3 or any later version
* *

2
packages/nc-gui/components/createOrEditProject.vue

@ -1388,7 +1388,7 @@ export default {
this.allSchemas = true; this.allSchemas = true;
await this.$axios({ await this.$axios({
url: 'demo', url: 'demo',
baseURL: process.env.NODE_ENV === 'production' ? './' : 'http://localhost:8080/dashboard', baseURL: `${this.$axios.defaults.baseURL}/dashboard`,
}); });
}, },

2
packages/nc-gui/components/project/graphqlClient.vue

@ -55,7 +55,7 @@ export default {
if (this.$store.state.graphqlClient.list && this.$store.state.graphqlClient.list[0]) if (this.$store.state.graphqlClient.list && this.$store.state.graphqlClient.list[0])
this.webViewUrl = this.url = this.$store.state.graphqlClient.list[0].url; this.webViewUrl = this.url = this.$store.state.graphqlClient.list[0].url;
try { try {
const {info} = (await this.$axios.get(`/nc/${this.$route.params.project_id}/projectApiInfo`, { const {info} = (await this.$axios.get(`${this.$axios.defaults.baseURL}/nc/${this.$route.params.project_id}/projectApiInfo`, {
headers: { headers: {
'xc-auth': this.$store.state.users.token 'xc-auth': this.$store.state.users.token
} }

4
packages/nc-gui/components/project/settings/env.vue

@ -62,8 +62,7 @@ export default {
await new Promise(resolve => { await new Promise(resolve => {
const interv = setInterval(() => { const interv = setInterval(() => {
axios.create({ axios.create({
baseURL: process.env.NODE_ENV === 'production' ? './' : 'http://localhost:8080/dashboard', baseURL: `${this.$axios.defaults.baseURL}/dashboard`
// baseURL: 'http://localhost:8080/dashboard',
}).get('').then(() => { }).get('').then(() => {
this.projectReloading = false; this.projectReloading = false;
clearInterval(interv); clearInterval(interv);
@ -94,6 +93,7 @@ export default {
* *
* @author Naveen MR <oof1lab@gmail.com> * @author Naveen MR <oof1lab@gmail.com>
* @author Pranav C Balan <pranavxc@gmail.com> * @author Pranav C Balan <pranavxc@gmail.com>
* @author Wing-Kam Wong <wingkwong.code@gmail.com>
* *
* @license GNU AGPL version 3 or any later version * @license GNU AGPL version 3 or any later version
* *

2
packages/nc-gui/components/project/spreadsheet/apis/gqlApi.js

@ -29,7 +29,7 @@ export default class GqlApi {
post(url, params) { post(url, params) {
return this.$axios({ return this.$axios({
url, url: `${this.$axios.defaults.baseURL}/${url}`,
method: 'post', method: 'post',
data: params, data: params,
}) })

2
packages/nc-gui/components/project/swaggerClient.vue

@ -55,7 +55,7 @@ export default {
// if (this.$store.state.graphqlClient.list && this.$store.state.graphqlClient.list[0]) // if (this.$store.state.graphqlClient.list && this.$store.state.graphqlClient.list[0])
// this.webViewUrl = this.url = this.$store.state.graphqlClient.list[0].url; // this.webViewUrl = this.url = this.$store.state.graphqlClient.list[0].url;
try { try {
const {info} = (await this.$axios.get(`/nc/${this.$route.params.project_id}/projectApiInfo`, { const {info} = (await this.$axios.get(`${this.$axios.defaults.baseURL}/nc/${this.$route.params.project_id}/projectApiInfo`, {
headers: { headers: {
'xc-auth': this.$store.state.users.token 'xc-auth': this.$store.state.users.token
} }

5
packages/nc-gui/components/project/xcInfo.vue

@ -241,7 +241,7 @@ export default {
async created() { async created() {
await this.loadProjectApiInfo(); await this.loadProjectApiInfo();
try { try {
this.iframeUrl = this._isDev ? 'http://localhost:8080/dashboard/status' : './status'; this.iframeUrl = `${this.$axios.defaults.baseURL}/dashboard/status`;
const res = await this.$axios.get(this.iframeUrl); const res = await this.$axios.get(this.iframeUrl);
this.showinfoIFrame = true; this.showinfoIFrame = true;
} catch (e) { } catch (e) {
@ -252,7 +252,7 @@ export default {
}, methods: { }, methods: {
async loadProjectApiInfo() { async loadProjectApiInfo() {
try { try {
const {info, aggregatedInfo} = (await this.$axios.get(`/nc/${this.$route.params.project_id}/projectApiInfo`, { const {info, aggregatedInfo} = (await this.$axios.get(`${this.$axios.defaults.baseURL}/nc/${this.$route.params.project_id}/projectApiInfo`, {
headers: { headers: {
'xc-auth': this.$store.state.users.token 'xc-auth': this.$store.state.users.token
} }
@ -322,6 +322,7 @@ iframe {
* *
* @author Naveen MR <oof1lab@gmail.com> * @author Naveen MR <oof1lab@gmail.com>
* @author Pranav C Balan <pranavxc@gmail.com> * @author Pranav C Balan <pranavxc@gmail.com>
* @author Wing-Kam Wong <wingkwong.code@gmail.com>
* *
* @license GNU AGPL version 3 or any later version * @license GNU AGPL version 3 or any later version
* *

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

@ -624,7 +624,7 @@
</v-list-item-title> </v-list-item-title>
</v-list-item>--> </v-list-item>-->
<v-list-item v-if="swaggerOrGraphiqlUrl" dense @click.stop="openUrl(swaggerOrGraphiqlUrl)"> <v-list-item v-if="swaggerOrGraphiqlUrl" dense @click.stop="openUrl(`${$axios.defaults.baseURL}${swaggerOrGraphiqlUrl}`)">
<v-list-item-title> <v-list-item-title>
<v-icon small key="terminal-dash"> <v-icon small key="terminal-dash">
@ -977,7 +977,7 @@ export default {
async loadProjectInfo() { async loadProjectInfo() {
if (this.$route.params.project_id) if (this.$route.params.project_id)
try { try {
const {info} = (await this.$axios.get(`/nc/${this.$route.params.project_id}/projectApiInfo`, { const {info} = (await this.$axios.get(`${this.$axios.defaults.baseURL}/nc/${this.$route.params.project_id}/projectApiInfo`, {
headers: { headers: {
'xc-auth': this.$store.state.users.token 'xc-auth': this.$store.state.users.token
} }

29
packages/nc-gui/nuxt.config.js

@ -86,9 +86,7 @@ export default {
** See https://axios.nuxtjs.org/options ** See https://axios.nuxtjs.org/options
*/ */
axios: { axios: {
baseURL: process.env.NODE_ENV === 'production' ? '../' : 'http://localhost:8080/', baseURL: process.env.NC_BACKEND_URL || (process.env.NODE_ENV === 'production' ? '../' : 'http://localhost:8080/'),
// baseURL: 'http://localhost:8080/',
// baseURL: 'http://localhost:8080/',
}, },
/* /*
** vuetify module configuration ** vuetify module configuration
@ -218,6 +216,7 @@ export default {
* *
* @author Naveen MR <oof1lab@gmail.com> * @author Naveen MR <oof1lab@gmail.com>
* @author Pranav C Balan <pranavxc@gmail.com> * @author Pranav C Balan <pranavxc@gmail.com>
* @author Wing-Kam Wong <wingkwong.code@gmail.com>
* *
* @license GNU AGPL version 3 or any later version * @license GNU AGPL version 3 or any later version
* *
@ -234,26 +233,4 @@ export default {
* You should have received a copy of the GNU Affero General Public License * 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/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
/**
* @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/>.
*
*/

3
packages/nc-gui/pages/nc/_project_id.vue

@ -47,7 +47,7 @@ export default {
this.$router.replace({query: {}}) this.$router.replace({query: {}})
} }
try { try {
hj('stateChange', 'http://localhost:8080/dashboard/#/nc/'); hj('stateChange', `${this.$axios.defaults.baseURL}/dashboard/#/nc/`);
} catch (e) { } catch (e) {
} }
}, },
@ -112,6 +112,7 @@ export default {
* *
* @author Naveen MR <oof1lab@gmail.com> * @author Naveen MR <oof1lab@gmail.com>
* @author Pranav C Balan <pranavxc@gmail.com> * @author Pranav C Balan <pranavxc@gmail.com>
* @author Wing-Kam Wong <wingkwong.code@gmail.com>
* *
* @license GNU AGPL version 3 or any later version * @license GNU AGPL version 3 or any later version
* *

4
packages/nc-gui/pages/project/id.vue

@ -1113,8 +1113,7 @@ export default {
} }
axios.create({ axios.create({
baseURL: process.env.NODE_ENV === 'production' ? './' : 'http://localhost:8080/dashboard', baseURL: `${this.$axios.defaults.baseURL}/dashboard`,
// baseURL: 'http://localhost:8080/dashboard',
}).get('').then(() => { }).get('').then(() => {
toast.goAway(100); toast.goAway(100);
this.projectReloading = false; this.projectReloading = false;
@ -1692,6 +1691,7 @@ export default {
* *
* @author Naveen MR <oof1lab@gmail.com> * @author Naveen MR <oof1lab@gmail.com>
* @author Pranav C Balan <pranavxc@gmail.com> * @author Pranav C Balan <pranavxc@gmail.com>
* @author Wing-Kam Wong <wingkwong.code@gmail.com>
* *
* @license GNU AGPL version 3 or any later version * @license GNU AGPL version 3 or any later version
* *

12
packages/nc-gui/pages/user/authentication/signin.vue

@ -105,11 +105,7 @@
<div> <div>
<v-btn <v-btn
v-if="googleAuthEnabled" v-if="googleAuthEnabled"
:href=" :href="`${$axios.defaults.baseURL}/auth/google`"
_isDev
? 'http://localhost:8080/auth/google'
: '../auth/google'
"
outlined outlined
large large
elevation-10 elevation-10
@ -126,11 +122,7 @@
</v-btn> </v-btn>
<v-btn <v-btn
v-if="githubAuthEnabled" v-if="githubAuthEnabled"
:href=" :href="`${$axios.defaults.baseURL}/auth/google`"
_isDev
? 'http://localhost:8080/auth/github'
: '../auth/github'
"
outlined outlined
large large
elevation-10 elevation-10

5
packages/nc-gui/pages/user/authentication/signup/_token.vue

@ -98,7 +98,7 @@
<v-btn <v-btn
v-if="googleAuthEnabled" v-if="googleAuthEnabled"
:href="(_isDev ?'http://localhost:8080/auth/google':'../auth/google') + `?state=${token}`" outlined :href="`${$axios.defaults.baseURL}/auth/google?state=${token}`" outlined
large elevation-10 large elevation-10
block block
color="blue"> color="blue">
@ -154,7 +154,7 @@
<!-- <v-btn <!-- <v-btn
v-if="googleAuthEnabled" v-if="googleAuthEnabled"
:href="(_isDev ?'http://localhost:8080/auth/google':'../auth/google') + `?state=${token}`" outlined :href="`${$axios.defaults.baseURL}/auth/google?state=${token}`" outlined
large elevation-10 large elevation-10
block block
color="blue"> color="blue">
@ -500,6 +500,7 @@ export default {
* *
* @author Naveen MR <oof1lab@gmail.com> * @author Naveen MR <oof1lab@gmail.com>
* @author Pranav C Balan <pranavxc@gmail.com> * @author Pranav C Balan <pranavxc@gmail.com>
* @author Wing-Kam Wong <wingkwong.code@gmail.com>
* *
* @license GNU AGPL version 3 or any later version * @license GNU AGPL version 3 or any later version
* *

3
packages/nc-gui/pages/user/authentication/signup/index.vue

@ -131,7 +131,7 @@
<v-btn <v-btn
v-if="googleAuthEnabled" v-if="googleAuthEnabled"
:href="_isDev ?'http://localhost:8080/auth/google':'../auth/google'" outlined large elevation-10 :href="`${this.$axios.defaults.baseURL}/auth/google`" outlined large elevation-10
block block
color="blue"> color="blue">
<img :src="require('~/assets/img/gmail.png')" <img :src="require('~/assets/img/gmail.png')"
@ -482,6 +482,7 @@ export default {
* *
* @author Naveen MR <oof1lab@gmail.com> * @author Naveen MR <oof1lab@gmail.com>
* @author Pranav C Balan <pranavxc@gmail.com> * @author Pranav C Balan <pranavxc@gmail.com>
* @author Wing-Kam Wong <wingkwong.code@gmail.com>
* *
* @license GNU AGPL version 3 or any later version * @license GNU AGPL version 3 or any later version
* *

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

@ -5,7 +5,7 @@ export default async ({store, redirect, $axios, $toast}) => {
&& /\bcode=/.test(window.location.search)) { && /\bcode=/.test(window.location.search)) {
try { try {
const tokenData = await $axios.create({ const tokenData = await $axios.create({
baseURL: process.env.NODE_ENV === 'production' ? '../' : 'http://localhost:8080/', baseURL: $axios.defaults.baseURL,
}).post(`/auth/${window.location.search.indexOf('state=github') > -1 ? 'github' : 'google'}/genTokenByCode${window.location.search}`); }).post(`/auth/${window.location.search.indexOf('state=github') > -1 ? 'github' : 'google'}/genTokenByCode${window.location.search}`);
store.commit('users/MutSetToken', tokenData.data.token); store.commit('users/MutSetToken', tokenData.data.token);
@ -68,6 +68,7 @@ export default async ({store, redirect, $axios, $toast}) => {
* *
* @author Naveen MR <oof1lab@gmail.com> * @author Naveen MR <oof1lab@gmail.com>
* @author Pranav C Balan <pranavxc@gmail.com> * @author Pranav C Balan <pranavxc@gmail.com>
* @author Wing-Kam Wong <wingkwong.code@gmail.com>
* *
* @license GNU AGPL version 3 or any later version * @license GNU AGPL version 3 or any later version
* *
@ -84,26 +85,4 @@ export default async ({store, redirect, $axios, $toast}) => {
* You should have received a copy of the GNU Affero General Public License * 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/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
/**
* @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/>.
*
*/

5
packages/nc-gui/store/graphqlClient.js

@ -11,7 +11,7 @@ export const state = () => ({
* *
*/ */
list: [{ list: [{
url: 'http://localhost:8080/graphql' url: `${process.env.NC_BACKEND_URL || 'http://localhost:8080'}/graphql`
}] }]
}); });
@ -33,13 +33,12 @@ export const actions = {
}; };
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
* *
* @author Naveen MR <oof1lab@gmail.com> * @author Naveen MR <oof1lab@gmail.com>
* @author Pranav C Balan <pranavxc@gmail.com> * @author Pranav C Balan <pranavxc@gmail.com>
* @author Wing-Kam Wong <wingkwong.code@gmail.com>
* *
* @license GNU AGPL version 3 or any later version * @license GNU AGPL version 3 or any later version
* *

5
packages/nc-gui/store/project.js

@ -583,19 +583,20 @@ export const actions = {
async ActLoadProjectInfo({commit}) { async ActLoadProjectInfo({commit}) {
const projectInfo = (await this.$axios({ const projectInfo = (await this.$axios({
url: '/auth/type', url: '/auth/type',
baseURL: process.env.NODE_ENV === 'production' ? './' : 'http://localhost:8080/dashboard', baseURL: `${this.$axios.defaults.baseURL}/dashboard`,
// baseURL: 'http://localhost:8080/dashboard',
method: 'get' method: 'get'
})).data; })).data;
commit('MutProjectInfo', projectInfo) commit('MutProjectInfo', projectInfo)
} }
}; };
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
* *
* @author Naveen MR <oof1lab@gmail.com> * @author Naveen MR <oof1lab@gmail.com>
* @author Pranav C Balan <pranavxc@gmail.com> * @author Pranav C Balan <pranavxc@gmail.com>
* @author Wing-Kam Wong <wingkwong.code@gmail.com>
* *
* @license GNU AGPL version 3 or any later version * @license GNU AGPL version 3 or any later version
* *

10
packages/nc-gui/store/sqlMgr.js

@ -339,8 +339,7 @@ export const actions = {
// result = await state.sqlMgr.sqlOpPlus(args, op, opArgs); // result = await state.sqlMgr.sqlOpPlus(args, op, opArgs);
result = (await this.$axios({ result = (await this.$axios({
url: '?q=sqlOpPlus_' + op, url: '?q=sqlOpPlus_' + op,
baseURL: process.env.NODE_ENV === 'production' ? './' : 'http://localhost:8080/dashboard', baseURL: `${this.$axios.defaults.baseURL}/dashboard`,
// baseURL: 'http://localhost:8080/dashboard',
data: {api: op, ...args, ...params, args: opArgs, sqlOpPlus: true}, data: {api: op, ...args, ...params, args: opArgs, sqlOpPlus: true},
headers, headers,
method: 'post' method: 'post'
@ -377,8 +376,7 @@ export const actions = {
} }
return (await this.$axios({ return (await this.$axios({
url: '?q=sqlOp_' + op, url: '?q=sqlOp_' + op,
baseURL: process.env.NODE_ENV === 'production' ? './' : 'http://localhost:8080/dashboard', baseURL: `${this.$axios.defaults.baseURL}/dashboard`,
// baseURL: 'http://localhost:8080/dashboard',
data: {api: op, ...args, ...params, args: opArgs}, data: {api: op, ...args, ...params, args: opArgs},
headers, headers,
method: 'post', method: 'post',
@ -423,8 +421,7 @@ export const actions = {
return (await this.$axios({ return (await this.$axios({
url: '?q=sqlOp_' + op, url: '?q=sqlOp_' + op,
baseURL: process.env.NODE_ENV === 'production' ? './' : 'http://localhost:8080/dashboard', baseURL: `${$this.axios.defaults.baseURL}/dashboard`,
// baseURL: 'http://localhost:8080/dashboard',
data: formData, //{api: op, ...args, args: opArgs}, data: formData, //{api: op, ...args, args: opArgs},
headers, headers,
method: 'post', method: 'post',
@ -445,6 +442,7 @@ export const actions = {
* *
* @author Naveen MR <oof1lab@gmail.com> * @author Naveen MR <oof1lab@gmail.com>
* @author Pranav C Balan <pranavxc@gmail.com> * @author Pranav C Balan <pranavxc@gmail.com>
* @author Wing-Kam Wong <wingkwong.code@gmail.com>
* *
* @license GNU AGPL version 3 or any later version * @license GNU AGPL version 3 or any later version
* *

5
packages/nc-gui/store/users.js

@ -497,8 +497,7 @@ export const actions = {
return (await this.$axios({ return (await this.$axios({
url: '/auth/admin/verify', url: '/auth/admin/verify',
baseURL: process.env.NODE_ENV === 'production' ? './' : 'http://localhost:8080/dashboard', baseURL: `${this.$axios.defaults.baseURL}/dashboard`,
// baseURL: 'http://localhost:8080/dashboard',
method: 'post', method: 'post',
data: {secret} data: {secret}
})).data; })).data;
@ -531,11 +530,13 @@ export const actions = {
// actions, // actions,
// mutations // mutations
// } // }
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
* *
* @author Naveen MR <oof1lab@gmail.com> * @author Naveen MR <oof1lab@gmail.com>
* @author Pranav C Balan <pranavxc@gmail.com> * @author Pranav C Balan <pranavxc@gmail.com>
* @author Wing-Kam Wong <wingkwong.code@gmail.com>
* *
* @license GNU AGPL version 3 or any later version * @license GNU AGPL version 3 or any later version
* *

Loading…
Cancel
Save