Browse Source

Merge branch 'develop' into refactor/product-analytics

pull/1795/head
Raju Udava 2 years ago committed by GitHub
parent
commit
299907fa16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      .all-contributorsrc
  2. 7
      .github/workflows/sync-to-develop.yml
  3. 1
      README.md
  4. 7
      packages/nc-gui/assets/style/style.css
  5. 11
      packages/nc-gui/components/auth/shareOrInviteModal.vue
  6. 34
      packages/nc-gui/components/auth/userManagement.vue
  7. 2
      packages/nc-gui/components/importantAnnouncement.vue
  8. 2
      packages/nc-gui/components/project/appStore/inputs/checkboxField.vue
  9. 1
      packages/nc-gui/components/project/auditTab/db.vue
  10. 6
      packages/nc-gui/components/project/spreadsheet/components/columnFilter.vue
  11. 1
      packages/nc-gui/components/project/spreadsheet/components/editColumn/lookupOptions.vue
  12. 2
      packages/nc-gui/components/project/spreadsheet/components/editVirtualColumn.vue
  13. 7
      packages/nc-gui/components/project/spreadsheet/components/editableCell.vue
  14. 4
      packages/nc-gui/components/project/spreadsheet/components/importExport/columnMappingModal.vue
  15. 2
      packages/nc-gui/components/project/spreadsheet/components/sortListMenu.vue
  16. 28
      packages/nc-gui/components/project/spreadsheet/helpers/imageExt.js
  17. 2
      packages/nc-gui/components/project/spreadsheet/mixins/spreadsheet.js
  18. 10
      packages/nc-gui/components/project/spreadsheet/rowsXcDataTable.vue
  19. 4
      packages/nc-gui/components/project/spreadsheet/views/formView.vue
  20. 1
      packages/nc-gui/components/project/tableTabs/aclTsFileDbChild.vue
  21. 17
      packages/nc-gui/components/templates/help.vue
  22. 1
      packages/nc-gui/components/trialExpired.vue
  23. 41
      packages/nc-gui/helpers/index.js
  24. 2
      packages/nc-gui/lang/da.json
  25. 2
      packages/nc-gui/lang/de.json
  26. 2
      packages/nc-gui/lang/en.json
  27. 2
      packages/nc-gui/lang/es.json
  28. 2
      packages/nc-gui/lang/fi.json
  29. 2
      packages/nc-gui/lang/fr.json
  30. 2
      packages/nc-gui/lang/id.json
  31. 2
      packages/nc-gui/lang/it_IT.json
  32. 2
      packages/nc-gui/lang/iw.json
  33. 2
      packages/nc-gui/lang/ko.json
  34. 2
      packages/nc-gui/lang/no.json
  35. 2
      packages/nc-gui/lang/pt.json
  36. 2
      packages/nc-gui/lang/pt_BR.json
  37. 2
      packages/nc-gui/lang/sv.json
  38. 2
      packages/nc-gui/lang/th.json
  39. 2
      packages/nc-gui/lang/uk.json
  40. 2
      packages/nc-gui/lang/vi.json
  41. 27
      packages/nc-gui/layouts/default.vue
  42. 3
      packages/nc-gui/layouts/public.vue
  43. 6
      packages/nc-gui/package-lock.json
  44. 2
      packages/nc-gui/package.json
  45. 2
      packages/nc-gui/pages/projects/index.vue
  46. 74
      packages/nc-gui/plugins/i18n.js
  47. 4
      packages/nc-gui/store/app.js
  48. 1
      packages/nc-gui/xc.js
  49. 2
      packages/nc-lib-gui/package.json
  50. 1
      packages/noco-docs/content/en/developer-resources/rest-apis.md
  51. 2
      packages/nocodb-sdk/package-lock.json
  52. 2
      packages/nocodb-sdk/package.json
  53. 23
      packages/nocodb-sdk/src/lib/Api.ts
  54. 14
      packages/nocodb/package-lock.json
  55. 6
      packages/nocodb/package.json
  56. 76
      packages/nocodb/src/lib/noco/meta/api/projectUserApis.ts
  57. 2
      packages/nocodb/src/lib/noco/meta/helpers/NcPluginMgrv2.ts
  58. 3
      packages/nocodb/src/lib/utils/projectAcl.ts
  59. 47
      scripts/sdk/swagger.json

9
.all-contributorsrc

@ -729,6 +729,15 @@
"contributions": [ "contributions": [
"code" "code"
] ]
},
{
"login": "iamnamananand996",
"name": "Naman Anand",
"avatar_url": "https://avatars.githubusercontent.com/u/31537362?v=4",
"profile": "https://github.com/iamnamananand996",
"contributions": [
"code"
]
} }
], ],
"contributorsPerLine": 7, "contributorsPerLine": 7,

7
.github/workflows/sync-to-develop.yml

@ -9,16 +9,11 @@ jobs:
sync-to-develop: sync-to-develop:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
# See https://github.com/actions/checkout/issues/766
- name: Workaround for unsafe repository issue
run: |
git config --global --add safe.directory ${GITHUB_WORKSPACE}
- name: Checkout - name: Checkout
uses: actions/checkout@v1 uses: actions/checkout@v1
- name: Merge from master to develop - name: Merge from master to develop
uses: robotology/gh-action-nightly-merge@v1.3.1 uses: wingkwong/gh-action-nightly-merge@master
with: with:
stable_branch: 'master' stable_branch: 'master'
development_branch: 'develop' development_branch: 'develop'

1
README.md

@ -442,6 +442,7 @@ Our mission is to provide the most powerful no-code interface for databases whic
<td align="center"><a href="https://github.com/RobinFrcd"><img src="https://avatars.githubusercontent.com/u/29704178?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Robin Fourcade</b></sub></a><br /><a href="https://github.com/nocodb/nocodb/commits?author=RobinFrcd" title="Code">💻</a></td> <td align="center"><a href="https://github.com/RobinFrcd"><img src="https://avatars.githubusercontent.com/u/29704178?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Robin Fourcade</b></sub></a><br /><a href="https://github.com/nocodb/nocodb/commits?author=RobinFrcd" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/zprial"><img src="https://avatars.githubusercontent.com/u/33095380?v=4?s=100" width="100px;" alt=""/><br /><sub><b>zprial</b></sub></a><br /><a href="https://github.com/nocodb/nocodb/commits?author=zprial" title="Code">💻</a></td> <td align="center"><a href="https://github.com/zprial"><img src="https://avatars.githubusercontent.com/u/33095380?v=4?s=100" width="100px;" alt=""/><br /><sub><b>zprial</b></sub></a><br /><a href="https://github.com/nocodb/nocodb/commits?author=zprial" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/nilsreichardt"><img src="https://avatars.githubusercontent.com/u/24459435?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nils Reichardt</b></sub></a><br /><a href="https://github.com/nocodb/nocodb/commits?author=nilsreichardt" title="Code">💻</a></td> <td align="center"><a href="https://github.com/nilsreichardt"><img src="https://avatars.githubusercontent.com/u/24459435?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Nils Reichardt</b></sub></a><br /><a href="https://github.com/nocodb/nocodb/commits?author=nilsreichardt" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/iamnamananand996"><img src="https://avatars.githubusercontent.com/u/31537362?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Naman Anand</b></sub></a><br /><a href="https://github.com/nocodb/nocodb/commits?author=iamnamananand996" title="Code">💻</a></td>
</tr> </tr>
</table> </table>

7
packages/nc-gui/assets/style/style.css

@ -362,3 +362,10 @@ html {
.cursor-pointer{ .cursor-pointer{
cursor: pointer; cursor: pointer;
} }
/* sorting and filter */
.menu-filter-dropdown {
max-height: 500px;
overflow-y: auto;
}

11
packages/nc-gui/components/auth/shareOrInviteModal.vue

@ -43,15 +43,8 @@
</v-alert> </v-alert>
<p class="caption grey--text mt-3"> <p class="caption grey--text mt-3">
{{ $t("msg.info.userInviteNoSMTP") }} <!-- Looks like you have not configured mailer yet! <br> Please copy above invite link and send it to -->
<!-- Looks like you have not configured mailer yet! <br>Please copy above --> <pre>{{ $t('msg.info.userInviteNoSMTP') }} {{ invite_token && (invite_token.email || invite_token.emails && invite_token.emails.join(', ')) }}.</pre>
<!-- invite -->
<!-- link and send it to -->
{{
invite_token &&
(invite_token.email ||
(invite_token.emails && invite_token.emails.join(", ")))
}}.
</p> </p>
<div class="text-right"> <div class="text-right">

34
packages/nc-gui/components/auth/userManagement.vue

@ -314,15 +314,10 @@
</v-alert> </v-alert>
<p class="caption grey--text mt-3"> <p class="caption grey--text mt-3">
{{ $t("msg.info.userInviteNoSMTP") }}
<!-- Looks like you have not configured mailer yet! <br>Please copy above --> <!-- Looks like you have not configured mailer yet! <br> Please copy above invite link and send it to -->
<!-- invite --> <pre>{{ $t('msg.info.userInviteNoSMTP') }} {{ invite_token && (invite_token.email || invite_token.emails && invite_token.emails.join(', ')) }}.</pre>
<!-- link and send it to -->
{{
invite_token &&
(invite_token.email ||
(invite_token.emails && invite_token.emails.join(", ")))
}}.
</p> </p>
<div class="text-right"> <div class="text-right">
@ -646,22 +641,11 @@ export default {
}, },
async resendInvite(id) { async resendInvite(id) {
try { try {
await this.$axios.post(
"/admin/resendInvite/" + id, await this.$api.auth.projectUserResendInvite(this.$route.params.project_id, id)
{ this.$toast.success('Invite email sent successfully').goAway(3000)
projectName: this.$store.getters["project/GtrProjectName"], await this.loadUsers()
},
{
headers: {
"xc-auth": this.$store.state.users.token,
},
params: {
project_id: this.$route.params.project_id,
},
}
);
this.$toast.success("Invite email sent successfully").goAway(3000);
await this.loadUsers();
} catch (e) { } catch (e) {
this.$toast.error(e.response.data.msg).goAway(3000); this.$toast.error(e.response.data.msg).goAway(3000);
} }

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

@ -67,7 +67,7 @@ export default {
set(val) { set(val) {
return this.$store.commit('app/MutHiddenAnnouncement', val ? null : true) return this.$store.commit('app/MutHiddenAnnouncement', val ? null : true)
} }
}, }
}, },
mounted() { mounted() {
setTimeout(() => { setTimeout(() => {

2
packages/nc-gui/components/project/appStore/inputs/checkboxField.vue

@ -28,7 +28,7 @@ export default {
const $listeners = {} const $listeners = {}
return $listeners return $listeners
} }
}, }
} }
</script> </script>

1
packages/nc-gui/components/project/auditTab/db.vue

@ -407,7 +407,6 @@ export default {
}, },
async migrationUp(steps = 99999999999) { async migrationUp(steps = 99999999999) {
try { try {
await this.$store.dispatch('sqlMgr/ActSqlOp', [null, 'migrationsUp', { await this.$store.dispatch('sqlMgr/ActSqlOp', [null, 'migrationsUp', {
env: this.nodes.env, env: this.nodes.env,
dbAlias: this.nodes.dbAlias, dbAlias: this.nodes.dbAlias,

6
packages/nc-gui/components/project/spreadsheet/components/columnFilter.vue

@ -1,7 +1,9 @@
<template> <template>
<div <div
class="backgroundColor pa-2"
:style="{ width: nested ? '100%' : '530px' }" class="backgroundColor pa-2 menu-filter-dropdown"
:style="{width:nested ? '100%' : '530px'}"
> >
<div class="grid" @click.stop> <div class="grid" @click.stop>
<template v-for="(filter, i) in filters" dense> <template v-for="(filter, i) in filters" dense>

1
packages/nc-gui/components/project/spreadsheet/components/editColumn/lookupOptions.vue

@ -78,7 +78,6 @@ export default {
})) }))
return refTables return refTables
}, },
columnList() { columnList() {
return (( return ((

2
packages/nc-gui/components/project/spreadsheet/components/editVirtualColumn.vue

@ -6,7 +6,7 @@
style="overflow: auto" style="overflow: auto"
class=" card nc-col-create-or-edit-card" class=" card nc-col-create-or-edit-card"
> >
<v-form v-model="valid"> <v-form v-model="valid" @submit.prevent="save">
<v-container fluid @click.stop.prevent> <v-container fluid @click.stop.prevent>
<v-row> <v-row>
<v-col cols="12"> <v-col cols="12">

7
packages/nc-gui/components/project/spreadsheet/components/editableCell.vue

@ -184,10 +184,8 @@ export default {
this.$emit('input', val) this.$emit('input', val)
if (this.isAttachment || this.isEnum || this.isBoolean || this.isSet || this.isTime || this.isDateTime || this.isDate) { if (this.isAttachment || this.isEnum || this.isBoolean || this.isSet || this.isTime || this.isDateTime || this.isDate) {
this.syncData() this.syncData()
} else { } else if (!this.isCurrency) {
if (!this.isCurrency) { this.syncDataDebounce(this)
this.syncDataDebounce(this)
}
} }
} }
} }
@ -206,7 +204,6 @@ export default {
$listeners.cancel = this.$listeners.cancel $listeners.cancel = this.$listeners.cancel
} }
return $listeners return $listeners
} }

4
packages/nc-gui/components/project/spreadsheet/components/importExport/columnMappingModal.vue

@ -154,8 +154,8 @@ export default {
// check if the input contains null value for a required column // check if the input contains null value for a required column
if (v.pk ? !v.ai && !v.cdf : !v.cdf && v.rqd) { if (v.pk ? !v.ai && !v.cdf : !v.cdf && v.rqd) {
if (this.parsedCsv && this.parsedCsv.data && this.parsedCsv.data.slice(0, 500) if (this.parsedCsv && this.parsedCsv.data && this.parsedCsv.data.slice(0, 500)
.some(r => r[row.sourceCn] === null || r[row.sourceCn] === undefined || r[row.sourceCn] === "" )) { .some(r => r[row.sourceCn] === null || r[row.sourceCn] === undefined || r[row.sourceCn] === '')) {
return `null value violates not-null constraint` return 'null value violates not-null constraint'
} }
} }

2
packages/nc-gui/components/project/spreadsheet/components/sortListMenu.vue

@ -22,7 +22,7 @@
</v-btn> </v-btn>
</v-badge> </v-badge>
</template> </template>
<div class="backgroundColor pa-2" style="min-width: 330px"> <div class="backgroundColor pa-2 menu-filter-dropdown" style="min-width: 330px">
<div class="sort-grid" @click.stop> <div class="sort-grid" @click.stop>
<template v-for="(sort, i) in sortList || []" dense> <template v-for="(sort, i) in sortList || []" dense>
<v-icon <v-icon

28
packages/nc-gui/components/project/spreadsheet/helpers/imageExt.js

@ -1,22 +1,22 @@
const imageExt = [ const imageExt = [
"jpeg", 'jpeg',
"gif", 'gif',
"png", 'png',
"png", 'png',
"svg", 'svg',
"bmp", 'bmp',
"ico", 'ico',
"jpg", 'jpg',
"webp", 'webp'
]; ]
export default imageExt; export default imageExt
const isImage = (name) => { const isImage = (name) => {
return imageExt.some((e) => name.toLowerCase().endsWith(`.${e}`)); return imageExt.some(e => name.toLowerCase().endsWith(`.${e}`))
}; }
export { isImage }; export { isImage }
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
* *

2
packages/nc-gui/components/project/spreadsheet/mixins/spreadsheet.js

@ -145,7 +145,7 @@ export default {
concatenatedXWhere() { concatenatedXWhere() {
let where = '' let where = ''
if (this.searchField && this.searchQuery.trim()) { if (this.searchField && this.searchQuery.trim()) {
const col = this.availableColumns.find(({ _cn }) => _cn === this.searchField) || this.availableColumns[0] const col = this.availableColumns.find(({ alias }) => alias === this.searchField) || this.availableColumns[0]
// bigint values are displayed in string format in UI // bigint values are displayed in string format in UI
// when searching bigint values, the operator should be 'eq' instead of 'like' // when searching bigint values, the operator should be 'eq' instead of 'like'
if (['text', 'string'].includes(this.sqlUi.getAbstractType(col)) && col.dt !== 'bigint') { if (['text', 'string'].includes(this.sqlUi.getAbstractType(col)) && col.dt !== 'bigint') {

10
packages/nc-gui/components/project/spreadsheet/rowsXcDataTable.vue

@ -597,13 +597,9 @@
</span> </span>
</v-list-item> </v-list-item>
</template> </template>
<template
v-if=" <template v-if="isEditable && !isLocked && rowContextMenu.col && !rowContextMenu.col.rqd && !rowContextMenu.col.virtual">
rowContextMenu.col &&
!rowContextMenu.col.rqd &&
!rowContextMenu.col.virtual
"
>
<v-tooltip bottom> <v-tooltip bottom>
<template #activator="{ on }"> <template #activator="{ on }">
<v-list-item <v-list-item

4
packages/nc-gui/components/project/spreadsheet/views/formView.vue

@ -689,9 +689,7 @@ export default {
}, },
columns: { columns: {
get() { get() {
return this.fields return this.fields.filter(f => f.show && f.uidt != UITypes.Rollup && f.uidt != UITypes.Lookup).sort((a, b) => a.order - b.order)
.filter((f) => f.show)
.sort((a, b) => a.order - b.order);
}, },
set(v) {}, set(v) {},
}, },

1
packages/nc-gui/components/project/tableTabs/aclTsFileDbChild.vue

@ -341,7 +341,6 @@ export default {
}, },
async save() { async save() {
try { try {
await this.$store.dispatch('sqlMgr/ActSqlOp', [null, 'xcRoutesPolicyUpdate', { await this.$store.dispatch('sqlMgr/ActSqlOp', [null, 'xcRoutesPolicyUpdate', {
env: this.nodes.env, env: this.nodes.env,
dbAlias: this.nodes.dbAlias, dbAlias: this.nodes.dbAlias,

17
packages/nc-gui/components/templates/help.vue

@ -39,38 +39,39 @@ export default {
description: 'Add tables', description: 'Add tables',
mac: '<kbd>Command</kbd> + <kbd>Control</kbd> + <kbd>T</kbd>', mac: '<kbd>Command</kbd> + <kbd>Control</kbd> + <kbd>T</kbd>',
windows: '<kbd>Alt</kbd> + <kbd>Shift</kbd> + <kbd>T</kbd>' windows: '<kbd>Alt</kbd> + <kbd>Shift</kbd> + <kbd>T</kbd>'
},{ }, {
description: 'Add columns', description: 'Add columns',
mac: '<kbd>Command</kbd> + <kbd>Control</kbd> + <kbd>C</kbd>', mac: '<kbd>Command</kbd> + <kbd>Control</kbd> + <kbd>C</kbd>',
windows: '<kbd>Alt</kbd> + <kbd>Shift</kbd> + <kbd>C</kbd>' windows: '<kbd>Alt</kbd> + <kbd>Shift</kbd> + <kbd>C</kbd>'
},{ }, {
description: 'Add new column row', description: 'Add new column row',
mac: '<kbd>Command</kbd> + <kbd>Control</kbd> + <kbd>A</kbd>', mac: '<kbd>Command</kbd> + <kbd>Control</kbd> + <kbd>A</kbd>',
windows: '<kbd>Alt</kbd> + <kbd>Shift</kbd> + <kbd>A</kbd>' windows: '<kbd>Alt</kbd> + <kbd>Shift</kbd> + <kbd>A</kbd>'
},{ }, {
description: 'Table navigation', description: 'Table navigation',
mac: '<kbd>Command</kbd> + <kbd>Control</kbd> + <kbd>Arrow Down</kbd> <br>AND<br> <kbd>Command</kbd> + <kbd>Control</kbd> + <kbd>Arrow Up</kbd>', mac: '<kbd>Command</kbd> + <kbd>Control</kbd> + <kbd>Arrow Down</kbd> <br>AND<br> <kbd>Command</kbd> + <kbd>Control</kbd> + <kbd>Arrow Up</kbd>',
windows: '<kbd>Alt</kbd> + <kbd>Shift</kbd> + <kbd>Arrow Down</kbd> <br>AND<br> <kbd>Alt</kbd> + <kbd>Shift</kbd> + <kbd>Arrow Up</kbd>' windows: '<kbd>Alt</kbd> + <kbd>Shift</kbd> + <kbd>Arrow Down</kbd> <br>AND<br> <kbd>Alt</kbd> + <kbd>Shift</kbd> + <kbd>Arrow Up</kbd>'
},{ }, {
description: 'Column navigation', description: 'Column navigation',
mac: '<kbd>Command</kbd> + <kbd>Control</kbd> + <kbd>Arrow Right</kbd> <br>AND<br> <kbd>Command</kbd> + <kbd>Control</kbd> + <kbd>Arrow Left</kbd>', mac: '<kbd>Command</kbd> + <kbd>Control</kbd> + <kbd>Arrow Right</kbd> <br>AND<br> <kbd>Command</kbd> + <kbd>Control</kbd> + <kbd>Arrow Left</kbd>',
windows: '<kbd>Alt</kbd> + <kbd>Shift</kbd> + <kbd>Arrow Right</kbd> <br>AND<br> <kbd>Alt</kbd> + <kbd>Shift</kbd> + <kbd>Arrow Right</kbd>' windows: '<kbd>Alt</kbd> + <kbd>Shift</kbd> + <kbd>Arrow Right</kbd> <br>AND<br> <kbd>Alt</kbd> + <kbd>Shift</kbd> + <kbd>Arrow Right</kbd>'
},{ }, {
description: 'Copy json to clipboard', description: 'Copy json to clipboard',
mac: '<kbd>Command</kbd> + <kbd>Control</kbd> + <kbd>J</kbd>', mac: '<kbd>Command</kbd> + <kbd>Control</kbd> + <kbd>J</kbd>',
windows: '<kbd>Alt</kbd> + <kbd>Shift</kbd> + <kbd>J</kbd>' windows: '<kbd>Alt</kbd> + <kbd>Shift</kbd> + <kbd>J</kbd>'
},{ }, {
description: 'Submit template', description: 'Submit template',
mac: '<kbd>Command</kbd> + <kbd>Control</kbd> + <kbd>S</kbd>', mac: '<kbd>Command</kbd> + <kbd>Control</kbd> + <kbd>S</kbd>',
windows: '<kbd>Alt</kbd> + <kbd>Shift</kbd> + <kbd>S</kbd>' windows: '<kbd>Alt</kbd> + <kbd>Shift</kbd> + <kbd>S</kbd>'
},] }]
} }
}, },
computed: { computed: {
localState: { localState: {
get() { get() {
return this.value return this.value
}, set(val) { },
set(val) {
this.$emit('input', val) this.$emit('input', val)
} }
} }

1
packages/nc-gui/components/trialExpired.vue

@ -14,7 +14,6 @@
<script> <script>
export default { export default {
name: 'TrialExpired', name: 'TrialExpired',
methods: { methods: {

41
packages/nc-gui/helpers/index.js

@ -75,7 +75,7 @@ function GetCaretPosition(ctrl) {
export function validateTableName(v, isGQL) { export function validateTableName(v, isGQL) {
if (!v) { if (!v) {
return "Table name required"; return 'Table name required'
} }
// GraphQL naming convention // GraphQL naming convention
@ -83,67 +83,66 @@ export function validateTableName(v, isGQL) {
if (isGQL) { if (isGQL) {
if (/^[_A-Za-z][_0-9A-Za-z]*$/.test(v)) { if (/^[_A-Za-z][_0-9A-Za-z]*$/.test(v)) {
return true; return true
} }
if (/^[^_A-Za-z]/.test(v)) { if (/^[^_A-Za-z]/.test(v)) {
return "Name should start with an alphabet or _"; return 'Name should start with an alphabet or _'
} }
const m = v.match(/[^_A-Za-z\d]/g); const m = v.match(/[^_A-Za-z\d]/g)
if (m) { if (m) {
return `Following characters are not allowed ${m return `Following characters are not allowed ${m
.map((c) => JSON.stringify(c)) .map(c => JSON.stringify(c))
.join(", ")}`; .join(', ')}`
} }
} else { } else {
// exclude . / \ // exclude . / \
// rest all characters allowed // rest all characters allowed
// https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/acreldb/n0rfg6x1shw0ppn1cwhco6yn09f7.htm#:~:text=By%20default%2C%20MySQL%20encloses%20column,not%20truncate%20a%20longer%20name. // https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/acreldb/n0rfg6x1shw0ppn1cwhco6yn09f7.htm#:~:text=By%20default%2C%20MySQL%20encloses%20column,not%20truncate%20a%20longer%20name.
const m = v.match(/[./\\]/g); const m = v.match(/[./\\]/g)
if (m) { if (m) {
return `Following characters are not allowed ${m return `Following characters are not allowed ${m
.map((c) => JSON.stringify(c)) .map(c => JSON.stringify(c))
.join(", ")}`; .join(', ')}`
} }
return true; return true
} }
} }
export function validateColumnName(v, isGQL) { export function validateColumnName(v, isGQL) {
if (!v) { if (!v) {
return "Column name required"; return 'Column name required'
} }
// GraphQL naming convention // GraphQL naming convention
// http://spec.graphql.org/June2018/#Name // http://spec.graphql.org/June2018/#Name
if (isGQL) { if (isGQL) {
if (/^[_A-Za-z][_0-9A-Za-z]*$/.test(v)) { if (/^[_A-Za-z][_0-9A-Za-z]*$/.test(v)) {
return true; return true
} }
if (/^[^_A-Za-z]/.test(v)) { if (/^[^_A-Za-z]/.test(v)) {
return "Name should start with an alphabet or _"; return 'Name should start with an alphabet or _'
} }
const m = v.match(/[^_A-Za-z\d]/g); const m = v.match(/[^_A-Za-z\d]/g)
if (m) { if (m) {
return `Following characters are not allowed ${m return `Following characters are not allowed ${m
.map((c) => JSON.stringify(c)) .map(c => JSON.stringify(c))
.join(", ")}`; .join(', ')}`
} }
} else { } else {
// exclude . / \ // exclude . / \
// rest all characters allowed // rest all characters allowed
// https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/acreldb/n0rfg6x1shw0ppn1cwhco6yn09f7.htm#:~:text=By%20default%2C%20MySQL%20encloses%20column,not%20truncate%20a%20longer%20name. // https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/acreldb/n0rfg6x1shw0ppn1cwhco6yn09f7.htm#:~:text=By%20default%2C%20MySQL%20encloses%20column,not%20truncate%20a%20longer%20name.
const m = v.match(/[./\\]/g); const m = v.match(/[./\\]/g)
if (m) { if (m) {
return `Following characters are not allowed ${m return `Following characters are not allowed ${m
.map((c) => JSON.stringify(c)) .map(c => JSON.stringify(c))
.join(", ")}`; .join(', ')}`
} }
return true; return true
} }
} }

2
packages/nc-gui/lang/da.json

@ -406,7 +406,7 @@
"deleteProject": "Ønsker du at slette projektet?", "deleteProject": "Ønsker du at slette projektet?",
"shareBasePrivate": "Generer offentligt delbart readonly base", "shareBasePrivate": "Generer offentligt delbart readonly base",
"shareBasePublic": "Enhver på internettet med dette link kan se", "shareBasePublic": "Enhver på internettet med dette link kan se",
"userInviteNoSMTP": "Ser ud som om du ikke har konfigureret mailer endnu! \\ n Kopier venligst ovenstående invitation link og send det til", "userInviteNoSMTP": "Ser ud som om du ikke har konfigureret mailer endnu!\nKopier venligst ovenstående invitation link og send det til",
"dragDropHide": "Træk og slip felter her for at skjule", "dragDropHide": "Træk og slip felter her for at skjule",
"formInput": "Indtast formularindgangsmærke", "formInput": "Indtast formularindgangsmærke",
"formHelpText": "Tilføj nogle hjælpetekst", "formHelpText": "Tilføj nogle hjælpetekst",

2
packages/nc-gui/lang/de.json

@ -406,7 +406,7 @@
"deleteProject": "Möchten Sie das Projekt löschen?", "deleteProject": "Möchten Sie das Projekt löschen?",
"shareBasePrivate": "Öffentlich freigegebene Nur-Lese-Datenbank generieren", "shareBasePrivate": "Öffentlich freigegebene Nur-Lese-Datenbank generieren",
"shareBasePublic": "Für Jeden im Internet mit diesem Link sichtbar", "shareBasePublic": "Für Jeden im Internet mit diesem Link sichtbar",
"userInviteNoSMTP": "Es sieht so aus, als hätten Sie den Mailer noch nicht konfiguriert! \\ n Bitte kopieren Sie den obigen Einladungs-Link und senden Sie ihn an", "userInviteNoSMTP": "Es sieht so aus, als hätten Sie den Mailer noch nicht konfiguriert!\nBitte kopieren Sie den obigen Einladungs-Link und senden Sie ihn an",
"dragDropHide": "Ziehen Sie die Felder hierher, um sie zu verstecken", "dragDropHide": "Ziehen Sie die Felder hierher, um sie zu verstecken",
"formInput": "Formularbezeichnung eingeben", "formInput": "Formularbezeichnung eingeben",
"formHelpText": "Einen Hilfs-Text hinzufügen", "formHelpText": "Einen Hilfs-Text hinzufügen",

2
packages/nc-gui/lang/en.json

@ -406,7 +406,7 @@
"deleteProject": "Do you want to delete the project?", "deleteProject": "Do you want to delete the project?",
"shareBasePrivate": "Generate publicly shareable readonly base", "shareBasePrivate": "Generate publicly shareable readonly base",
"shareBasePublic": "Anyone on the internet with this link can view", "shareBasePublic": "Anyone on the internet with this link can view",
"userInviteNoSMTP": "Looks like you have not configured mailer yet! \\n Please copy above invite link and send it to", "userInviteNoSMTP": "Looks like you have not configured mailer yet!\nPlease copy above invite link and send it to",
"dragDropHide": "Drag and drop fields here to hide", "dragDropHide": "Drag and drop fields here to hide",
"formInput": "Enter form input label", "formInput": "Enter form input label",
"formHelpText": "Add some help text", "formHelpText": "Add some help text",

2
packages/nc-gui/lang/es.json

@ -406,7 +406,7 @@
"deleteProject": "¿Quieres eliminar el proyecto?", "deleteProject": "¿Quieres eliminar el proyecto?",
"shareBasePrivate": "Generar una base de sólo lectura compartible públicamente", "shareBasePrivate": "Generar una base de sólo lectura compartible públicamente",
"shareBasePublic": "Cualquier persona en Internet con este enlace puede ver", "shareBasePublic": "Cualquier persona en Internet con este enlace puede ver",
"userInviteNoSMTP": "¡Parece que aún no has configurado Mailer! \\ n Por favor, copia el link de invitación de arriba y envíalo a", "userInviteNoSMTP": "¡Parece que aún no has configurado Mailer!\nPor favor, copia el link de invitación de arriba y envíalo a",
"dragDropHide": "Arrastra y suelta los campos a ocultar aquí", "dragDropHide": "Arrastra y suelta los campos a ocultar aquí",
"formInput": "Ingrese la etiqueta de entrada del formulario", "formInput": "Ingrese la etiqueta de entrada del formulario",
"formHelpText": "Añade algo de texto de ayuda", "formHelpText": "Añade algo de texto de ayuda",

2
packages/nc-gui/lang/fi.json

@ -406,7 +406,7 @@
"deleteProject": "Haluatko poistaa projektin?", "deleteProject": "Haluatko poistaa projektin?",
"shareBasePrivate": "Luo julkisesti jakattava Readonly Base", "shareBasePrivate": "Luo julkisesti jakattava Readonly Base",
"shareBasePublic": "Jokainen Internetissä tällä linkillä voi tarkastella", "shareBasePublic": "Jokainen Internetissä tällä linkillä voi tarkastella",
"userInviteNoSMTP": "Näyttää siltä, ettet ole määrittänyt sähköpostia! \\ n Kopioi yllä kutsun linkki ja lähetä se", "userInviteNoSMTP": "Näyttää siltä, ettet ole määrittänyt sähköpostia!\nKopioi yllä kutsun linkki ja lähetä se",
"dragDropHide": "Vedä ja pudota kentät täällä piiloutumaan", "dragDropHide": "Vedä ja pudota kentät täällä piiloutumaan",
"formInput": "Anna lomakkeen syöttömerkki", "formInput": "Anna lomakkeen syöttömerkki",
"formHelpText": "Lisää joitain ohjeita", "formHelpText": "Lisää joitain ohjeita",

2
packages/nc-gui/lang/fr.json

@ -406,7 +406,7 @@
"deleteProject": "Voulez-vous supprimer le projet ?", "deleteProject": "Voulez-vous supprimer le projet ?",
"shareBasePrivate": "Générer une base partagée en lecture seule", "shareBasePrivate": "Générer une base partagée en lecture seule",
"shareBasePublic": "Toute personne avec ce lien peut consulter", "shareBasePublic": "Toute personne avec ce lien peut consulter",
"userInviteNoSMTP": "On dirait que vous n'avez pas encore configuré Mailer! \\ n Merci de copier-coller le lien d'invitation ci-dessous et l'envoyer à", "userInviteNoSMTP": "On dirait que vous n'avez pas encore configuré Mailer!\nMerci de copier-coller le lien d'invitation ci-dessous et l'envoyer à",
"dragDropHide": "Glisser et déposer des champs ici pour masquer", "dragDropHide": "Glisser et déposer des champs ici pour masquer",
"formInput": "Entrer le libelé du formulaire", "formInput": "Entrer le libelé du formulaire",
"formHelpText": "Ajouter du texte d'assitance", "formHelpText": "Ajouter du texte d'assitance",

2
packages/nc-gui/lang/id.json

@ -406,7 +406,7 @@
"deleteProject": "Apakah Anda ingin menghapus proyek?", "deleteProject": "Apakah Anda ingin menghapus proyek?",
"shareBasePrivate": "Menghasilkan basis readonly yang dapat dibagikan secara publik", "shareBasePrivate": "Menghasilkan basis readonly yang dapat dibagikan secara publik",
"shareBasePublic": "Siapa pun di Internet dengan tautan ini dapat dilihat", "shareBasePublic": "Siapa pun di Internet dengan tautan ini dapat dilihat",
"userInviteNoSMTP": "Sepertinya Anda belum mengonfigurasi mailer! \\ n Harap salin tautan undangan di atas dan kirimkan ke", "userInviteNoSMTP": "Sepertinya Anda belum mengonfigurasi mailer!\nHarap salin tautan undangan di atas dan kirimkan ke",
"dragDropHide": "Seret dan jatuhkan bidang di sini untuk bersembunyi", "dragDropHide": "Seret dan jatuhkan bidang di sini untuk bersembunyi",
"formInput": "Masukkan label input formulir", "formInput": "Masukkan label input formulir",
"formHelpText": "Tambahkan beberapa teks bantuan", "formHelpText": "Tambahkan beberapa teks bantuan",

2
packages/nc-gui/lang/it_IT.json

@ -406,7 +406,7 @@
"deleteProject": "Vuoi cancellare il progetto?", "deleteProject": "Vuoi cancellare il progetto?",
"shareBasePrivate": "Genera base readonly condivisibile pubblicamente condivisa", "shareBasePrivate": "Genera base readonly condivisibile pubblicamente condivisa",
"shareBasePublic": "Chiunque su Internet con questo link può visualizzare", "shareBasePublic": "Chiunque su Internet con questo link può visualizzare",
"userInviteNoSMTP": "Sembra che non abbia ancora configurato mailer! \\ n Si prega di copiare sopra Invita link e invialo a", "userInviteNoSMTP": "Sembra che non abbia ancora configurato mailer!\nSi prega di copiare sopra Invita link e invialo a",
"dragDropHide": "Trascina e rilascia i campi qui per nascondersi", "dragDropHide": "Trascina e rilascia i campi qui per nascondersi",
"formInput": "Inserisci l'etichetta di input del modulo", "formInput": "Inserisci l'etichetta di input del modulo",
"formHelpText": "Aggiungi un po 'di testo di aiuto", "formHelpText": "Aggiungi un po 'di testo di aiuto",

2
packages/nc-gui/lang/iw.json

@ -406,7 +406,7 @@
"deleteProject": "האם ברצונך למחוק את הפרויקט?", "deleteProject": "האם ברצונך למחוק את הפרויקט?",
"shareBasePrivate": "ליצור בסיס שיתוף פעולה לציבור", "shareBasePrivate": "ליצור בסיס שיתוף פעולה לציבור",
"shareBasePublic": "כל אחד באינטרנט עם קישור זה יכול להציג", "shareBasePublic": "כל אחד באינטרנט עם קישור זה יכול להציג",
"userInviteNoSMTP": "נראה כאילו לא הגדרת מיילר עדיין! \\ N אנא העתק מעל הזמנת קישור ולשלוח אותו", "userInviteNoSMTP": "נראה כאילו לא הגדרת מיילר עדיין!\nאנא העתק מעל הזמנת קישור ולשלוח אותו",
"dragDropHide": "גרור ושחרר שדות כאן כדי להסתיר", "dragDropHide": "גרור ושחרר שדות כאן כדי להסתיר",
"formInput": "הזן תווית קלט טופס", "formInput": "הזן תווית קלט טופס",
"formHelpText": "הוסף טקסט עזרה", "formHelpText": "הוסף טקסט עזרה",

2
packages/nc-gui/lang/ko.json

@ -406,7 +406,7 @@
"deleteProject": "프로젝트를 삭제 하시겠습니까?", "deleteProject": "프로젝트를 삭제 하시겠습니까?",
"shareBasePrivate": "공개적으로 공유 할 수있는 ReadOnly Base를 생성합니다", "shareBasePrivate": "공개적으로 공유 할 수있는 ReadOnly Base를 생성합니다",
"shareBasePublic": "이 링크가있는 인터넷의 모든 사람은 볼 수 있습니다", "shareBasePublic": "이 링크가있는 인터넷의 모든 사람은 볼 수 있습니다",
"userInviteNoSMTP": "아직 메일러를 구성하지 않은 것처럼 보입니다! \\ n 초대장 링크를 복사하여 보냅니다.", "userInviteNoSMTP": "아직 메일러를 구성하지 않은 것처럼 보입니다!\n초대장 링크를 복사하여 보냅니다.",
"dragDropHide": "여기에서 필드를 드래그 앤 드롭하십시오", "dragDropHide": "여기에서 필드를 드래그 앤 드롭하십시오",
"formInput": "양식 입력 레이블을 입력하십시오", "formInput": "양식 입력 레이블을 입력하십시오",
"formHelpText": "도움말 텍스트를 추가하십시오", "formHelpText": "도움말 텍스트를 추가하십시오",

2
packages/nc-gui/lang/no.json

@ -406,7 +406,7 @@
"deleteProject": "Ønsker du å slette prosjektet?", "deleteProject": "Ønsker du å slette prosjektet?",
"shareBasePrivate": "Generer offentlig delbar readonly base", "shareBasePrivate": "Generer offentlig delbar readonly base",
"shareBasePublic": "Alle på Internett med denne lenken kan se", "shareBasePublic": "Alle på Internett med denne lenken kan se",
"userInviteNoSMTP": "Ser ut som om du ikke har konfigurert mailer ennå! \\ n Vennligst kopier over Inviter Link og send den til", "userInviteNoSMTP": "Ser ut som om du ikke har konfigurert mailer ennå!\nVennligst kopier over Inviter Link og send den til",
"dragDropHide": "Dra og slipp felt her for å skjule", "dragDropHide": "Dra og slipp felt her for å skjule",
"formInput": "Skriv inn skjema inngangsetikett", "formInput": "Skriv inn skjema inngangsetikett",
"formHelpText": "Legg til litt hjelpetekst", "formHelpText": "Legg til litt hjelpetekst",

2
packages/nc-gui/lang/pt.json

@ -406,7 +406,7 @@
"deleteProject": "Você quer excluir o projeto?", "deleteProject": "Você quer excluir o projeto?",
"shareBasePrivate": "Gerar base readonly compartilhável publicamente", "shareBasePrivate": "Gerar base readonly compartilhável publicamente",
"shareBasePublic": "Qualquer pessoa na internet com este link pode ver", "shareBasePublic": "Qualquer pessoa na internet com este link pode ver",
"userInviteNoSMTP": "Parece que você ainda não configurou o mailer! \\ n por favor copie o link acima do convite e envie-o para", "userInviteNoSMTP": "Parece que você ainda não configurou o mailer!\npor favor copie o link acima do convite e envie-o para",
"dragDropHide": "Arraste e solte os campos aqui para se esconder", "dragDropHide": "Arraste e solte os campos aqui para se esconder",
"formInput": "Digite a etiqueta de entrada do formulário", "formInput": "Digite a etiqueta de entrada do formulário",
"formHelpText": "Adicione um texto de ajuda", "formHelpText": "Adicione um texto de ajuda",

2
packages/nc-gui/lang/pt_BR.json

@ -406,7 +406,7 @@
"deleteProject": "Você quer excluir o projeto?", "deleteProject": "Você quer excluir o projeto?",
"shareBasePrivate": "Gerar base readonly compartilhável publicamente", "shareBasePrivate": "Gerar base readonly compartilhável publicamente",
"shareBasePublic": "Qualquer pessoa na internet com este link pode ver", "shareBasePublic": "Qualquer pessoa na internet com este link pode ver",
"userInviteNoSMTP": "Parece que você ainda não configurou o mailer! \\ n por favor copie o link acima do convite e envie-o para", "userInviteNoSMTP": "Parece que você ainda não configurou o mailer!\npor favor copie o link acima do convite e envie-o para",
"dragDropHide": "Arraste e solte os campos aqui para se esconder", "dragDropHide": "Arraste e solte os campos aqui para se esconder",
"formInput": "Digite a etiqueta de entrada do formulário", "formInput": "Digite a etiqueta de entrada do formulário",
"formHelpText": "Adicione um texto de ajuda", "formHelpText": "Adicione um texto de ajuda",

2
packages/nc-gui/lang/sv.json

@ -406,7 +406,7 @@
"deleteProject": "Vill du radera projektet?", "deleteProject": "Vill du radera projektet?",
"shareBasePrivate": "Generera offentligt delbar readonly base", "shareBasePrivate": "Generera offentligt delbar readonly base",
"shareBasePublic": "Någon på internet med den här länken kan visa", "shareBasePublic": "Någon på internet med den här länken kan visa",
"userInviteNoSMTP": "Det verkar som om du inte har konfigurerat Mailer än! \\ n Vänligen kopiera ovanför bjudningslänk och skicka den till", "userInviteNoSMTP": "Det verkar som om du inte har konfigurerat Mailer än!\nVänligen kopiera ovanför bjudningslänk och skicka den till",
"dragDropHide": "Dra och släpp fält här för att dölja", "dragDropHide": "Dra och släpp fält här för att dölja",
"formInput": "Ange formulärinmatningslabel", "formInput": "Ange formulärinmatningslabel",
"formHelpText": "Lägg till lite hjälptext", "formHelpText": "Lägg till lite hjälptext",

2
packages/nc-gui/lang/th.json

@ -406,7 +406,7 @@
"deleteProject": "คณตองการลบโครงการหรอไม", "deleteProject": "คณตองการลบโครงการหรอไม",
"shareBasePrivate": "สรางฐาน Readonly ทใชวมกนไดอยางเปดเผย", "shareBasePrivate": "สรางฐาน Readonly ทใชวมกนไดอยางเปดเผย",
"shareBasePublic": "ทกคนบนอนเทอรเนตดวยลงคสามารถดได", "shareBasePublic": "ทกคนบนอนเทอรเนตดวยลงคสามารถดได",
"userInviteNoSMTP": "ดเหมอนวาคณยงไมไดกำหนดคาเมล! \\ n โปรดคดลอกลงกเชญดานบนและสงไปท", "userInviteNoSMTP": "ดเหมอนวาคณยงไมไดกำหนดคาเมล!\nโปรดคดลอกลงกเชญดานบนและสงไปท",
"dragDropHide": "ลากและวางฟลดเพอซอน", "dragDropHide": "ลากและวางฟลดเพอซอน",
"formInput": "ปอนปายชออนพตแบบฟอรม", "formInput": "ปอนปายชออนพตแบบฟอรม",
"formHelpText": "เพมขอความชวยเหลอบางอยาง", "formHelpText": "เพมขอความชวยเหลอบางอยาง",

2
packages/nc-gui/lang/uk.json

@ -406,7 +406,7 @@
"deleteProject": "Ви хочете видалити проект?", "deleteProject": "Ви хочете видалити проект?",
"shareBasePrivate": "Генерувати загальнодоступну групою", "shareBasePrivate": "Генерувати загальнодоступну групою",
"shareBasePublic": "Будь-хто в Інтернеті за допомогою цього посилання може переглядати", "shareBasePublic": "Будь-хто в Інтернеті за допомогою цього посилання може переглядати",
"userInviteNoSMTP": "Схоже, ви ще не налаштували Mailer! \\ n Будь ласка, скопіюйте вище посилання на запрошення і надішліть його", "userInviteNoSMTP": "Схоже, ви ще не налаштували Mailer!\nБудь ласка, скопіюйте вище посилання на запрошення і надішліть його",
"dragDropHide": "Перетягніть поля тут, щоб приховати", "dragDropHide": "Перетягніть поля тут, щоб приховати",
"formInput": "Введіть етикетку введення форми", "formInput": "Введіть етикетку введення форми",
"formHelpText": "Додайте деякий текст довідки", "formHelpText": "Додайте деякий текст довідки",

2
packages/nc-gui/lang/vi.json

@ -406,7 +406,7 @@
"deleteProject": "Bạn có muốn xóa dự án?", "deleteProject": "Bạn có muốn xóa dự án?",
"shareBasePrivate": "Tạo cơ sở chỉ đọc chia sẻ công khai", "shareBasePrivate": "Tạo cơ sở chỉ đọc chia sẻ công khai",
"shareBasePublic": "Bất cứ ai trên Internet với liên kết này có thể xem", "shareBasePublic": "Bất cứ ai trên Internet với liên kết này có thể xem",
"userInviteNoSMTP": "Có vẻ như bạn chưa định cấu hình Mailer! \\ n Vui lòng sao chép liên kết mời trên và gửi nó đến", "userInviteNoSMTP": "Có vẻ như bạn chưa định cấu hình Mailer!\nVui lòng sao chép liên kết mời trên và gửi nó đến",
"dragDropHide": "Kéo và thả các trường ở đây để ẩn", "dragDropHide": "Kéo và thả các trường ở đây để ẩn",
"formInput": "Nhập nhãn đầu vào Mẫu", "formInput": "Nhập nhãn đầu vào Mẫu",
"formHelpText": "Thêm một số văn bản trợ giúp", "formHelpText": "Thêm một số văn bản trợ giúp",

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

@ -302,19 +302,20 @@
</template> </template>
<script> <script>
import { mapGetters, mapActions, mapMutations } from "vuex";
import ReleaseInfo from "@/components/releaseInfo"; import { mapGetters, mapActions, mapMutations } from 'vuex'
import "splitpanes/dist/splitpanes.css"; import ReleaseInfo from '@/components/releaseInfo'
import XBtn from "../components/global/xBtn"; import 'splitpanes/dist/splitpanes.css'
import dlgUnexpectedError from "../components/utils/dlgUnexpectedError"; import XBtn from '../components/global/xBtn'
import settings from "../components/settings"; import dlgUnexpectedError from '../components/utils/dlgUnexpectedError'
import { copyTextToClipboard } from "@/helpers/xutils"; import settings from '../components/settings'
import Snackbar from "~/components/snackbar"; import { copyTextToClipboard } from '@/helpers/xutils'
import Language from "~/components/utils/language"; import Snackbar from '~/components/snackbar'
import Loader from "~/components/loader"; import Language from '~/components/utils/language'
import PreviewAs from "~/components/previewAs"; import Loader from '~/components/loader'
import ShareOrInviteModal from "~/components/auth/shareOrInviteModal"; import PreviewAs from '~/components/previewAs'
import ImportantAnnouncement from "../components/importantAnnouncement.vue"; import ShareOrInviteModal from '~/components/auth/shareOrInviteModal'
import ImportantAnnouncement from '../components/importantAnnouncement.vue'
export default { export default {
components: { components: {

3
packages/nc-gui/layouts/public.vue

@ -14,7 +14,8 @@
<template #activator="{ on }"> <template #activator="{ on }">
<v-btn <v-btn
to="/projects" to="/projects"
icon class="pa-1 brand-icon nc-noco-brand-icon" icon
class="pa-1 brand-icon nc-noco-brand-icon"
v-on="on" v-on="on"
> >
<v-img :src="require('~/assets/img/icons/512x512-trans.png')" max-height="30px" max-width="30px" /> <v-img :src="require('~/assets/img/icons/512x512-trans.png')" max-height="30px" max-width="30px" />

6
packages/nc-gui/package-lock.json generated

@ -7876,9 +7876,9 @@
} }
}, },
"nocodb-sdk": { "nocodb-sdk": {
"version": "0.90.3", "version": "0.90.5",
"resolved": "https://registry.npmjs.org/nocodb-sdk/-/nocodb-sdk-0.90.3.tgz", "resolved": "https://registry.npmjs.org/nocodb-sdk/-/nocodb-sdk-0.90.5.tgz",
"integrity": "sha512-qoQbuSIb/5qYyldZjtwZY6eZaQWzL/Z9pfsM+Aw8HivsyIqRLboKCAVEr6gJf/QToro49NEzjgisKMeX/YLB+w==", "integrity": "sha512-5H2nuVvt9n2DTQs9NMKtooGBXPpGjPoHIy6szXb+feigE2N8QPZNNt3YgpK9QaEG6mTpr04kXgCvFp0QsgV6Xg==",
"requires": { "requires": {
"axios": "^0.21.1", "axios": "^0.21.1",
"jsep": "^0.4.0" "jsep": "^0.4.0"

2
packages/nc-gui/package.json

@ -29,7 +29,7 @@
"monaco-editor": "^0.19.3", "monaco-editor": "^0.19.3",
"monaco-themes": "^0.2.5", "monaco-themes": "^0.2.5",
"nano-assign": "^1.0.1", "nano-assign": "^1.0.1",
"nocodb-sdk": "0.90.3", "nocodb-sdk": "0.90.5",
"nuxt": "^2.14.0", "nuxt": "^2.14.0",
"odometer": "^0.4.8", "odometer": "^0.4.8",
"papaparse": "^5.3.1", "papaparse": "^5.3.1",

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

@ -790,7 +790,7 @@ export default {
this.statusUpdatingProjectId = projectId; this.statusUpdatingProjectId = projectId;
this.projectStatusUpdating = true; this.projectStatusUpdating = true;
try { try {
await this.$api.project.delete(projectId); await this.$api.project.delete(projectId)
this.$toast this.$toast
.success(`Project '${project.title}' deleted successfully`) .success(`Project '${project.title}' deleted successfully`)
.goAway(3000); .goAway(3000);

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

@ -1,10 +1,10 @@
// plugins/i18n.js // plugins/i18n.js
import Vue from "vue"; import Vue from 'vue'
import VueI18n from "vue-i18n"; import VueI18n from 'vue-i18n'
// Tell Vue to use our plugin // Tell Vue to use our plugin
Vue.use(VueI18n); Vue.use(VueI18n)
export default ({ app, store }) => { export default ({ app, store }) => {
// Set the i18n instance on app // Set the i18n instance on app
@ -14,49 +14,49 @@ export default ({ app, store }) => {
locale: store.state.windows.language, locale: store.state.windows.language,
// Set the fallback locale in case the current locale can't be found // Set the fallback locale in case the current locale can't be found
fallbackLocale: "en", fallbackLocale: 'en',
// Associate each locale to a content file // Associate each locale to a content file
messages: { messages: {
en: require("~/lang/en.json"), en: require('~/lang/en.json'),
zh_HK: require("~/lang/zh_HK.json"), zh_HK: require('~/lang/zh_HK.json'),
zh_TW: require("~/lang/zh_TW.json"), zh_TW: require('~/lang/zh_TW.json'),
zh_CN: require("~/lang/zh_CN.json"), zh_CN: require('~/lang/zh_CN.json'),
ja: require("~/lang/ja.json"), ja: require('~/lang/ja.json'),
fr: require("~/lang/fr.json"), fr: require('~/lang/fr.json'),
es: require("~/lang/es.json"), es: require('~/lang/es.json'),
de: require("~/lang/de.json"), de: require('~/lang/de.json'),
id: require("~/lang/id.json"), id: require('~/lang/id.json'),
it_IT: require("~/lang/it_IT.json"), it_IT: require('~/lang/it_IT.json'),
ko: require("~/lang/ko.json"), ko: require('~/lang/ko.json'),
lv: require("~/lang/lv.json"), lv: require('~/lang/lv.json'),
nl: require("~/lang/nl.json"), nl: require('~/lang/nl.json'),
ru: require("~/lang/ru.json"), ru: require('~/lang/ru.json'),
sv: require("~/lang/sv.json"), sv: require('~/lang/sv.json'),
da: require("~/lang/da.json"), da: require('~/lang/da.json'),
vi: require("~/lang/vi.json"), vi: require('~/lang/vi.json'),
no: require("~/lang/no.json"), no: require('~/lang/no.json'),
iw: require("~/lang/iw.json"), iw: require('~/lang/iw.json'),
fi: require("~/lang/fi.json"), fi: require('~/lang/fi.json'),
uk: require("~/lang/uk.json"), uk: require('~/lang/uk.json'),
hr: require("~/lang/hr.json"), hr: require('~/lang/hr.json'),
th: require("~/lang/th.json"), th: require('~/lang/th.json'),
sl: require("~/lang/sl.json"), sl: require('~/lang/sl.json'),
pt_BR: require("~/lang/pt_BR.json"), pt_BR: require('~/lang/pt_BR.json'),
fa: require("~/lang/fa.json"), fa: require('~/lang/fa.json'),
tr: require("~/lang/tr.json"), tr: require('~/lang/tr.json')
}, }
}); })
store.watch( store.watch(
(state) => state.windows.language, state => state.windows.language,
(language) => { (language) => {
if (app.i18n.availableLocales.includes(language)) { if (app.i18n.availableLocales.includes(language)) {
app.i18n.locale = language; app.i18n.locale = language
} }
} }
); )
}; }
/** /**
* @copyright Copyright (c) 2021, Xgene Cloud Ltd * @copyright Copyright (c) 2021, Xgene Cloud Ltd
* *

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

@ -2,7 +2,7 @@ export const state = () => ({
releaseVersion: null, releaseVersion: null,
hiddenRelease: null, hiddenRelease: null,
latestRelease: null, latestRelease: null,
hiddenAnnouncement: null, hiddenAnnouncement: null
}) })
export const mutations = { export const mutations = {
@ -17,7 +17,7 @@ export const mutations = {
}, },
MutHiddenAnnouncement(state, hiddenAnnouncement) { MutHiddenAnnouncement(state, hiddenAnnouncement) {
state.hiddenAnnouncement = hiddenAnnouncement state.hiddenAnnouncement = hiddenAnnouncement
}, }
} }
/** /**

1
packages/nc-gui/xc.js

@ -2,7 +2,6 @@
function initApp(config) { function initApp(config) {
const nuxtApp = document.createElement('div') const nuxtApp = document.createElement('div')
nuxtApp.id = '__nuxt' nuxtApp.id = '__nuxt'
document.querySelector(config.selector).appendChild(nuxtApp); document.querySelector(config.selector).appendChild(nuxtApp);
[ [

2
packages/nc-lib-gui/package.json

@ -1,6 +1,6 @@
{ {
"name": "nc-lib-gui", "name": "nc-lib-gui",
"version": "0.90.3", "version": "0.90.5",
"description": "> TODO: description", "description": "> TODO: description",
"author": "“pranavxc” <pranavxc@gmail.com>", "author": "“pranavxc” <pranavxc@gmail.com>",
"homepage": "https://gitlab.com/xgenecloud-ts/xgenecloud-ts#readme", "homepage": "https://gitlab.com/xgenecloud-ts/xgenecloud-ts#readme",

1
packages/noco-docs/content/en/developer-resources/rest-apis.md

@ -78,6 +78,7 @@ Currently, the default value for {orgs} is <b>noco</b>. Users will be able to ch
| Meta | Post | auth | projectUserAdd | /api/v1/db/meta/projects/{projectId}/users | | Meta | Post | auth | projectUserAdd | /api/v1/db/meta/projects/{projectId}/users |
| Meta | Patch | auth | projectUserUpdate | /api/v1/db/meta/projects/{projectId}/users/{userId} | | Meta | Patch | auth | projectUserUpdate | /api/v1/db/meta/projects/{projectId}/users/{userId} |
| Meta | Delete| auth | projectUserRemove | /api/v1/db/meta/projects/{projectId}/users/{userId} | | Meta | Delete| auth | projectUserRemove | /api/v1/db/meta/projects/{projectId}/users/{userId} |
| Meta | Post | auth | projectUserResendInvite | /api/v1/db/meta/projects/{projectId}/users/{userId}/resend-invite |
| Meta | Post | dbTable | create | /api/v1/db/meta/projects/{projectId}/tables | | Meta | Post | dbTable | create | /api/v1/db/meta/projects/{projectId}/tables |
| Meta | Get | dbTable | list | /api/v1/db/meta/projects/{projectId}/tables | | Meta | Get | dbTable | list | /api/v1/db/meta/projects/{projectId}/tables |
| Meta | Post | dbTableColumn | create | /api/v1/db/meta/tables/{tableId}/columns | | Meta | Post | dbTableColumn | create | /api/v1/db/meta/tables/{tableId}/columns |

2
packages/nocodb-sdk/package-lock.json generated

@ -1,6 +1,6 @@
{ {
"name": "nocodb-sdk", "name": "nocodb-sdk",
"version": "0.90.3", "version": "0.90.5",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

2
packages/nocodb-sdk/package.json

@ -1,6 +1,6 @@
{ {
"name": "nocodb-sdk", "name": "nocodb-sdk",
"version": "0.90.3", "version": "0.90.5",
"description": "NocoDB SDK", "description": "NocoDB SDK",
"main": "build/main/index.js", "main": "build/main/index.js",
"typings": "build/main/index.d.ts", "typings": "build/main/index.d.ts",

23
packages/nocodb-sdk/src/lib/Api.ts

@ -1063,6 +1063,29 @@ export class Api<
format: 'json', format: 'json',
...params, ...params,
}), }),
/**
* @description Resend Invitation to a specific user
*
* @tags Auth
* @name ProjectUserResendInvite
* @request POST:/api/v1/db/meta/projects/{projectId}/users/{userId}/resend-invite
* @response `200` `any` OK
*/
projectUserResendInvite: (
projectId: string,
userId: string,
data: any,
params: RequestParams = {}
) =>
this.request<any, any>({
path: `/api/v1/db/meta/projects/${projectId}/users/${userId}/resend-invite`,
method: 'POST',
body: data,
type: ContentType.Json,
format: 'json',
...params,
}),
}; };
project = { project = {
/** /**

14
packages/nocodb/package-lock.json generated

@ -1,6 +1,6 @@
{ {
"name": "nocodb", "name": "nocodb",
"version": "0.90.3", "version": "0.90.5",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@ -12483,9 +12483,9 @@
} }
}, },
"nc-lib-gui": { "nc-lib-gui": {
"version": "0.90.3", "version": "0.90.5",
"resolved": "https://registry.npmjs.org/nc-lib-gui/-/nc-lib-gui-0.90.3.tgz", "resolved": "https://registry.npmjs.org/nc-lib-gui/-/nc-lib-gui-0.90.5.tgz",
"integrity": "sha512-3ii6JGz0OV5c04GmR+61ToOnKsLR9pE08VJsmDPod7pOt15uDtL8yYrJBuqHi3NmPkEhm86FtNOT6TXFdE9dzg==", "integrity": "sha512-P/6LXq6xcHx+hpwXeN87zPHUeQXPUut8Rje2WfpF0uMhth+pBZAT7qpeBOu7fpp8YjzZd6YZ2w3jM1DiJDhuzw==",
"requires": { "requires": {
"axios": "^0.19.2", "axios": "^0.19.2",
"body-parser": "^1.19.0", "body-parser": "^1.19.0",
@ -12592,9 +12592,9 @@
"dev": true "dev": true
}, },
"nocodb-sdk": { "nocodb-sdk": {
"version": "0.90.3", "version": "0.90.5",
"resolved": "https://registry.npmjs.org/nocodb-sdk/-/nocodb-sdk-0.90.3.tgz", "resolved": "https://registry.npmjs.org/nocodb-sdk/-/nocodb-sdk-0.90.5.tgz",
"integrity": "sha512-qoQbuSIb/5qYyldZjtwZY6eZaQWzL/Z9pfsM+Aw8HivsyIqRLboKCAVEr6gJf/QToro49NEzjgisKMeX/YLB+w==", "integrity": "sha512-5H2nuVvt9n2DTQs9NMKtooGBXPpGjPoHIy6szXb+feigE2N8QPZNNt3YgpK9QaEG6mTpr04kXgCvFp0QsgV6Xg==",
"requires": { "requires": {
"axios": "^0.21.1", "axios": "^0.21.1",
"jsep": "^0.4.0" "jsep": "^0.4.0"

6
packages/nocodb/package.json

@ -1,6 +1,6 @@
{ {
"name": "nocodb", "name": "nocodb",
"version": "0.90.3", "version": "0.90.5",
"description": "NocoDB", "description": "NocoDB",
"main": "dist/bundle.js", "main": "dist/bundle.js",
"repository": "https://github.com/nocodb/nocodb", "repository": "https://github.com/nocodb/nocodb",
@ -151,10 +151,10 @@
"nanoid": "^3.1.20", "nanoid": "^3.1.20",
"nc-common": "0.0.6", "nc-common": "0.0.6",
"nc-help": "^0.2.44", "nc-help": "^0.2.44",
"nc-lib-gui": "0.90.3", "nc-lib-gui": "0.90.5",
"nc-plugin": "^0.1.1", "nc-plugin": "^0.1.1",
"ncp": "^2.0.0", "ncp": "^2.0.0",
"nocodb-sdk": "0.90.3", "nocodb-sdk": "0.90.5",
"nodemailer": "^6.4.10", "nodemailer": "^6.4.10",
"ora": "^4.0.4", "ora": "^4.0.4",
"os-locale": "^5.0.0", "os-locale": "^5.0.0",

76
packages/nocodb/src/lib/noco/meta/api/projectUserApis.ts

@ -9,7 +9,11 @@ import User from '../../../noco-models/User';
import { Tele } from 'nc-help'; import { Tele } from 'nc-help';
import Audit from '../../../noco-models/Audit'; import Audit from '../../../noco-models/Audit';
import NocoCache from '../../../noco-cache/NocoCache'; import NocoCache from '../../../noco-cache/NocoCache';
import { CacheGetType, CacheScope } from '../../../utils/globals'; import { CacheGetType, CacheScope, MetaTable } from '../../../utils/globals';
import * as ejs from 'ejs';
import NcPluginMgrv2 from '../helpers/NcPluginMgrv2';
import Noco from '../../Noco';
import { PluginCategory } from 'nocodb-sdk';
async function userList(req, res) { async function userList(req, res) {
res.json({ res.json({
@ -112,15 +116,12 @@ async function userInvite(req, res, next): Promise<any> {
// in case of single user check for smtp failure // in case of single user check for smtp failure
// and send back token if failed // and send back token if failed
if ( if (
emails.length === 1 emails.length === 1 &&
// todo: email !(await sendInviteEmail(email, invite_token, req))
// &&
// !(await sendInviteEmail(email, invite_token, req))
) { ) {
return res.json({ invite_token, email }); return res.json({ invite_token, email });
} else { } else {
// todo: email sendInviteEmail(email, invite_token, req);
// sendInviteEmail(email, invite_token, req);
} }
} catch (e) { } catch (e) {
console.log(e); console.log(e);
@ -209,16 +210,13 @@ async function projectUserDelete(req, res): Promise<any> {
NcError.forbidden('Insufficient privilege to delete a owner user.'); NcError.forbidden('Insufficient privilege to delete a owner user.');
} }
// await this.users.where('id', req.params.id).del();
await ProjectUser.delete(project_id, req.params.userId); await ProjectUser.delete(project_id, req.params.userId);
res.json({ res.json({
msg: 'success' msg: 'success'
}); });
} }
// todo: map api async function projectUserInviteResend(req, res): Promise<any> {
// @ts-ignore
async function resendInvite(req, res, next): Promise<any> {
const user = await User.get(req.params.userId); const user = await User.get(req.params.userId);
if (!user) { if (!user) {
@ -233,8 +231,18 @@ async function resendInvite(req, res, next): Promise<any> {
invite_token_expires: new Date(Date.now() + 24 * 60 * 60 * 1000) invite_token_expires: new Date(Date.now() + 24 * 60 * 60 * 1000)
}); });
// todo: const pluginData = await Noco.ncMeta.metaGet2(null, null, MetaTable.PLUGIN, {
// await sendInviteEmail(user.email, invite_token, req); category: PluginCategory.EMAIL,
active: true
});
if (!pluginData) {
NcError.badRequest(
`No Email Plugin is found. Please go to App Store to configure first or copy the invitation URL to users instead.`
);
}
await sendInviteEmail(user.email, invite_token, req);
Audit.insert({ Audit.insert({
op_type: 'AUTHENTICATION', op_type: 'AUTHENTICATION',
@ -248,6 +256,44 @@ async function resendInvite(req, res, next): Promise<any> {
res.json({ msg: 'success' }); res.json({ msg: 'success' });
} }
async function sendInviteEmail(
email: string,
token: string,
req: any
): Promise<any> {
try {
const template = (await import('./userApi/ui/emailTemplates/invite'))
.default;
const emailAdapter = await NcPluginMgrv2.emailAdapter();
if (emailAdapter) {
await emailAdapter.mailSend({
to: email,
subject: 'Verify email',
html: ejs.render(template, {
signupLink: `${req.ncSiteUrl}${
Noco.getConfig()?.dashboardPath
}#/user/authentication/signup/${token}`,
projectName: req.body?.projectName,
roles: (req.body?.roles || '')
.split(',')
.map(r => r.replace(/^./, m => m.toUpperCase()))
.join(', '),
adminEmail: req.session?.passport?.user?.email
})
});
return true;
}
} catch (e) {
console.log(
'Warning : `mailSend` failed, Please configure emailClient configuration.',
e.message
);
throw e;
}
}
const router = Router({ mergeParams: true }); const router = Router({ mergeParams: true });
router.get( router.get(
'/api/v1/db/meta/projects/:projectId/users', '/api/v1/db/meta/projects/:projectId/users',
@ -265,4 +311,8 @@ router.delete(
'/api/v1/db/meta/projects/:projectId/users/:userId', '/api/v1/db/meta/projects/:projectId/users/:userId',
ncMetaAclMw(projectUserDelete, 'projectUserDelete') ncMetaAclMw(projectUserDelete, 'projectUserDelete')
); );
router.post(
'/api/v1/db/meta/projects/:projectId/users/:userId/resend-invite',
ncMetaAclMw(projectUserInviteResend, 'projectUserInviteResend')
);
export default router; export default router;

2
packages/nocodb/src/lib/noco/meta/helpers/NcPluginMgrv2.ts

@ -134,6 +134,8 @@ class NcPluginMgrv2 {
active: true active: true
}); });
if (!pluginData) return null;
const pluginConfig = defaultPlugins.find( const pluginConfig = defaultPlugins.find(
c => c.title === pluginData.title && c.category === PluginCategory.EMAIL c => c.title === pluginData.title && c.category === PluginCategory.EMAIL
); );

3
packages/nocodb/src/lib/utils/projectAcl.ts

@ -127,7 +127,8 @@ export default {
bulkDataDeleteAll: true, bulkDataDeleteAll: true,
relationDataRemove: true, relationDataRemove: true,
relationDataAdd: true, relationDataAdd: true,
dataCount: true dataCount: true,
upload: true
}, },
commenter: { commenter: {
formViewGet: true, formViewGet: true,

47
scripts/sdk/swagger.json

@ -4821,6 +4821,51 @@
} }
] ]
} }
},
"/api/v1/db/meta/projects/{projectId}/users/{userId}/resend-invite": {
"parameters": [
{
"schema": {
"type": "string"
},
"name": "projectId",
"in": "path",
"required": true
},
{
"schema": {
"type": "string"
},
"name": "userId",
"in": "path",
"required": true
}
],
"post": {
"summary": "",
"operationId": "auth-project-user-resend-invite",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {}
}
}
}
},
"tags": [
"Auth"
],
"description": "Resend Invitation to a specific user",
"requestBody": {
"content": {
"application/json": {
"schema": {}
}
}
}
}
} }
}, },
"components": { "components": {
@ -7718,4 +7763,4 @@
} }
} }
} }
} }
Loading…
Cancel
Save