Browse Source

Merge pull request #1138 from nocodb/develop

0.84.10 Pre-Release
pull/1140/head
navi 3 years ago committed by GitHub
parent
commit
8d96a8c977
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1390
      .github/workflows/ci-cd.yml
  2. 2
      README.md
  3. 2
      docker-compose/mssql/docker-compose.yml
  4. 2
      docker-compose/mysql/docker-compose.yml
  5. 2
      docker-compose/nginx-proxy-manager/docker-compose.yml
  6. 2
      docker-compose/pg/docker-compose.yml
  7. 6
      packages/nc-gui/components/ProjectTreeView.vue
  8. 14
      packages/nc-gui/components/project/spreadsheet/components/columnFilter.vue
  9. 8
      packages/nc-gui/components/project/spreadsheet/components/columnFilterMenu.vue
  10. 16
      packages/nc-gui/components/project/spreadsheet/components/fieldsMenu.vue
  11. 23
      packages/nc-gui/components/project/spreadsheet/components/importExport/columnMappingModal.vue
  12. 10
      packages/nc-gui/components/project/spreadsheet/components/moreActions.vue
  13. 3
      packages/nc-gui/components/project/spreadsheet/components/shareViewMenu.vue
  14. 10
      packages/nc-gui/components/project/spreadsheet/components/sortListMenu.vue
  15. 30
      packages/nc-gui/components/project/spreadsheet/public/xcTable.vue
  16. 25
      packages/nc-gui/components/project/spreadsheet/rowsXcDataTable.vue
  17. 4
      packages/nc-gui/components/project/spreadsheet/views/xcGridView.vue
  18. 2
      packages/nc-gui/components/project/tableTabs/columnsMock.vue
  19. 2
      packages/nc-gui/components/project/tableTabs/constraints.vue
  20. 2
      packages/nc-gui/components/project/tableTabs/indexes.vue
  21. 2
      packages/nc-gui/components/project/tableTabs/relations.vue
  22. 4
      packages/nc-gui/components/project/tableTabs/triggers.vue
  23. 116
      packages/nc-gui/components/project/viewTabs/viewSpreadsheet.vue
  24. 3
      packages/nc-gui/components/projectTabs.vue
  25. 10
      packages/nc-gui/components/sponsorMini.vue
  26. 5
      packages/nc-gui/components/templates/editor.vue
  27. 2
      packages/nc-gui/helpers/sqlUi/PgUi.js
  28. 3
      packages/nc-gui/lang/en.json
  29. 31
      packages/nc-gui/layouts/default.vue
  30. 2
      packages/nc-gui/store/tabs.js
  31. 6
      packages/noco-docs/content/en/getting-started/installation.md
  32. 2
      packages/noco-docs/content/en/setup-and-usages/audit.md
  33. 2
      packages/noco-docs/content/en/setup-and-usages/column-operations.md
  34. 2
      packages/noco-docs/content/en/setup-and-usages/column-types.md
  35. 2
      packages/noco-docs/content/en/setup-and-usages/dashboard.md
  36. 2
      packages/noco-docs/content/en/setup-and-usages/formulas.md
  37. 2
      packages/noco-docs/content/en/setup-and-usages/link-to-another-record.md
  38. 2
      packages/noco-docs/content/en/setup-and-usages/lookup.md
  39. 2
      packages/noco-docs/content/en/setup-and-usages/meta-management.md
  40. 2
      packages/noco-docs/content/en/setup-and-usages/primary-value.md
  41. 2
      packages/noco-docs/content/en/setup-and-usages/rollup.md
  42. 2
      packages/noco-docs/content/en/setup-and-usages/sync-schema.md
  43. 2
      packages/noco-docs/content/en/setup-and-usages/table-operations.md
  44. 2
      packages/noco-docs/content/en/setup-and-usages/team-and-auth.md
  45. 40
      packages/noco-docs/content/en/setup-and-usages/usage-information.md
  46. 28
      packages/nocodb/src/lib/noco/common/BaseApiBuilder.ts
  47. 11
      packages/nocodb/src/lib/noco/gql/GqlApiBuilder.ts
  48. 11
      packages/nocodb/src/lib/noco/rest/RestApiBuilder.ts
  49. 2
      packages/nocodb/src/lib/sqlUi/PgUi.ts
  50. 2
      scripts/cypress/integration/common/6b_downloadCsv.js
  51. 3
      scripts/cypress/integration/common/6d_language_validation.js
  52. 2
      scripts/markdown/readme/languages/chinese.md
  53. 2
      scripts/markdown/readme/languages/dutch.md
  54. 2
      scripts/markdown/readme/languages/french.md
  55. 2
      scripts/markdown/readme/languages/german.md
  56. 2
      scripts/markdown/readme/languages/indonesian.md
  57. 2
      scripts/markdown/readme/languages/italian.md
  58. 2
      scripts/markdown/readme/languages/japanese.md
  59. 2
      scripts/markdown/readme/languages/korean.md
  60. 2
      scripts/markdown/readme/languages/portuguese.md
  61. 2
      scripts/markdown/readme/languages/russian.md
  62. 2
      scripts/markdown/readme/languages/spanish.md

1390
.github/workflows/ci-cd.yml

File diff suppressed because it is too large Load Diff

2
README.md

@ -224,7 +224,7 @@ git clone https://github.com/nocodb/nocodb
cd nocodb
cd docker-compose
cd mysql or pg or mssql
docker-compose up
docker-compose up -d
```
## Environment variables

2
docker-compose/mssql/docker-compose.yml

@ -6,6 +6,7 @@ services:
restart: always
volumes:
- db_data:/var/opt/mssql
- nc_data:/usr/app/data
environment:
SA_PASSWORD: Password123.
ACCEPT_EULA: Y
@ -28,3 +29,4 @@ services:
NC_DB: "mssql://root_db:1433?u=sa&p=Password123.&d=root_db"
volumes:
db_data: {}
nc_data: {}

2
docker-compose/mysql/docker-compose.yml

@ -5,6 +5,7 @@ services:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
- nc_data:/usr/app/data
restart: always
environment:
MYSQL_ROOT_PASSWORD: password
@ -28,3 +29,4 @@ services:
NC_DB: "mysql2://root_db:3306?u=noco&p=password&d=root_db"
volumes:
db_data: {}
nc_data: {}

2
docker-compose/nginx-proxy-manager/docker-compose.yml

@ -5,6 +5,7 @@ services:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
- nc_data:/usr/app/data
restart: always
environment:
MYSQL_ROOT_PASSWORD: password
@ -49,6 +50,7 @@ services:
volumes:
nginx-proxy-manager: {}
db_data: {}
nc_data: {}
networks:
default:

2
docker-compose/pg/docker-compose.yml

@ -6,6 +6,7 @@ services:
restart: always
volumes:
- db_data:/var/lib/postgresql/data
- nc_data:/usr/app/data
environment:
POSTGRES_PASSWORD: password
POSTGRES_USER: postgres
@ -27,3 +28,4 @@ services:
NC_DB: "pg://root_db:5432?u=postgres&p=password&d=root_db"
volumes:
db_data: {}
nc_data: {}

6
packages/nc-gui/components/ProjectTreeView.vue

@ -32,7 +32,7 @@
<v-text-field
v-else
v-model="search"
placeholder="Search tables"
:placeholder="$t('placeholder.searchProjectTree')"
dense
hide-details
class="elevation-0 mr-2 pl-3 pr-1 caption nc-table-list-filter"
@ -162,7 +162,7 @@
<v-tooltip v-if="!isNonAdminAccessAllowed(item)" top>
<template #activator="{ on }">
<span v-if="item.type === 'tableDir'" class="body-2 font-weight-medium" v-on="on">
Tables<template v-if="item.children && item.children.length"> ({{
{{ $t('objects.tables') }}<template v-if="item.children && item.children.length"> ({{
item.children.filter(child => !search || child.name.toLowerCase().includes(search.toLowerCase())).length
}})</template></span>
<span v-else class="body-2 font-weight-medium" v-on="on">
@ -174,7 +174,7 @@
v-else
>
<span v-if="item.type === 'tableDir'" class="body-2 font-weight-medium">
Tables<template v-if="item.children && item.children.length"> ({{
{{ $t('objects.tables') }}<template v-if="item.children && item.children.length"> ({{
item.children.filter(child => !search || child.name.toLowerCase().includes(search.toLowerCase())).length
}})</template></span>
<span v-else class="caption font-weight-regular">

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

@ -20,7 +20,10 @@
v-if="!i"
:key="i + '_2'"
class="caption d-flex align-center"
>where</span>
>
<!-- where -->
{{ $t('labels.where') }}
</span>
<v-select
v-else
@ -44,7 +47,7 @@
:key="i + '_5'"
v-model="filter.field"
class="caption "
placeholder="Field"
:placeholder="$t('objects.field')"
solo
flat
dense
@ -62,7 +65,7 @@
v-model="filter.field"
class="caption nc-filter-field-select"
:items="fieldList"
placeholder="Field"
:placeholder="$t('objects.field')"
solo
flat
dense
@ -79,7 +82,7 @@
v-model="filter.op"
class="flex-shrink-1 flex-grow-0 caption nc-filter-operation-select"
:items="opList"
placeholder="Operation"
:placeholder="$t('labels.operation')"
solo
flat
style="max-width:120px"
@ -126,7 +129,8 @@
<v-icon small color="grey">
mdi-plus
</v-icon>
Add Filter
<!-- Add Filter -->
{{ $t('activity.addFilter') }}
</v-btn>
<slot />
</div>

8
packages/nc-gui/components/project/spreadsheet/components/columnFilterMenu.vue

@ -19,7 +19,8 @@
<v-icon small class="mr-1" color="grey darken-3">
mdi-filter-outline
</v-icon>
Filter
<!-- Filter -->
{{ $t('activity.filter') }}
<v-icon small color="#777">
mdi-menu-down
</v-icon>
@ -38,7 +39,10 @@
color="grey"
>
<template #label>
<span class="grey--text caption">Auto apply</span>
<span class="grey--text caption">
{{ $t('msg.info.filterAutoApply') }}
<!-- Auto apply -->
</span>
</template>
</v-checkbox>

16
packages/nc-gui/components/project/spreadsheet/components/fieldsMenu.vue

@ -19,7 +19,8 @@
<v-icon small class="mr-1" color="#777">
mdi-eye-off-outline
</v-icon>
Fields
<!-- Fields -->
{{ $t('objects.fields') }}
<v-icon small color="#777">
mdi-menu-down
</v-icon>
@ -86,7 +87,7 @@
flat
class="caption mt-3 mb-2"
color="grey"
placeholder="Search fields"
:placeholder="$t('placeholder.searchFields')"
hide-details
@click.stop
>
@ -137,16 +138,21 @@
@click.stop
>
<template #label>
<span class="caption">Show System Fields</span>
<span class="caption">
<!-- Show System Fields -->
{{ $t('activity.showSystemFields') }}
</span>
</template>
</v-checkbox>
</v-list-item>
<v-list-item dense class="mt-2 list-btn mb-3">
<v-btn small class="elevation-0 grey--text" @click.stop="showAll">
Show All
<!-- Show All -->
{{ $t('general.showAll') }}
</v-btn>
<v-btn small class="elevation-0 grey--text" @click.stop="hideAll">
Hide All
<!-- Hide All -->
{{ $t('general.hideAll') }}
</v-btn>
</v-list-item>
</v-list>

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

@ -7,7 +7,11 @@
</v-card-title>
<v-spacer />
<v-btn
:disabled="!valid || requiredColumnValidationError"
:disabled="
!valid ||
(typeof requiredColumnValidationError === 'string' || requiredColumnValidationError) ||
(typeof noSelectedColumnError === 'string' || noSelectedColumnError)
"
color="primary"
large
@click="$emit('import',mappings)"
@ -21,6 +25,9 @@
<div v-if="requiredColumnValidationError" class="error--text caption pa-2 text-center">
{{ requiredColumnValidationError }}
</div>
<div v-if="noSelectedColumnError" class="error--text caption pa-2 text-center">
{{ noSelectedColumnError }}
</div>
<v-divider />
<v-container fluid>
<v-form ref="form" v-model="valid">
@ -39,7 +46,7 @@
<tbody>
<tr v-for="(r,i) in mappings" :key="i">
<td>
<v-checkbox v-model="r.enabled" class="mt-0" dense hide-details />
<v-checkbox v-model="r.enabled" class="mt-0" dense hide-details @change="$refs.form.validate()"/>
</td>
<td class="caption" style="width:45%">
<div :title="r.sourceCn" style="">
@ -117,6 +124,12 @@ export default {
return `Following columns are required : ${missingRequiredColumns.map(c => c._cn).join(', ')}`
}
return false
},
noSelectedColumnError() {
if ((this.mappings || []).filter(v => v.enabled === true).length == 0) {
return 'At least one column has to be selected'
}
return false
}
},
mounted() {
@ -129,6 +142,11 @@ export default {
return true
}
// if it is not selected, then pass validation
if (!row.enabled) {
return true
}
const v = this.meta && this.meta.columns.find(c => c._cn === _cn)
if ((this.mappings || []).filter(v => v.destCn === _cn).length > 1) { return 'Duplicate mapping found, please remove one of the mapping' }
@ -154,6 +172,7 @@ export default {
}
this.mappings.push(o)
}
this.$nextTick(()=> this.$refs.form.validate())
},
getIcon(uidt) {
return getUIDTIcon(uidt) || 'mdi-alpha-v-circle-outline'

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

@ -34,7 +34,8 @@
mdi-download-outline
</v-icon>
<span class="caption">
Download as CSV
<!-- Download as CSV -->
{{ $t('activity.downloadCSV') }}
</span>
</v-list-item-title>
</v-list-item>
@ -48,7 +49,8 @@
mdi-upload-outline
</v-icon>
<span class="caption ">
Upload CSV
<!-- Upload CSV -->
{{ $t('activity.uploadCSV') }}
</span>
<span class="caption grey--text">(<x-icon small color="grey lighten-2">
@ -66,7 +68,8 @@
mdi-view-list-outline
</v-icon>
<span class="caption ">
Shared View List
<!-- Shared View List -->
{{ $t('activity.listSharedView') }}
</span>
</v-list-item-title>
</v-list-item> <v-list-item
@ -286,6 +289,7 @@ export default {
}
this.columnMappingModal = false
this.$store.commit('loader/MutClear')
this.$emit('reload')
this.$toast.success('Successfully imported table data').goAway(3000)
} catch (e) {
this.$toast.error(e.message).goAway(3000)

3
packages/nc-gui/components/project/spreadsheet/components/shareViewMenu.vue

@ -17,7 +17,8 @@
<v-icon size="13" class="mr-1" color="#777">
mdi-open-in-new
</v-icon>
Share View
<!-- Share View -->
{{ $t('activity.shareView') }}
</v-btn>
<!-- </template>

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

@ -19,7 +19,8 @@
<v-icon small class="mr-1" color="#777">
mdi-sort
</v-icon>
Sort
<!-- Sort -->
{{ $t('activity.sort') }}
<v-icon small color="#777">
mdi-menu-down
</v-icon>
@ -38,7 +39,7 @@
v-model="sort.field"
class="caption nc-sort-field-select"
:items="fieldList"
label="Field"
:label="$t('objects.field')"
solo
flat
dense
@ -54,7 +55,7 @@
v-model="sort.order"
class="flex-shrink-1 flex-grow-0 caption nc-sort-dir-select"
:items="[{text : 'A -> Z', value: ''},{text : 'Z -> A', value: '-'}]"
label="Operation"
:label="$t('labels.operation')"
solo
flat
dense
@ -71,7 +72,8 @@
<v-icon small color="grey">
mdi-plus
</v-icon>
Add Sort Option
<!-- Add Sort Option -->
{{ $t('activity.addSort') }}
</v-btn>
</div>
</v-menu>

30
packages/nc-gui/components/project/spreadsheet/public/xcTable.vue

@ -15,14 +15,19 @@
<span class="font-weight-bold"> {{ viewName }}</span> <span class="font-weight-regular ml-1" />
</div>
<v-toolbar v-if="meta" height="40" dense class="elevation-0 xc-toolbar xc-border-bottom" style="z-index: 7;border-radius: 4px">
<!--
<div class="d-flex xc-border align-center search-box">
<v-toolbar
v-if="meta"
height="32"
dense
class="nc-table-toolbar elevation-0 xc-toolbar xc-border-bottom mx-1"
style="z-index: 7"
>
<div class="d-flex xc-border align-center search-box" style="min-width:156px">
<v-menu bottom offset-y>
<template #activator="{on}">
<div v-on="on">
<div style="min-width: 56px" v-on="on">
<v-icon
class="pa-1 pr-0 ml-2"
class="ml-2"
small
color="grey"
>
@ -56,7 +61,7 @@
<v-text-field
v-model="searchQuery"
autocomplete="off"
style="min-width: 300px"
style="min-width: 100px ; width: 150px"
flat
dense
solo
@ -74,16 +79,15 @@
>{{ refTable }}({{
relationPrimaryValue
}}) -> {{ relationType === 'hm' ? ' Has Many ' : ' Belongs To ' }} -> {{ table }}</span>
-->
<v-spacer />
<div class="d-inline-flex">
<v-btn outlined small text @click="reload">
<!-- <v-btn outlined small text @click="reload">
<v-icon small class="mr-1" color="grey darken-3">
mdi-reload
</v-icon>
Reload
</v-btn>
</v-btn> -->
<fields-menu v-model="showFields" :field-list="fieldList" is-public />
@ -92,7 +96,8 @@
<column-filter-menu v-model="filters" :field-list="realFieldList" />
<csv-export-import :is-view="isView" :query-params="{...queryParams, showFields}" :public-view-id="$route.params.id" :meta="meta" />
</div>
<v-spacer class="h-100" @dblclick="debug=true" />
<!-- <v-menu>
<template #activator="{ on, attrs }">
<v-icon
@ -293,7 +298,7 @@ export default {
concatenatedXWhere() {
let where = ''
if (this.searchField && this.searchQuery.trim()) {
if (['text', 'string'].includes(this.sqlUi.getAbstractType(this.meta.columns.find(({ cn }) => cn === this.searchField)))) {
if (['text', 'string'].includes(this.sqlUi.getAbstractType(this.meta.columns.find(({ _cn }) => _cn === this.searchField)))) {
where = `(${this.searchField},like,%${this.searchQuery.trim()}%)`
} else {
where = `(${this.searchField},eq,${this.searchQuery.trim()})`
@ -720,6 +725,7 @@ export default {
*
* @author Naveen MR <oof1lab@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
*

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

@ -50,7 +50,7 @@
dense
solo
hide-details
:placeholder="searchField ? `Search '${searchField}' column` : 'Search all columns'"
:placeholder="searchField ? $t('placeholder.searchColumn', {searchField}) : 'Search all columns'"
class="elevation-0 pa-0 flex-grow-1 caption search-field"
@keyup.enter="searchQuery = searchQueryVal"
@blur="searchQuery = searchQueryVal"
@ -110,6 +110,7 @@
:selected-view="selectedView"
@showAdditionalFeatOverlay="showAdditionalFeatOverlay($event)"
@webhook="showAdditionalFeatOverlay('webhooks')"
@reload="reload"
/>
</div>
<v-spacer class="h-100" @dblclick="debug=true" />
@ -138,6 +139,7 @@
<v-icon small class="mx-n1" color="grey lighten-1">
mdi-circle-small
</v-icon>
<!-- tooltip="Reload view data" -->
<x-icon
tooltip="Reload view data"
icon.class="nc-table-reload-btn mx-1"
@ -165,10 +167,12 @@
<!-- btn.class="nc-add-new-row-btn"-->
<!-- @click="insertNewRow(true,true)"-->
<!-- >-->
<!-- tooltip="Add new row"-->
<x-icon
v-if="isEditable && relationType !== 'bt'"
icon.class="nc-add-new-row-btn mx-1"
tooltip="Add new row"
:tooltip="$t('activity.addRow')"
:disabled="isLocked"
small
:color="['success','']"
@ -219,7 +223,7 @@
:disabled="isLocked"
small
:color="['red',''] "
tooltip="Delete table"
:tooltip="$t('activity.deleteTable')"
@click="checkAndDeleteTable"
>
mdi-delete-outline
@ -524,13 +528,22 @@
v-if="relationType !== 'bt'"
@click="insertNewRow(false)"
>
<span class="caption">Insert New Row</span>
<span class="caption">
<!-- Insert New Row -->
{{ $t('activity.insertRow') }}
</span>
</v-list-item>
<v-list-item @click="deleteRow">
<span class="caption">Delete Row</span>
<span class="caption">
<!-- Delete Row -->
{{ $t('activity.deleteRow') }}
</span>
</v-list-item>
<v-list-item @click="deleteSelectedRows">
<span class="caption">Delete Selected Rows</span>
<span class="caption">
<!-- Delete Selected Rows -->
{{ $t('activity.deleteSelectedRow') }}
</span>
</v-list-item>
</template>
<template v-if="rowContextMenu.col && !rowContextMenu.col.rqd && !rowContextMenu.col.virtual">

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

@ -244,7 +244,9 @@
<v-icon small color="pink" v-on="on">
mdi-plus
</v-icon>
<span class="ml-1 caption grey--text ">New Row</span>
<span class="ml-1 caption grey--text ">
{{ $t('activity.addRow') }}
</span>
</template>
<span class="caption"> Add new row</span>
</v-tooltip>

2
packages/nc-gui/components/project/tableTabs/columnsMock.vue

@ -69,7 +69,7 @@
class="error text-right"
@click="deleteTable('showDialog')"
>
Delete Table &nbsp;
{{ $t('activity.deleteTable') }} &nbsp;
<v-progress-circular
v-if="progress.deleteTable"

2
packages/nc-gui/components/project/tableTabs/constraints.vue

@ -45,7 +45,7 @@
class="error text-right"
@click="deleteTable('showDialog')"
>
Delete Table
{{ $t('activity.deleteTable') }}
</v-btn>
<v-btn
icon

2
packages/nc-gui/components/project/tableTabs/indexes.vue

@ -65,7 +65,7 @@
<x-btn
v-ge="['indexes','delete-table']"
outlined
tooltip="Delete Table"
:tooltip="$t('activity.deleteTable')"
small
color="error "
class="error text-right"

2
packages/nc-gui/components/project/tableTabs/relations.vue

@ -15,7 +15,7 @@
class=" text-right"
@click="deleteTable('showDialog')"
>
Delete Table
{{ $t('activity.deleteTable') }}
</v-btn>
<v-btn @click="throwError()">
error

4
packages/nc-gui/components/project/tableTabs/triggers.vue

@ -65,14 +65,14 @@
<x-btn
v-ge="['triggers','delete']"
outlined
tooltip="Delete Table"
:tooltip="$t('activity.deleteTable')"
small
icon="mdi-delete-outline"
class="error text-right"
color="error "
@click="deleteTable('showDialog')"
>
Delete Table
{{ $t('activity.deleteTable') }}
</x-btn>
</v-toolbar>
<v-skeleton-loader v-if="loading" type="table" />

116
packages/nc-gui/components/project/viewTabs/viewSpreadsheet.vue

@ -1,16 +1,20 @@
<template>
<v-container class=" j-excel-container pa-0 ma-0" fluid>
<v-container class="h-100 j-excel-container backgroundColor pa-0 ma-0" fluid>
<div v-if="modelName" class="model-name text-capitalize">
<span class="font-weight-bold"> {{ modelName }}</span> <span class="font-weight-regular ml-1">( Main View )</span>
</div>
<v-toolbar height="36" dense class="elevation-0 xc-toolbar xc-border-bottom" style="z-index: 7;border-radius: 4px">
<div class="d-flex xc-border align-center search-box">
<v-toolbar
height="32"
dense
class="nc-table-toolbar elevation-0 xc-toolbar xc-border-bottom mx-1"
style="z-index: 7"
>
<div class="d-flex xc-border align-center search-box" style="min-width:156px">
<v-menu bottom offset-y>
<template #activator="{on}">
<div v-on="on">
<div style="min-width: 56px" v-on="on">
<v-icon
class="pa-1 pr-0 ml-2"
class="ml-2"
small
color="grey"
>
@ -44,7 +48,7 @@
<v-text-field
v-model="searchQuery"
autocomplete="off"
style="min-width: 300px"
style="min-width: 100px ; width: 150px"
flat
dense
solo
@ -63,47 +67,49 @@
relationPrimaryValue
}}) -> {{ relationType === 'hm' ? ' Has Many ' : ' Belongs To ' }} -> {{ table }}</span>
<v-spacer />
<div class="d-inline-flex">
<v-btn outlined small text @click="loadTableData">
<v-icon small class="mr-1" color="grey darken-3">
mdi-reload
<fields-menu v-model="showFields" :field-list="fieldList" :is-locked="isLocked" />
<sort-list-menu v-model="sortList" :field-list="fieldList" :is-locked="isLocked" />
<column-filter-menu v-model="filters" :field-list="fieldList" :is-locked="isLocked" />
<share-view-menu @share="$refs.drawer && $refs.drawer.genShareLink()" />
<MoreActions
ref="csvExportImport"
:meta="meta"
:nodes="nodes"
:query-params="{
fieldsOrder,
fieldFilter,
sortList,
showFields
}"
:selected-view="selectedView"
:is-view="true"
@showAdditionalFeatOverlay="showAdditionalFeatOverlay($event)"
@webhook="showAdditionalFeatOverlay('webhooks')"
/>
</div>
<v-spacer class="h-100" @dblclick="debug=true" />
<template>
<debug-metas v-if="debug" class="mr-3" />
<lock-menu v-if="_isUIAllowed('view-type')" v-model="viewStatus.type" />
<v-icon small class="mx-n1" color="grey lighten-1">
mdi-circle-small
</v-icon>
Reload
</v-btn>
<fields-menu v-model="showFields" :field-list="fieldList" />
<sort-list-menu v-model="sortList" :field-list="fieldList" />
<column-filter-menu v-model="filters" :field-list="fieldList" />
<!-- <v-menu>
<template #activator="{ on, attrs }">
<v-icon
v-bind="attrs"
small
class="mx-2"
color="grey darken-3"
v-on="on"
>
mdi-arrow-collapse-vertical
</v-icon>
</template>
<v-list dense class="caption">
<v-list-item v-for="h in cellHeights" :key="h.size" dense @click.stop="cellHeight = h.size">
<v-list-item-icon class="mr-1">
<v-icon small :color="cellHeight === h.size && 'primary'">
{{ h.icon }}
</v-icon>
</v-list-item-icon>
<v-list-item-title :class="{'primary&#45;&#45;text' : cellHeight === h.size}" style="text-transform: capitalize">
{{ h.size }}
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>-->
<x-icon
tooltip="Reload view data"
icon.class="nc-table-reload-btn mx-1"
small
@click="loadTableData"
>
mdi-reload
</x-icon>
</template>
<x-btn
tooltip="Toggle navigation drawer"
@ -195,6 +201,7 @@
</div>
<spreadsheet-nav-drawer
ref="drawer"
:nodes="nodes"
:table="table"
:meta="meta"
@ -208,6 +215,7 @@
:filters.sync="filters"
:sort-list.sync="sortList"
:show-fields.sync="showFields"
:view-status.sync="viewStatus"
>
<!-- <v-list-item
@click="showAdditionalFeatOverlay('view-columns')"
@ -239,7 +247,6 @@
<script>
import debounce from 'debounce'
import ApiFactory from '@/components/project/spreadsheet/apis/apiFactory'
import { SqlUI } from '@/helpers/sqlUi/SqlUiFactory'
import FieldsMenu from '@/components/project/spreadsheet/components/fieldsMenu'
import SortListMenu from '@/components/project/spreadsheet/components/sortListMenu'
@ -251,6 +258,10 @@ import KanbanView from '@/components/project/spreadsheet/views/kanbanView'
import CalendarView from '@/components/project/spreadsheet/views/calendarView'
import AdditionalFeatures from '@/components/project/spreadsheet/overlay/additinalFeatures'
import spreadsheet from '@/components/project/spreadsheet/mixins/spreadsheet'
import MoreActions from '@/components/project/spreadsheet/components/moreActions'
import ShareViewMenu from '@/components/project/spreadsheet/components/shareViewMenu'
import LockMenu from '@/components/project/spreadsheet/components/lockMenu'
export default {
name: 'Spreadsheet',
@ -263,7 +274,10 @@ export default {
XcGridView,
ColumnFilterMenu,
SortListMenu,
FieldsMenu
FieldsMenu,
ShareViewMenu,
MoreActions,
LockMenu,
},
mixins: [spreadsheet],
props: {
@ -340,7 +354,10 @@ export default {
icon: 'mdi-card'
}],
rowContextMenu: null,
modelName: null
modelName: null,
viewStatus: {
type: null
},
}),
computed: {
meta() {
@ -638,6 +655,7 @@ export default {
*
* @author Naveen MR <oof1lab@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
*

3
packages/nc-gui/components/projectTabs.vue

@ -253,9 +253,10 @@
<!-- </v-tabs-items>-->
</v-tabs-items>
<!-- tooltip: Add new table -->
<x-icon
v-if="_isUIAllowed('addTable')"
tooltip="Create new table"
:tooltip="$t('tooltip.addTable')"
icon-class="add-btn"
:color="[ 'white','grey lighten-2']"
@click="dialogCreateTableShow = true"

10
packages/nc-gui/components/sponsorMini.vue

@ -14,14 +14,16 @@
/>
</template>
</v-img>
<!-- You can help us! -->
<v-card-title v-if="!nav" class="pb-2" :class="{'body-2 justify-center mt-n2' : nav}">
You can help us
{{ $t('msg.info.sponsor.header') }}
</v-card-title>
<v-card-text v-if="!nav" class="pb-0">
<p class="caption text-left body-1 textColor--text text--lighten-1">
<template>
We are a tiny team working full time to make NocoDB open source. We believe a tool like NocoDB should be
available freely to every problem solver on internet.
<!-- We are a tiny team working full time to make NocoDB open source. We believe a tool like NocoDB should be
available freely to every problem solver on internet. -->
{{ $t('msg.info.sponsor.message') }}
</template>
</p>
</v-card-text>
@ -30,7 +32,7 @@
<v-icon small color="red" class="mr-2">
mdi-cards-heart
</v-icon>
Sponsor Us
{{ $t('activity.sponsorUs') }}
</v-btn>
</v-card-actions>
</v-card>

5
packages/nc-gui/components/templates/editor.vue

@ -578,7 +578,10 @@
<v-icon>mdi-plus</v-icon>
</v-btn>
</template>
<span class="caption">Add new table</span>
<span class="caption">
<!--Add new table-->
{{ $t('tooltip.addTable') }}
</span>
</v-tooltip>
</div>
</template>

2
packages/nc-gui/helpers/sqlUi/PgUi.js

@ -1609,7 +1609,7 @@ export class PgUi {
colProp.validate = { func: ['isCurrency'], args: [''], msg: ['Validation failed : Invalid Currency Format'] }
break
case 'Percent':
colProp.dt = 'double'
colProp.dt = 'float8'
break
case 'Duration':
colProp.dt = 'int8'

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

@ -260,6 +260,7 @@
"createTable": "Table Create",
"refreshTable": "Tables Refresh",
"renameTable": "Table Rename",
"deleteTable": "Table Delete",
"addField": "Add new field to this table",
"setPrimary": "Set as Primary value",
"addRow": "Add new row",
@ -344,7 +345,7 @@
},
"searchProjectTree": "Search tables",
"searchFields": "Search fields",
"searchColumn": "Search {search} column",
"searchColumn": "Search {searchField} column",
"searchApps": "Search apps",
"searchModels": "Search models",
"noItemsFound": "No items found",

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

@ -22,7 +22,8 @@
><v-icon color="primary">alpha-c-circle </v-icon> -->
</v-btn>
</template>
Home
<!-- Home -->
{{ $t('general.home') }}
<span
class="caption ml-1 font-weight-light"
>(v{{
@ -67,7 +68,8 @@
</template>
</v-toolbar-items>-->
<span v-show="$nuxt.$loading.show" class="caption grey--text ml-3">Loading <v-icon small color="grey">mdi-spin mdi-loading</v-icon></span>
<!-- loading -->
<span v-show="$nuxt.$loading.show" class="caption grey--text ml-3">{{ $t('general.loading') }} <v-icon small color="grey">mdi-spin mdi-loading</v-icon></span>
<span
v-shortkey="[ 'ctrl','shift', 'd']"
@ -121,7 +123,8 @@
<v-icon small class="mr-1">
mdi-account-supervisor-outline
</v-icon>
Share
<!-- Share -->
{{ $t('activity.share') }}
</x-btn>
</div>
@ -236,7 +239,9 @@
</v-icon>
</template>
<h3 class="pa-3">
{{ $vuetify.theme.dark ? 'It does come in Black (^⇧B)' : 'Does it come in Black ? (^⇧B)' }}
<!-- "dark": "It does come in Black (^⇧B)",
"light": "Does it come in Black ? (^⇧B)" -->
{{ $vuetify.theme.dark ? $t('tooltip.theme.dark') : $t('tooltip.theme.light') }}
<i />
</h3>
</v-tooltip>
@ -339,17 +344,19 @@
<v-divider />
<!-- Copy Auth Token -->
<!-- "Auth token copied to clipboard" -->
<v-list-item
v-if="isDashboard"
v-clipboard="$store.state.users.token"
dense
@click.stop="$toast.success('Auth token copied to clipboard').goAway(3000)"
@click.stop="$toast.success($t('msg.toast.authToken')).goAway(3000)"
>
<v-list-item-title>
<v-icon key="terminal-dash" small>
mdi-content-copy
</v-icon>&nbsp;
<span class="font-weight-regular caption">Copy auth token</span>
<span class="font-weight-regular caption">{{ $t('activity.account.authToken') }}</span>
</v-list-item-title>
</v-list-item>
@ -374,7 +381,7 @@
{{ isGql ? 'mdi-graphql' : 'mdi-code-json' }}
</v-icon>&nbsp;
<span class="font-weight-regular caption">
{{ isGql ? 'GraphQL APIs' : 'Swagger APIs Doc' }}</span>
{{ isGql ? 'GraphQL APIs' : 'Swagger APIs' }}</span>
</v-list-item-title>
</v-list-item>
<v-divider />
@ -382,7 +389,7 @@
<v-list-item-title>
<v-icon small>
mdi-information-outline
</v-icon>&nbsp; <span class="font-weight-regular caption">Copy Project info</span>
</v-icon>&nbsp; <span class="font-weight-regular caption">{{ $t('activity.account.projInfo') }}</span>
</v-list-item-title>
</v-list-item>
@ -391,7 +398,7 @@
<v-icon key="terminal-dash" small>
mdi-palette
</v-icon>&nbsp;
<span class="font-weight-regular caption">Themes</span>
<span class="font-weight-regular caption">{{ $t('activity.account.themes') }}</span>
</v-list-item-title>
</v-list-item>
@ -401,7 +408,7 @@
<v-list-item-title>
<v-icon small>
mdi-logout
</v-icon>&nbsp; <span class="font-weight-regular caption">Sign Out</span>
</v-icon>&nbsp; <span class="font-weight-regular caption">{{ $t('general.signOut') }}</span>
</v-list-item-title>
</v-list-item>
</template>
@ -422,14 +429,14 @@
mdi-account-plus-outline
</v-icon> &nbsp; <span
class="font-weight-regular caption"
>Sign Up</span>
>{{ $t('general.signUp') }}</span>
</v-list-item-title>
</v-list-item>
<v-list-item v-if="!user && !isThisMobile" dense to="/user/authentication/signin">
<v-list-item-title>
<v-icon small>
mdi-login
</v-icon> &nbsp; <span class="font-weight-regular caption">Login</span>
</v-icon> &nbsp; <span class="font-weight-regular caption">{{ $t('general.signIn') }}</span>
</v-list-item-title>
</v-list-item>
<!-- <v-list-item @click="openPricingPage">-->

2
packages/nc-gui/store/tabs.js

@ -171,7 +171,7 @@ export const actions = {
.list[0] // project
.children[0] // environment
.children[0] // db
.children.find(n => n.type === 'viewDir') // parent node
.children.find(n => n.type === 'tableDir') // parent node
.children.find(t => t.name === name)
break

6
packages/noco-docs/content/en/getting-started/installation.md

@ -155,7 +155,7 @@ And connection params for this database can be specified in `NC_DB` environment
cd nocodb
cd docker-compose
cd mysql
docker-compose up
docker-compose up -d
```
</code-block>
@ -167,7 +167,7 @@ And connection params for this database can be specified in `NC_DB` environment
cd nocodb
cd docker-compose
cd pg
docker-compose up
docker-compose up -d
```
</code-block>
@ -179,7 +179,7 @@ And connection params for this database can be specified in `NC_DB` environment
cd nocodb
cd docker-compose
cd mssql
docker-compose up
docker-compose up -d
```
</code-block>

2
packages/noco-docs/content/en/setup-and-usages/audit.md

@ -2,7 +2,7 @@
title: 'Audit'
description: 'Audit log'
position: 590
category: 'Usage'
category: 'Product'
menuTitle: 'Audit'
---

2
packages/noco-docs/content/en/setup-and-usages/column-operations.md

@ -2,7 +2,7 @@
title: "Column Operations"
description: "Column Operations"
position: 530
category: "Usage"
category: "Product"
menuTitle: "Column Operations"
---
## Fields

2
packages/noco-docs/content/en/setup-and-usages/column-types.md

@ -2,7 +2,7 @@
title: 'Column Types'
description: 'Column Types'
position: 520
category: 'Usage'
category: 'Product'
menuTitle: 'Column Types'
---

2
packages/noco-docs/content/en/setup-and-usages/dashboard.md

@ -2,7 +2,7 @@
title: 'Dashboard'
description: 'Dashboard'
position: 500
category: 'Usage'
category: 'Product'
menuTitle: 'Dashboard'
---

2
packages/noco-docs/content/en/setup-and-usages/formulas.md

@ -2,7 +2,7 @@
title: "Formulas"
description: "Formulas"
position: 570
category: "Usage"
category: "Product"
menuTitle: "Formulas"
---

2
packages/noco-docs/content/en/setup-and-usages/link-to-another-record.md

@ -2,7 +2,7 @@
title: "Link To Another Record"
description: "Link To Another Record"
position: 540
category: "Usage"
category: "Product"
menuTitle: "Link To Another Record"
---

2
packages/noco-docs/content/en/setup-and-usages/lookup.md

@ -2,7 +2,7 @@
title: "Lookup"
description: "Lookup"
position: 550
category: "Usage"
category: "Product"
menuTitle: "Lookup"
---

2
packages/noco-docs/content/en/setup-and-usages/meta-management.md

@ -2,7 +2,7 @@
title: 'Metadata'
description: 'Metadata'
position: 600
category: 'Usage'
category: 'Product'
menuTitle: 'Metadata'
---

2
packages/noco-docs/content/en/setup-and-usages/primary-value.md

@ -2,7 +2,7 @@
title: "Primary value"
description: "Primary value"
position: 575
category: "Usage"
category: "Product"
menuTitle: "Primary value"
---

2
packages/noco-docs/content/en/setup-and-usages/rollup.md

@ -2,7 +2,7 @@
title: "Rollup"
description: "Rollup"
position: 560
category: "Usage"
category: "Product"
menuTitle: "Rollup"
---

2
packages/noco-docs/content/en/setup-and-usages/sync-schema.md

@ -2,7 +2,7 @@
title: 'Sync Schema'
description: 'Schema changes made to database from outside nocodb GUI can be synced'
position: 610
category: 'Usage'
category: 'Product'
menuTitle: 'Sync Schema'
---

2
packages/noco-docs/content/en/setup-and-usages/table-operations.md

@ -2,7 +2,7 @@
title: "Table Operations"
description: "Table Operations"
position: 510
category: "Usage"
category: "Product"
menuTitle: "Table Operations"
---

2
packages/noco-docs/content/en/setup-and-usages/team-and-auth.md

@ -2,7 +2,7 @@
title: 'Team & Auth'
description: 'Breakdown of roles & permissions for team user management'
position: 620
category: 'Usage'
category: 'Product'
menuTitle: 'Team & Auth'
---

40
packages/noco-docs/content/en/setup-and-usages/usage-information.md

@ -0,0 +1,40 @@
---
title: 'Usage Information'
description: 'Non-sensitive and anonymous usage information'
position: 900
category: 'Product'
menuTitle: 'Usage Information'
---
NocoDB is a fast growing open source project and we are committed to providing a solution that exceeds the expectations of the users and community.
We are also committed to continuing to develop and make NocoDB even better than it is today.
To that end, NocoDB contains a feature in which anonymous and otherwise non-sensitive data is collected.
This anonymous and non-sensitive data gives a better understanding of how users are interacting and using the product.
## Context
We will always continue to do hands-on UI/UX testing, surveys, issue tracking and roadmap.
Otherwise talk with the Community while striving to understand
and deliver what is being asked for and what is needed, by any means available.
However, these above actions alone are often insufficient to maintain an overall picture of the product usage.
## What we collect ?
The following data is collected:
- Unique machine ID (generated with node-machine-id)
- Environment (dev, staging, production)
- System information (OS, node version, docker or npm)
- Failures and errors.
- Create and delete events of a project, table, view, linkToAnotherRecord, sharedView, user, hook, image, sharedBase.
## What we DO NOT collect ?
We do not collect private or sensitive information, such as:
- Personally identifiable information
- Credential information (endpoints, ports, DB connections, username/password)
- User data
## Opt-out
To disable usage information collection please set following environment variable.
> NC_DISABLE_TELE=true

28
packages/nocodb/src/lib/noco/common/BaseApiBuilder.ts

@ -32,6 +32,7 @@ import ncModelsOrderUpgrader from './jobs/ncModelsOrderUpgrader';
import ncParentModelTitleUpgrader from './jobs/ncParentModelTitleUpgrader';
import ncRemoveDuplicatedRelationRows from './jobs/ncRemoveDuplicatedRelationRows';
import xcMetaDiffSync from './handlers/xcMetaDiffSync';
import UITypes from '../../sqlUi/UITypes';
const log = debug('nc:api:base');
@ -755,11 +756,12 @@ export default abstract class BaseApiBuilder<T extends Noco>
const columns =
changeObj.columns
.filter(c => c.altered !== 4)
.map(({ altered: _al, ...rest }) => ({
...rest,
// find and overwrite column property from db
...(columnsFromDb?.find(c => c.cn === rest.cn) || {})
})) || (await this.getColumnList(tn));
.map(({ altered: _al, ...rest }) =>
this.mergeUiColAndDbColMetas(
rest,
columnsFromDb?.find(c => c.cn === rest.cn)
)
) || (await this.getColumnList(tn));
/* Get all relations */
const relations = await this.relationsSyncAndGet();
@ -1201,6 +1203,22 @@ export default abstract class BaseApiBuilder<T extends Noco>
await NcHelp.executeOperations(aclOper, this.connectionConfig.client);
}
protected mergeUiColAndDbColMetas(uiCol, dbCol) {
return {
...(uiCol || {}),
...(dbCol || {}),
// persist x props for single/multi select
...(uiCol?.uidt === UITypes.SingleSelect ||
uiCol?.uidt === UITypes.MultiSelect
? {
dtx: uiCol.dtx,
dtxp: uiCol.dtxp,
dtxs: uiCol.dtxs
}
: {})
};
}
public async onViewUpdate(
viewName: string,
beforeMetaUpdate?: (args: any) => Promise<void>

11
packages/nocodb/src/lib/noco/gql/GqlApiBuilder.ts

@ -195,11 +195,12 @@ export class GqlApiBuilder extends BaseApiBuilder<Noco> implements XcMetaMgr {
const columns = args.columns
? {
[tn]: args.columns?.map(({ altered: _al, ...rest }) => ({
...rest,
// find and overwrite column property from db
...columnsFromDb?.find(c => c.cn === rest.cn)
}))
[tn]: args.columns?.map(({ altered: _al, ...rest }) =>
this.mergeUiColAndDbColMetas(
rest,
columnsFromDb?.find(c => c.cn === rest.cn)
)
)
}
: {};

11
packages/nocodb/src/lib/noco/rest/RestApiBuilder.ts

@ -881,11 +881,12 @@ export class RestApiBuilder extends BaseApiBuilder<Noco> {
const columns = args.columns
? {
[tn]: args.columns?.map(({ altered: _al, ...rest }) => ({
...rest,
// find and overwrite column property from db
...(columnsFromDb?.find(c => c.cn === rest.cn) || {})
}))
[tn]: args.columns?.map(({ altered: _al, ...rest }) =>
this.mergeUiColAndDbColMetas(
rest,
columnsFromDb?.find(c => c.cn === rest.cn)
)
)
}
: {};

2
packages/nocodb/src/lib/sqlUi/PgUi.ts

@ -1644,7 +1644,7 @@ export class PgUi {
};
break;
case 'Percent':
colProp.dt = 'double';
colProp.dt = 'float8';
break;
case 'Duration':
colProp.dt = 'int8';

2
scripts/cypress/integration/common/6b_downloadCsv.js

@ -9,10 +9,12 @@ export const genTest = (type, xcdb) => {
before(() => {
// loginPage.loginAndOpenProject(type)
cy.openTableTab("Country", 25);
cy.screenshot("6b-before");
});
after(() => {
cy.closeTableTab("Country");
cy.screenshot('6b-after')
});
it("Download verification- base view, default columns", () => {

3
scripts/cypress/integration/common/6d_language_validation.js

@ -9,6 +9,7 @@ export const genTest = (type, xcdb) => {
before(() => {
//loginPage.signIn(roles.owner.credentials)
mainPage.toolBarTopLeft(mainPage.HOME).click();
cy.screenshot("6d-1");
});
const langVerification = (idx, lang) => {
@ -20,6 +21,8 @@ export const genTest = (type, xcdb) => {
cy.get(".nc-menu-translate").click();
cy.getActiveMenu().find(".v-list-item").eq(idx).click();
cy.screenshot("6d-2");
// basic validations
// 1. Page title: "My Projects"
// 2. Button: "New Project"

2
scripts/markdown/readme/languages/chinese.md

@ -175,7 +175,7 @@ docker run -d -p 8080:8080 \
git clone https://github.com/nocodb/nocodb
cd docker-compose
cd mysql or pg or mssql
docker-compose up
docker-compose up -d
```
## 环境变量

2
scripts/markdown/readme/languages/dutch.md

@ -189,7 +189,7 @@ git clone https://github.com/nocodb/nocodb
cd nocodb
cd docker-compose
cd mysql or pg or mssql
docker-compose up
docker-compose up -d
```
## Environment variables

2
scripts/markdown/readme/languages/french.md

@ -180,7 +180,7 @@ git clone https://github.com/nocodb/nocodb
cd nocodb
cd docker-compose
cd mysql or pg or mssql
docker-compose up
docker-compose up -d
```
## Variables d'environnement

2
scripts/markdown/readme/languages/german.md

@ -191,7 +191,7 @@ git clone https://github.com/nocodb/nocodb
cd nocodb
cd docker-compose
cd mysql or pg or mssql
docker-compose up
docker-compose up -d
```
## Umgebungsvariablen

2
scripts/markdown/readme/languages/indonesian.md

@ -190,7 +190,7 @@ git clone https://github.com/nocodb/nocodb
cd nocodb
cd docker-compose
cd mysql or pg or mssql
docker-compose up
docker-compose up -d
```
## Environment variables

2
scripts/markdown/readme/languages/italian.md

@ -192,7 +192,7 @@ git clone https://github.com/nocodb/nocodb
cd nocodb
cd docker-compose
cd mysql or pg or mssql
docker-compose up
docker-compose up -d
```
## Variabili d'ambiente

2
scripts/markdown/readme/languages/japanese.md

@ -192,7 +192,7 @@ git clone https://github.com/nocodb/nocodb
cd nocodb
cd docker-compose
cd mysql or pg or mssql
docker-compose up
docker-compose up -d
```
## Environment variables

2
scripts/markdown/readme/languages/korean.md

@ -193,7 +193,7 @@ git clone https://github.com/nocodb/nocodb
cd nocodb
cd docker-compose
cd mysql or pg or mssql
docker-compose up
docker-compose up -d
```
## 환경변수

2
scripts/markdown/readme/languages/portuguese.md

@ -191,7 +191,7 @@ git clone https://github.com/nocodb/nocodb
cd nocodb
cd docker-compose
cd mysql or pg or mssql
docker-compose up
docker-compose up -d
```
## Environment variables

2
scripts/markdown/readme/languages/russian.md

@ -193,7 +193,7 @@ git clone https://github.com/nocodb/nocodb
cd nocodb
cd docker-compose
cd mysql or pg or mssql
docker-compose up
docker-compose up -d
```
## Переменные среды

2
scripts/markdown/readme/languages/spanish.md

@ -191,7 +191,7 @@ git clone https://github.com/nocodb/nocodb
cd nocodb
cd docker-compose
cd mysql or pg or mssql
docker-compose up
docker-compose up -d
```
## Variables de entorno

Loading…
Cancel
Save