Browse Source

Merge branch 'nocodb:develop' into Enable-scroll-for-sort-&-filter-#1675

pull/1714/head
Naman Anand 3 years ago committed by GitHub
parent
commit
e35a984682
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 217
      README.md
  2. BIN
      packages/nc-gui/assets/img/discourse-icon.png
  3. 21
      packages/nc-gui/components/importantAnnouncement.vue
  4. 35
      packages/nc-gui/components/project/spreadsheet/components/editColumn/linkedToAnotherOptions.vue
  5. 56
      packages/nc-gui/components/project/spreadsheet/components/extras.vue
  6. 2
      packages/nc-gui/components/project/spreadsheet/components/virtualCell/belongsToCell.vue
  7. 27
      packages/nc-gui/components/project/spreadsheet/components/virtualCell/hasManyCell.vue
  8. 18
      packages/nc-gui/components/project/spreadsheet/components/virtualCell/manyToManyCell.vue
  9. 2
      packages/nc-gui/components/project/spreadsheet/dialog/createViewDialog.vue
  10. 4
      packages/nc-gui/components/project/spreadsheet/views/formView.vue
  11. 9
      packages/nc-gui/components/releaseInfo.vue
  12. 2
      packages/nc-gui/helpers/themes.js
  13. 1
      packages/nc-gui/lang/da.json
  14. 1
      packages/nc-gui/lang/de.json
  15. 1
      packages/nc-gui/lang/en.json
  16. 1
      packages/nc-gui/lang/es.json
  17. 1
      packages/nc-gui/lang/fa.json
  18. 1
      packages/nc-gui/lang/fi.json
  19. 1
      packages/nc-gui/lang/fr.json
  20. 1
      packages/nc-gui/lang/hr.json
  21. 1
      packages/nc-gui/lang/id.json
  22. 1
      packages/nc-gui/lang/it_IT.json
  23. 1
      packages/nc-gui/lang/iw.json
  24. 1
      packages/nc-gui/lang/ja.json
  25. 1
      packages/nc-gui/lang/ko.json
  26. 1
      packages/nc-gui/lang/lv.json
  27. 1
      packages/nc-gui/lang/nl.json
  28. 1
      packages/nc-gui/lang/no.json
  29. 1
      packages/nc-gui/lang/pl.json
  30. 1
      packages/nc-gui/lang/pt.json
  31. 1
      packages/nc-gui/lang/pt_BR.json
  32. 1
      packages/nc-gui/lang/sl.json
  33. 1
      packages/nc-gui/lang/sv.json
  34. 1
      packages/nc-gui/lang/th.json
  35. 1
      packages/nc-gui/lang/tr.json
  36. 1
      packages/nc-gui/lang/uk.json
  37. 1
      packages/nc-gui/lang/vi.json
  38. 1
      packages/nc-gui/lang/zh_CN.json
  39. 1
      packages/nc-gui/lang/zh_HK.json
  40. 1
      packages/nc-gui/lang/zh_TW.json
  41. 5
      packages/nc-gui/layouts/default.vue
  42. 2
      packages/nc-gui/nuxt.config.js
  43. 19755
      packages/nc-gui/package-lock.json
  44. 2
      packages/nc-gui/package.json
  45. 11
      packages/nc-gui/plugins/projectLoader.js
  46. 20
      packages/nc-gui/plugins/tele.js
  47. 12
      packages/nc-gui/store/app.js
  48. 12
      packages/nc-gui/store/users.js
  49. 4
      packages/nc-lib-gui/package.json
  50. 43
      packages/noco-docs-prev/content/en/setup-and-usages/usage-information.md
  51. 33
      packages/noco-docs/content/en/developer-resources/accessing-apis.md
  52. 36
      packages/noco-docs/content/en/developer-resources/api-tokens.md
  53. 9
      packages/noco-docs/content/en/developer-resources/caching.md
  54. 9
      packages/noco-docs/content/en/developer-resources/data-apis.md
  55. 9
      packages/noco-docs/content/en/developer-resources/meta-apis.md
  56. 1349
      packages/noco-docs/content/en/developer-resources/rest-apis.md
  57. 55
      packages/noco-docs/content/en/developer-resources/sdk.md
  58. 2
      packages/noco-docs/content/en/developer-resources/webhooks.md
  59. 18
      packages/noco-docs/content/en/engineering/architecture.md
  60. 31
      packages/noco-docs/content/en/engineering/repository-structure.md
  61. 35
      packages/noco-docs/content/en/getting-started/installation.md
  62. 77
      packages/noco-docs/content/en/index.md
  63. 17
      packages/noco-docs/content/en/setup-and-usages/app-store.md
  64. 2
      packages/noco-docs/content/en/setup-and-usages/column-operations.md
  65. 2
      packages/noco-docs/content/en/setup-and-usages/column-types.md
  66. 14
      packages/noco-docs/content/en/setup-and-usages/primary-value.md
  67. 4
      packages/noco-docs/content/en/setup-and-usages/share-view.md
  68. 18
      packages/noco-docs/content/en/setup-and-usages/table-operations.md
  69. 2
      packages/noco-docs/content/en/setup-and-usages/team-and-auth.md
  70. 56
      packages/noco-docs/content/en/setup-and-usages/usage-information.md
  71. 93
      packages/noco-docs/content/en/setup-and-usages/views.md
  72. 10532
      packages/nocodb-sdk/package-lock.json
  73. 2
      packages/nocodb-sdk/package.json
  74. 62
      packages/nocodb-sdk/src/lib/Api.ts
  75. 25264
      packages/nocodb/package-lock.json
  76. 10
      packages/nocodb/package.json
  77. 4
      packages/nocodb/src/lib/noco-models/Column.ts
  78. 3
      packages/nocodb/src/lib/noco-models/LinkToAnotherRecordColumn.ts
  79. 2
      packages/nocodb/src/lib/noco/meta/api/auditApis.ts
  80. 70
      packages/nocodb/src/lib/noco/meta/api/columnApis.ts
  81. 4
      packages/nocodb/src/lib/noco/meta/api/dataApis/dataAliasNestedApis.ts
  82. 15
      packages/nocodb/src/lib/noco/meta/api/index.ts
  83. 14
      packages/nocodb/src/lib/noco/meta/api/metaDiffApis.ts
  84. 11
      packages/nocodb/src/lib/noco/meta/api/utilApis.ts
  85. 81
      packages/nocodb/src/lib/noco/upgrader/jobs/ncProjectUpgraderV2_0090000.ts
  86. 13
      packages/nocodb/src/lib/utils/projectAcl.ts
  87. 2
      scripts/bumpNocodbSdkVersion.js
  88. 231
      scripts/sdk/swagger.json

217
README.md

@ -21,6 +21,7 @@ Turns any MySQL, PostgreSQL, SQL Server, SQLite & MariaDB into a smart-spreadshe
<p align="center">
<a href="http://www.nocodb.com"><b>Website</b></a>
<a href="https://discord.gg/5RgZmkW"><b>Discord</b></a>
<a href="https://community.nocodb.com/"><b>Community</b></a>
<a href="https://twitter.com/nocodb"><b>Twitter</b></a>
<a href="https://www.reddit.com/r/NocoDB/"><b>Reddit</b></a>
<a href="https://docs.nocodb.com/"><b>Documentation</b></a>
@ -51,9 +52,11 @@ Turns any MySQL, PostgreSQL, SQL Server, SQLite & MariaDB into a smart-spreadshe
<img src="https://static.scarf.sh/a.png?x-pxid=c12a77cc-855e-4602-8a0f-614b2d0da56a" />
# Quick try
### 1-Click Deploy
#### Heroku
## 1-Click Deploy to Heroku
Before doing so, make sure you have a Heroku account. By default, an add-on Heroku Postgres will be used as meta database. You can see the connection string defined in `DATABASE_URL` by navigating to Heroku App Settings and selecting Config Vars.
<a href="https://heroku.com/deploy?template=https://github.com/nocodb/nocodb-seed-heroku">
<img
src="https://www.herokucdn.com/deploy/button.svg"
@ -61,43 +64,100 @@ Turns any MySQL, PostgreSQL, SQL Server, SQLite & MariaDB into a smart-spreadshe
alt="Deploy NocoDB to Heroku with 1-Click"
/>
</a>
<br>
### Using Docker
```bash
docker run -d --name nocodb -p 8080:8080 nocodb/nocodb:latest
```
<br/>
- NocoDB needs a database as input : See [Production Setup](https://github.com/nocodb/nocodb/blob/master/README.md#production-setup).
- If this input is absent, we fallback to SQLite. In order too persist sqlite, you can mount `/usr/app/data/`.
## NPX
Example:
You can run below command if you need an interactive configuration.
```
docker run -d -p 8080:8080 --name nocodb -v /local/path:/usr/app/data/ nocodb/nocodb:latest
```
### Using Npm
```
npx create-nocodb-app
```
### Using Git
```
<img src="https://user-images.githubusercontent.com/35857179/163672964-00ef5d62-0434-447d-ac01-3ebb780099b9.png" width="520px"/>
## Node Application
We provide a simple NodeJS Application for getting started.
```bash
git clone https://github.com/nocodb/nocodb-seed
cd nocodb-seed
npm install
npm start
```
### GUI
## Docker
```bash
# for SQLite
docker run -d --name nocodb \
-v /local/path:/usr/app/data/ \
-p 8080:8080 \
nocodb/nocodb:latest
# for MySQL
docker run -d --name nocodb-mysql \
-v /local/path:/usr/app/data/ \
-p 8080:8080 \
-e NC_DB="mysql2://host.docker.internal:3306?u=root&p=password&d=d1" \
-e NC_AUTH_JWT_SECRET="569a1821-0a93-45e8-87ab-eb857f20a010" \
nocodb/nocodb:latest
# for PostgreSQL
docker run -d --name nocodb-postgres \
-v /local/path:/usr/app/data/ \
-p 8080:8080 \
-e NC_DB="pg://host.docker.internal:5432?u=root&p=password&d=d1" \
-e NC_AUTH_JWT_SECRET="569a1821-0a93-45e8-87ab-eb857f20a010" \
nocodb/nocodb:latest
# for MSSQL
docker run -d --name nocodb-mssql \
-v /local/path:/usr/app/data/ \
-p 8080:8080 \
-e NC_DB="mssql://host.docker.internal:1433?u=root&p=password&d=d1" \
-e NC_AUTH_JWT_SECRET="569a1821-0a93-45e8-87ab-eb857f20a010" \
nocodb/nocodb:latest
```
> To persist data in docker you can mount volume at `/usr/app/data/` since 0.10.6. Otherwise your data will be lost after recreating the container.
> If you plan to input some special characters, you may need to change the character set and collation yourself when creating the database. Please check out the examples for [MySQL Docker](https://github.com/nocodb/nocodb/issues/1340#issuecomment-1049481043).
## Docker Compose
We provide different docker-compose.yml files under [this directory](https://github.com/nocodb/nocodb/tree/master/docker-compose). Here are some examples.
```bash
git clone https://github.com/nocodb/nocodb
# for MySQL
cd nocodb/docker-compose/mysql
# for PostgreSQL
cd nocodb/docker-compose/pg
# for MSSQL
cd nocodb/docker-compose/mssql
docker-compose up -d
```
> To persist data in docker, you can mount volume at `/usr/app/data/` since 0.10.6. Otherwise your data will be lost after recreating the container.
> If you plan to input some special characters, you may need to change the character set and collation yourself when creating the database. Please check out the examples for [MySQL Docker Compose](https://github.com/nocodb/nocodb/issues/1313#issuecomment-1046625974).
# GUI
Access Dashboard using : [http://localhost:8080/dashboard](http://localhost:8080/dashboard)
# Join Our Community
<a href="https://discord.gg/5RgZmkW">
<a href="https://discord.gg/5RgZmkW" target="_blank">
<img src="https://discordapp.com/api/guilds/661905455894888490/widget.png?style=banner3" alt="">
</a>
<a href="https://community.nocodb.com/" target="_blank">
<img src="https://i2.wp.com/www.feverbee.com/wp-content/uploads/2018/07/logo-discourse.png" alt="">
</a>
# Screenshots
@ -128,7 +188,8 @@ Access Dashboard using : [http://localhost:8080/dashboard](http://localhost:8080
![10](https://user-images.githubusercontent.com/5435402/133759250-ebd75ecf-31db-4a17-b2d7-2c43af78a54e.png)
<br>
![8](https://user-images.githubusercontent.com/5435402/133759248-3a7141e0-4b7d-4079-a5f9-cf8611d00bc5.png)
![8](https://user-images.githubusercontent.com/35857179/163675704-54eb644d-3b5e-45e3-aad4-794a0f55c692.png)
<br>
![9](https://user-images.githubusercontent.com/5435402/133759249-8c1a85c2-a55c-48f6-bd58-aa6b4195cce7.png)
@ -136,27 +197,25 @@ Access Dashboard using : [http://localhost:8080/dashboard](http://localhost:8080
# Table of Contents
- [Quick try](#quick-try)
+ [1-Click Deploy](#1-click-deploy)
- [Heroku](#heroku)
+ [Using Docker](#using-docker)
+ [Using Npm](#using-npm)
+ [Using Git](#using-git)
+ [GUI](#gui)
* [1-Click Deploy to Heroku](#1-click-deploy-to-heroku)
* [NPX](#npx)
* [Node Application](#node-application)
* [Docker](#docker)
* [Docker Compose](#docker-compose)
- [GUI](#gui)
- [Join Our Community](#join-our-community)
- [Screenshots](#screenshots)
- [Table of Contents](#table-of-contents)
- [Features](#features)
+ [Rich Spreadsheet Interface](#rich-spreadsheet-interface)
+ [App Store for workflow automations](#app-store-for-workflow-automations)
+ [Programmatic API access via](#programmatic-api-access-via)
+ [App Store for Workflow Automations](#app-store-for-workflow-automations)
+ [Programmatic Access](#programmatic-access)
+ [Sync Schema](#sync-schema)
+ [Audit](#audit)
- [Production Setup](#production-setup)
* [Docker](#docker)
- [Example: MySQL](#example--mysql)
- [Example: PostgreSQL](#example--postgresql)
- [Example: SQL Server](#example--sql-server)
* [Docker Compose](#docker-compose)
* [Environment variables](#environment-variables)
- [Development Setup](#development-setup)
* [Cloning the project](#clone-the-project)
* [Cloning the Project](#cloning-the-project)
* [Running Backend locally](#running-backend-locally)
* [Running Frontend locally](#running-frontend-locally)
* [Running Cypress tests locally](#running-cypress-tests-locally)
@ -166,66 +225,44 @@ Access Dashboard using : [http://localhost:8080/dashboard](http://localhost:8080
- [Contributors](#contributors)
# Features
### Rich Spreadsheet Interface
- ⚡ &nbsp;Search, sort, filter, hide columns with uber ease
- ⚡ &nbsp;Create Views : Grid, Gallery, Kanban, Form
- ⚡ &nbsp;Share Views : public & password protected
- ⚡ &nbsp;Personal & locked Views
- ⚡ &nbsp;Upload images to cells (Works with S3, Minio, GCP, Azure, DigitalOcean, Linode, OVH, BackBlaze)
- ⚡ &nbsp;Roles : Owner, Creator, Editor, Viewer, Commenter, Custom Roles.
- ⚡ &nbsp;Access Control : Fine-grained access control even at database, table & column level.
### App Store for workflow automations
- ⚡ &nbsp;Chat : Microsoft Teams, Slack, Discord, Mattermost
- ⚡ &nbsp;Email : SMTP, SES, Mailchimp
- ⚡ &nbsp;SMS : Twilio
- ⚡ &nbsp;Whatsapp
- ⚡ &nbsp;Any 3rd Party APIs
### Programmatic API access via
- ⚡ &nbsp;REST APIs (Swagger)
- ⚡ &nbsp;GraphQL APIs.
- ⚡ &nbsp;Includes JWT Authentication & Social Auth
- ⚡ &nbsp;API tokens to integrate with Zapier, Integromat.
# Production Setup
NocoDB requires a database to store metadata of spreadsheets views and external databases.
And connection params for this database can be specified in `NC_DB` environment variable.
- ⚡ &nbsp;Basic Operations: Create, Read, Update and Delete on Tables, Columns, and Rows
- ⚡ &nbsp;Fields Operations: Sort, Filter, Hide / Unhide Columns
- ⚡ &nbsp;Multiple Views Types: Grid (By default), Gallery and Form View
- ⚡ &nbsp;View Permissions Types: Collaborative Views, & Locked Views
- ⚡ &nbsp;Share Bases / Views: either Public or Private (with Password Protected)
- ⚡ &nbsp;Variant Cell Types: ID, LinkToAnotherRecord, Lookup, Rollup, SingleLineText, Attachement, Currency, Formula and etc
- ⚡ &nbsp;Access Control with Roles : Fine-grained Access Control at different levels
- ⚡ &nbsp;and more ...
## Docker
### App Store for Workflow Automations
#### Example: MySQL
```
docker run -d -p 8080:8080 \
-e NC_DB="mysql2://host.docker.internal:3306?u=root&p=password&d=d1" \
-e NC_AUTH_JWT_SECRET="569a1821-0a93-45e8-87ab-eb857f20a010" \
nocodb/nocodb:latest
```
We provide different integrations in three main categories. See <a href="https://docs.nocodb.com/setup-and-usages/app-store" target="_blank">App Store</a> for details.
#### Example: PostgreSQL
```
docker run -d -p 8080:8080 \
-e NC_DB="pg://host:port?u=user&p=password&d=database" \
-e NC_AUTH_JWT_SECRET="569a1821-0a93-45e8-87ab-eb857f20a010" \
nocodb/nocodb:latest
```
- ⚡ &nbsp;Chat : Slack, Discord, Mattermost, and etc
- ⚡ &nbsp;Email : AWS SES, SMTP, MailerSend, and etc
- ⚡ &nbsp;Storage : AWS S3, Google Cloud Storage, Minio, and etc
#### Example: SQL Server
```
docker run -d -p 8080:8080 \
-e NC_DB="mssql://host:port?u=user&p=password&d=database" \
-e NC_AUTH_JWT_SECRET="569a1821-0a93-45e8-87ab-eb857f20a010" \
nocodb/nocodb:latest
```
### Programmatic Access
## Docker Compose
```
git clone https://github.com/nocodb/nocodb
cd nocodb
cd docker-compose
cd mysql or pg or mssql
docker-compose up -d
```
We provide the following ways to let users to invoke actions in a programmatic way. You can use a token (either JWT or Social Auth) to sign your requests for authorization to NocoDB.
- ⚡ &nbsp;REST APIs
- ⚡ &nbsp;NocoDB SDK
### Sync Schema
We allow you to sync schema changes if you have made changes outside NocoDB GUI. However, it has to be noted then you will have to bring your own schema migrations for moving from environment to others. See <a href="https://docs.nocodb.com/setup-and-usages/sync-schema/" target="_blank">Sync Schema</a> for details.
### Audit
We are keeping all the user operation logs under one place. See <a href="https://docs.nocodb.com/setup-and-usages/audit" target="_blank">Audit</a> for details.
# Production Setup
By default, SQLite is used for storing meta data. However, you can specify your own database. The connection params for this database can be specified in `NC_DB` environment variable. Moreover, we also provide the below environment variables for configuration.
## Environment variables
@ -262,7 +299,6 @@ Changes made to code automatically restart.
> nocodb/packages/nocodb includes nc-lib-gui which is the built version of nc-gui hosted in npm registry. You can visit localhost:8000/dashboard in browser after starting the backend locally if you just want to modify the backend only.
## Running Cypress tests locally
```shell
@ -411,8 +447,3 @@ Our mission is to provide the most powerful no-code interface for databases whic
<!-- prettier-ignore-end -->
<!-- ALL-CONTRIBUTORS-LIST:END -->

BIN
packages/nc-gui/assets/img/discourse-icon.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

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

@ -3,7 +3,7 @@
<template #activator="{on}">
<transition name="announcement">
<v-btn
v-if="!loading"
v-show="announcementAlert"
text
small
class="mb-0 mr-2 py-0 "
@ -29,14 +29,21 @@
mdi-script-text-outline
</v-icon>
<span class="caption">
API Changes in v0.90.0
v0.90.0 API Changes
</span>
</v-list-item>
<v-list-item dense href="https://github.com/nocodb/nocodb/releases/tag/0.90.0" target="_blank">
<v-icon small class="mr-2">
mdi-script-text-outline
</v-icon>
<span class="caption">
v0.90.0 Release Note
</span>
</v-list-item>
<v-list-item @click="announcementAlert = false">
<v-icon small class="mr-2">
mdi-close
</v-icon>
<span class="caption">
<!--Hide menu-->
{{ $t('general.hideMenu') }}
@ -53,6 +60,14 @@ export default {
loading: true
}),
computed: {
announcementAlert: {
get() {
return !this.loading && !this.$store.state.app.hiddenAnnouncement
},
set(val) {
return this.$store.commit('app/MutHiddenAnnouncement', val ? null : true)
}
},
},
mounted() {
setTimeout(() => {

35
packages/nc-gui/components/project/spreadsheet/components/editColumn/linkedToAnotherOptions.vue

@ -52,8 +52,7 @@
</v-container>
<v-container v-show="advanceOptions" fluid class="wrapper">
<v-row>
</v-row>
<v-row />
<template v-if="!isSQLite">
<v-row>
<v-col cols="6">
@ -67,7 +66,7 @@
:items="onUpdateDeleteOptions"
required
dense
:disabled="relation.type !== 'real'"
:disabled="relation.virtual"
/>
</v-col>
<v-col cols="6">
@ -81,25 +80,23 @@
:items="onUpdateDeleteOptions"
required
dense
:disabled="relation.type !== 'real'"
/>
</v-col>
</v-row>
<v-row>
<v-col>
<v-checkbox
v-model="relation.type"
false-value="real"
true-value="virtual"
label="Virtual Relation"
:full-width="false"
required
class="mt-0"
dense
:disabled="relation.virtual"
/>
</v-col>
</v-row>
</template>
<v-row>
<v-col>
<v-checkbox
v-model="relation.virtual"
label="Virtual Relation"
:full-width="false"
required
class="mt-0"
dense
/>
</v-col>
</v-row>
</v-container>
</div>
</template>
@ -148,7 +145,7 @@ export default {
onDelete: 'NO ACTION',
onUpdate: 'NO ACTION',
updateRelation: !!this.column.rtn,
relationType: 'real'
virtual: this.isSQLite
}
},
methods: {

56
packages/nc-gui/components/project/spreadsheet/components/extras.vue

@ -30,7 +30,7 @@
dense
>
<v-list-item dense href="https://discord.gg/5RgZmkW" target="_blank">
<!-- Get your questions answered -->
<!-- Join Discord -->
<v-list-item-title>
<v-icon class="mr-1" small :color="textColors[0]">
mdi-discord
@ -40,7 +40,33 @@
}}</span>
</v-list-item-title>
</v-list-item>
<!-- Join Community -->
<v-list-item dense href="https://community.nocodb.com/" target="_blank">
<v-list-item-title>
<v-icon class="mr-1 discourse" small :color="textColors[0]">
mdi-discourse
</v-icon>
<span class="caption" :title="$t('labels.community.joinCommunity')" v-t="['community:discourse']">{{
$t('labels.community.joinCommunity')
}}</span>
</v-list-item-title>
</v-list-item>
<v-list-item dense href="https://twitter.com/NocoDB" target="_blank">
<!-- Join Reddit -->
<v-list-item-title>
<v-icon class="mr-1" small color="#ff4600">
mdi-reddit
</v-icon>
<span class="caption" :title="$t('labels.community.joinReddit')" v-t="['community:reddit']">{{
$t('labels.community.joinReddit')
}}</span>
</v-list-item-title>
</v-list-item>
<v-list-item
dense
target="_blank"
href="https://calendly.com/nocodb-meeting"
>
<!-- Follow NocoDB -->
<v-list-item-title>
<v-icon class="mr-1" small :color="textColors[1]">
@ -52,21 +78,6 @@
</v-list-item-title>
</v-list-item>
<v-list-item dense href="https://www.reddit.com/r/NocoDB/" target="_blank">
<!-- Get your questions answered -->
<v-list-item-title>
<v-icon class="mr-1" small color="#ff4600">
mdi-reddit
</v-icon>
<span class="caption" :title="$t('labels.community.joinReddit')" v-t="['community:reddit']">{{
$t('labels.community.joinReddit')
}}</span>
</v-list-item-title>
</v-list-item>
<v-list-item
dense
target="_blank"
href="https://calendly.com/nocodb-meeting"
>
<!-- Book a Free DEMO -->
<v-list-item-title>
<v-icon class="mr-1" small :color="textColors[3]">
@ -126,6 +137,19 @@ export default {
}
}
.v-icon.discourse {
height: 16px;
width: 16px;
background-image: url('~/assets/img/discourse-icon.png');
background-size: contain;
background-repeat: no-repeat;
}
.v-icon.discourse::before {
visibility: hidden;
content: "";
}
//
//@keyframes anim {
// 0%, 100% {

2
packages/nc-gui/components/project/spreadsheet/components/virtualCell/belongsToCell.vue

@ -281,7 +281,7 @@ export default {
const id = this.meta.columns.filter(c => c.pk).map(c => this.row[c.title]).join('___')
// todo: audit
await this.$api.dbTableRow.nestedDelete(
await this.$api.dbTableRow.nestedRemove(
'noco',
this.projectName,
this.meta.title,

27
packages/nc-gui/components/project/spreadsheet/components/virtualCell/hasManyCell.vue

@ -342,11 +342,13 @@ export default {
return
}
const id = this.childMeta.columns.filter(c => c.pk).map(c => child[c.title]).join('___')
await this.$api.data.nestedDelete(
this.meta.id,
await this.$api.dbTableRow.nestedRemove(
'noco',
this.projectName,
this.meta.title,
this.parentId,
this.column.id,
'hm',
RelationTypes.HAS_MANY,
this.column.title,
id
)
@ -440,15 +442,18 @@ export default {
// eslint-disable-next-line no-cond-assign
while (child = this.localState.pop()) {
if (row) {
// todo: use common method
const pid = this.meta.columns.filter(c => c.pk).map(c => row[c.title]).join('___')
const id = this.childMeta.columns.filter(c => c.pk).map(c => child[c.title]).join('___')
const title = this.childForeignKey
await this.childApi.update(id, {
[title]: parseIfInteger(pid)
}, {
[title]: child[this.childForeignKey]
})
await this.$api.dbTableRow.nestedAdd(
'noco',
this.projectName,
this.meta.title,
pid,
'hm',
this.column.title,
id
)
} else {
await this.addChildToParent(child)
}

18
packages/nc-gui/components/project/spreadsheet/components/virtualCell/manyToManyCell.vue

@ -318,7 +318,7 @@ export default {
const cid = this.childMeta.columns.filter(c => c.pk).map(c => child[c.title]).join('___')
const pid = this.meta.columns.filter(c => c.pk).map(c => this.row[c.title]).join('___')
await this.$api.dbTableRow.nestedDelete(
await this.$api.dbTableRow.nestedRemove(
'noco',
this.projectName,
this.meta.title,
@ -461,16 +461,18 @@ export default {
// eslint-disable-next-line no-cond-assign
while (child = this.localState.pop()) {
if (row) {
// todo: use common method
const cid = this.childMeta.columns.filter(c => c.pk).map(c => child[c.title]).join('___')
const pid = this.meta.columns.filter(c => c.pk).map(c => row[c.title]).join('___')
const vcidCol = this.assocMeta.columns.find(c => c.id === this.column.colOptions.fk_mm_parent_column_id).title
const vpidCol = this.assocMeta.columns.find(c => c.id === this.column.colOptions.fk_mm_child_column_id).title
await this.assocApi.insert({
[vcidCol]: parseIfInteger(cid),
[vpidCol]: parseIfInteger(pid)
})
await this.$api.dbTableRow.nestedAdd(
'noco',
this.projectName,
this.meta.title,
pid,
'mm',
this.column.title,
cid
)
} else {
await this.addChildToParent(child)
}

2
packages/nc-gui/components/project/spreadsheet/dialog/createViewDialog.vue

@ -4,7 +4,7 @@
<v-card-title class="grey darken-2 subheading" style="height:30px" />
<v-card-text class="pt-4 pl-4">
<p class="headline">
{{ $t('general.create') }} <span class="text-capitalize">{{ show_as }}</span> {{ $t('objects.view') }}
{{ $t('general.create') }} <span class="text-capitalize">{{ typeAlias }}</span> {{ $t('objects.view') }}
</p>
<v-form ref="form" v-model="valid" @submit.prevent="createView">
<!-- label="View Name" -->

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

@ -688,6 +688,10 @@ export default {
}
},
async updateView() {
if (this.view.subheading?.length > 255) {
this.$toast.error('Data too long for Form Description').goAway(3000)
return
}
await this.$api.dbView.formUpdate(this.viewId, this.view)
},
async loadView() {

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

@ -3,7 +3,7 @@
<template #activator="{on}">
<transition name="release">
<v-btn
v-if="releaseAlert"
v-show="releaseAlert"
text
small
class="mb-0 mr-2 py-0 "
@ -54,10 +54,13 @@ export default {
computed: {
releaseAlert: {
get() {
return !this.loading && this.$store.state.app.releaseVersion && this.$store.state.app.releaseVersion !== this.$store.state.app.hiddenRelease
return !this.loading && this.$store.state.app.releaseVersion &&
this.$store.state.app.latestRelease &&
this.$store.state.app.releaseVersion !== this.$store.state.app.latestRelease &&
this.$store.state.app.latestRelease !== this.$store.state.app.hiddenRelease
},
set(val) {
return this.$store.commit('app/MutHiddenRelease', val ? null : this.$store.state.app.releaseVersion)
return this.$store.commit('app/MutHiddenRelease', val ? null : this.$store.state.app.latestRelease)
}
},
releaseVersion() {

2
packages/nc-gui/helpers/themes.js

@ -11,7 +11,7 @@ export default {
Default: {
// "primary": "#0989ff",
// "primary": "#1082da",
primary: '#1972e6',
primary: '#1348ba',
secondary: '#9575CD',
accent: '#FF4081',
info: '#2196F3',

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

@ -225,6 +225,7 @@
"bookDemo": "Book en gratis demo",
"getAnswered": "Få dine spørgsmål besvaret",
"joinDiscord": "Deltag Diskord",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "Deltag /r/NocoDB",
"followNocodb": "Følg NocoDB"
},

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

@ -225,6 +225,7 @@
"bookDemo": "Eine kostenlose Demo buchen",
"getAnswered": "Erhalten Sie Antworten auf Ihre Fragen",
"joinDiscord": "Discord beitreten",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "/r/NocoDB beitreten",
"followNocodb": "Folgen Sie NocoDB"
},

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

@ -225,6 +225,7 @@
"bookDemo": "Book a Free DEMO",
"getAnswered": "Get your questions answered",
"joinDiscord": "Join Discord",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "Join /r/NocoDB",
"followNocodb": "Follow NocoDB"
},

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

@ -225,6 +225,7 @@
"bookDemo": "Agendar una demostración gratuita",
"getAnswered": "Obtén respuestas a tus preguntas",
"joinDiscord": "Únete a Discord",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "Únete /r/NocoDB",
"followNocodb": "Seguir a NocoDB"
},

1
packages/nc-gui/lang/fa.json

@ -225,6 +225,7 @@
"bookDemo": "رزرو دموی رایگان",
"getAnswered": "پاسخ سوالات خود را دریافت کنید",
"joinDiscord": "به Discord بپیوندید",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "به NocoDB بپیوندید",
"followNocodb": "NocoDB را دنبال کنید"
},

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

@ -225,6 +225,7 @@
"bookDemo": "Varaa ilmainen demo",
"getAnswered": "Hanki kysymyksesi vastasi",
"joinDiscord": "Liity discordiin",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "Liity /r/NocoDB",
"followNocodb": "Seuraa NocoDB"
},

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

@ -225,6 +225,7 @@
"bookDemo": "Planifier une démonstration gratuite",
"getAnswered": "Obtenir des réponses à vos questions",
"joinDiscord": "Rejoindre le serveur Discord",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "Rejoindre /r/NocoDB",
"followNocodb": "Suivre NocoDB"
},

1
packages/nc-gui/lang/hr.json

@ -225,6 +225,7 @@
"bookDemo": "Rezervirajte besplatni demo",
"getAnswered": "Odgovorite na vaša pitanja",
"joinDiscord": "Pridružite se nesloga",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "Pridružite se /r/NocoDB",
"followNocodb": "Slijedite NocoDB"
},

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

@ -225,6 +225,7 @@
"bookDemo": "Pesan demo gratis",
"getAnswered": "Dapatkan pertanyaan Anda dijawab",
"joinDiscord": "Bergabunglah dengan Perselisihan",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "Bergabunglah /r/NocoDB",
"followNocodb": "Ikuti NocoDB"
},

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

@ -225,6 +225,7 @@
"bookDemo": "Prenota una demo gratuita",
"getAnswered": "Ottieni risposte alle tue domande",
"joinDiscord": "Unisciti su Discord",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "Iscriviti /r/NocoDB",
"followNocodb": "Segui NocoDB"
},

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

@ -225,6 +225,7 @@
"bookDemo": "להזמין הדגמה חינם",
"getAnswered": "קבל את השאלות שלך ענה",
"joinDiscord": "הצטרף לדיסק",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "הצטרף /r/NocoDB",
"followNocodb": "בצע NocoDB"
},

1
packages/nc-gui/lang/ja.json

@ -225,6 +225,7 @@
"bookDemo": "無料のデモを予約する",
"getAnswered": "あなたの質問に回答しましょう",
"joinDiscord": "Discordに参加する",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "/r/NocoDBに参加する",
"followNocodb": "NocoDBをフォローする"
},

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

@ -225,6 +225,7 @@
"bookDemo": "무료 데모를 예약하십시오",
"getAnswered": "귀하의 질문에 답변 해주십시오",
"joinDiscord": "디스코드 참가",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "가입 /r/NocoDB",
"followNocodb": "NocoDB를 팔로우 하세요"
},

1
packages/nc-gui/lang/lv.json

@ -225,6 +225,7 @@
"bookDemo": "Rezervē bezmaksas DEMO",
"getAnswered": "Saņemt atbildi uz jautājumiem",
"joinDiscord": "Pievienoties Discord",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "Pievienoties /r/NocoDB",
"followNocodb": "Sekot NocoDB"
},

1
packages/nc-gui/lang/nl.json

@ -225,6 +225,7 @@
"bookDemo": "Boek een gratis demonstratie",
"getAnswered": "Krijg je vragen beantwoord",
"joinDiscord": "Join Discord",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "Join /r/NocoDB",
"followNocodb": "Volg NocoDB"
},

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

@ -225,6 +225,7 @@
"bookDemo": "Bestill en gratis demo",
"getAnswered": "Få dine spørsmål besvart",
"joinDiscord": "Bli med på Discord",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "Bli med /r/NocoDB",
"followNocodb": "Følg NocoDB"
},

1
packages/nc-gui/lang/pl.json

@ -225,6 +225,7 @@
"bookDemo": "Zarezerwuj darmowe demo",
"getAnswered": "Odpowiedzi na pytania",
"joinDiscord": "Dołącz do Discord.",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "Dołącz /r/NocoDB",
"followNocodb": "Śledź NocoDB"
},

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

@ -225,6 +225,7 @@
"bookDemo": "Marque uma DEMONSTRAÇÃO gratuita",
"getAnswered": "Obtenha resposta às suas questões",
"joinDiscord": "Junte-se ao Discord",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "Junte-se /r/NocoDB",
"followNocodb": "Siga NocoDB"
},

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

@ -225,6 +225,7 @@
"bookDemo": "Marque uma DEMONSTRAÇÃO gratuita",
"getAnswered": "Obtenha resposta às suas perguntas",
"joinDiscord": "Junte-se ao Discord",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "Junte-se /r/NocoDB",
"followNocodb": "Siga NocoDB"
},

1
packages/nc-gui/lang/sl.json

@ -225,6 +225,7 @@
"bookDemo": "Rezervirajte brezplačno demo",
"getAnswered": "Odgovorili na vaša vprašanja",
"joinDiscord": "Pridružite se nam na Discord-u",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "Pridružite se /r/NocoDB",
"followNocodb": "Sledite NocoDB"
},

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

@ -225,6 +225,7 @@
"bookDemo": "Boka en gratis demo",
"getAnswered": "Få dina frågor besvarade",
"joinDiscord": "Gå med i Discord",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "Gå med /r/NocoDB",
"followNocodb": "Följ NocoDB"
},

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

@ -225,6 +225,7 @@
"bookDemo": "จองการสาธตฟร",
"getAnswered": "รบคำถามของคณตอบ",
"joinDiscord": "เขารวมกบความไมลงรอยกน",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "เขารวม /r/NocoDB",
"followNocodb": "ตดตาม NocoDB"
},

1
packages/nc-gui/lang/tr.json

@ -225,6 +225,7 @@
"bookDemo": "Ücretsiz bir demo rezervasyonu yapın",
"getAnswered": "Sorularınıza cevap bulun",
"joinDiscord": "Discord'a katıl",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "/r/NocoDB'ye katıl",
"followNocodb": "NocoDB'yi takip et"
},

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

@ -225,6 +225,7 @@
"bookDemo": "Забронюйте безкоштовну демонстрацію",
"getAnswered": "Отримайте відповіді на запитання",
"joinDiscord": "Приєднуватися",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "Приєднатися /r/NocoDB",
"followNocodb": "Слідувати NocoDB"
},

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

@ -225,6 +225,7 @@
"bookDemo": "Đặt một bản demo miễn phí",
"getAnswered": "Nhận câu hỏi của bạn được trả lời",
"joinDiscord": "Tham gia thông minh",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "Tham gia /r/NocoDB",
"followNocodb": "Theo dõi NocoDB"
},

1
packages/nc-gui/lang/zh_CN.json

@ -225,6 +225,7 @@
"bookDemo": "查看免费演示",
"getAnswered": "通过这里让你的问题得到解答",
"joinDiscord": "加入 Discord",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "加入/r/NocoDB",
"followNocodb": "关注 NocoDB"
},

1
packages/nc-gui/lang/zh_HK.json

@ -225,6 +225,7 @@
"bookDemo": "Book個 free demo",
"getAnswered": "讓您的問題得到解答",
"joinDiscord": "加入 Discord",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "加入 /r/NocoDB",
"followNocodb": "Fol下NocoDB"
},

1
packages/nc-gui/lang/zh_TW.json

@ -225,6 +225,7 @@
"bookDemo": "預訂免費 Demo",
"getAnswered": "解惑您的問題",
"joinDiscord": "加入 Discord",
"joinCommunity": "Join NocoDB Community",
"joinReddit": "加入 /r/NocoDB",
"followNocodb": "追蹤 NocoDB"
},

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

@ -52,6 +52,7 @@
<div style="flex: 1" class="d-flex justify-end">
<v-toolbar-items class="hidden-sm-and-down nc-topright-menu">
<important-announcement />
<release-info />
<language class="mr-3" />
@ -282,6 +283,7 @@ import Language from '~/components/utils/language'
import Loader from '~/components/loader'
import PreviewAs from '~/components/previewAs'
import ShareOrInviteModal from '~/components/auth/shareOrInviteModal'
import ImportantAnnouncement from '../components/importantAnnouncement.vue'
export default {
components: {
@ -293,7 +295,8 @@ export default {
XBtn,
Snackbar,
dlgUnexpectedError,
settings
settings,
ImportantAnnouncement
},
data: () => ({
clickCount: true,

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

@ -215,7 +215,7 @@ export default {
packageJson.version = `${packageJson.version}-${process.env.targetVersion}`
packageJson.name += '-daily'
} else {
packageJson.version = version
packageJson.version = process.env.targetVersion
}
fs.writeFileSync('../nc-lib-gui/package.json', JSON.stringify(packageJson, 0, 2))

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

File diff suppressed because it is too large Load Diff

2
packages/nc-gui/package.json

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

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

@ -1,4 +1,4 @@
export default async({ store, redirect, $axios, $toast, route }) => {
export default async({ store, redirect, $axios, $toast, $api, route }) => {
// if (!route.path || !route.path.startsWith('/nc/')) { await store.dispatch('plugins/pluginPostInstall', 'Branding') }
if (window.location.search &&
/\bscope=|\bstate=/.test(window.location.search) &&
@ -63,11 +63,14 @@ export default async({ store, redirect, $axios, $toast, route }) => {
// fetch latest release info
const fetchReleaseInfo = async() => {
try {
const releaseInfo = await store.dispatch('sqlMgr/ActSqlOp', [null, 'xcRelease'])
if (releaseInfo && releaseInfo.docker && releaseInfo.docker.upgrade) {
store.commit('app/MutReleaseVersion', releaseInfo.docker.name)
const releaseInfo = await $api.utils.appInfo()
const latestRelease = await $api.utils.appVersion()
if (releaseInfo && latestRelease && releaseInfo.version) {
store.commit('app/MutReleaseVersion', releaseInfo.version)
store.commit('app/MutLatestRelease', latestRelease.releaseVersion || null)
} else {
store.commit('app/MutReleaseVersion', null)
store.commit('app/MutLatestRelease', null)
}
} catch (e) {
// ignore

20
packages/nc-gui/plugins/tele.js

@ -23,7 +23,8 @@ export default function({
socket.disconnect()
socket = null
})
} catch { }
} catch {
}
}
app.router.onReady(() => {
@ -32,13 +33,11 @@ export default function({
return
}
socket.emit('page', {
id: store.state.users.user && store.state.users.user.id,
path: to.matched[0].path + (to.query && to.query.type ? `?type=${to.query.type}` : '')
})
})
if (socket) {
socket.emit('page', {
id: store.state.users.user && store.state.users.user.id,
path: route.matched[0].path + (route.query && route.query.type ? `?type=${route.query.type}` : '')
})
}
@ -49,9 +48,8 @@ export default function({
if (socket) {
socket.emit('event', {
event: evt,
id: store.state.users.user && store.state.users.user.id,
...(data || {}),
$current_url: gatPath(app)
path: gatPath(app)
})
}
}
@ -61,14 +59,14 @@ export default function({
function getListener(binding) {
return function(e) {
if (!socket) { return }
const cat = window.location.hash.replace(/\d+\/(?=dashboard)/, '')
if (!socket) {
return
}
const event = binding.value && binding.value[0]
const data = binding.value && binding.value[1]
const extra = binding.value && binding.value.slice(2)
tele.emit(event,
{
cat,
data,
extra
})
@ -87,14 +85,16 @@ export default function({
store.watch(state => state.project.projectInfo && state.project.projectInfo.teleEnabled && state.users.token, (token) => {
if (token) {
init(token).then(() => {})
init(token).then(() => {
})
} else if (socket) {
socket.disconnect()
socket = null
}
})
if (store.state.project.projectInfo && store.state.project.projectInfo.teleEnabled && store.state.users.token) {
init(store.state.users.token).then(() => {})
init(store.state.users.token).then(() => {
})
}
}

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

@ -1,6 +1,8 @@
export const state = () => ({
releaseVersion: null,
hiddenRelease: null
hiddenRelease: null,
latestRelease: null,
hiddenAnnouncement: null,
})
export const mutations = {
@ -9,7 +11,13 @@ export const mutations = {
},
MutHiddenRelease(state, hiddenRelease) {
state.hiddenRelease = hiddenRelease
}
},
MutLatestRelease(state, latestRelease) {
state.latestRelease = latestRelease
},
MutHiddenAnnouncement(state, hiddenAnnouncement) {
state.hiddenAnnouncement = hiddenAnnouncement
},
}
/**

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

@ -153,7 +153,7 @@ export const actions = {
setInterval(async() => {
if (getters.GtrUser) {
try {
const res = await this.$api.auth.me() // this.$axios.get('/user/me')
const res = await this.$api.auth.me()
if (res === null || !res.email) {
commit('MutSetUser', null)
} else {
@ -239,7 +239,6 @@ export const actions = {
// console.log('in action signin');
let err = null
try {
const userPromise = await this.$api.auth.signin(data)
commit('MutSetToken', userPromise.token)
@ -272,7 +271,7 @@ export const actions = {
async ActGetUserDetails({ commit, state }) {
try {
const user = await this.$api.auth.me({ // await this.$axios.get('/user/me', {
const user = await this.$api.auth.me({}, {
headers: {
'xc-auth': state.token
}
@ -285,11 +284,10 @@ export const actions = {
async ActGetProjectUserDetails({ commit, state }, projectId) {
try {
const user = await this.$api.auth.me({ // '/user/me?project_id=' + projectId, {
const user = await this.$api.auth.me({ project_id: projectId }, {
headers: {
'xc-auth': state.token
},
query: { project_id: projectId }
}
})
commit('MutProjectRole', user && user.roles)
} catch (e) {
@ -299,7 +297,7 @@ export const actions = {
async ActGetBaseUserDetails({ commit, state }, sharedBaseId) {
try {
try {
const user = await this.$api.auth.me({ // '/user/me', {
const user = await this.$api.auth.me({}, {
headers: {
'xc-shared-base-id': sharedBaseId
}

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

@ -1,6 +1,6 @@
{
"name": "nc-lib-gui",
"version": "0.84.17",
"version": "0.90.0",
"description": "> TODO: description",
"author": "“pranavxc” <pranavxc@gmail.com>",
"homepage": "https://gitlab.com/xgenecloud-ts/xgenecloud-ts#readme",
@ -30,4 +30,4 @@
"express": "^4.17.1",
"vuedraggable": "^2.24.3"
}
}
}

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

@ -8,7 +8,7 @@ menuTitle: 'Usage Information'
<announcement></announcement>
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.
NocoDB is a fast growing open source project which is UI heavy 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.
@ -18,19 +18,49 @@ We will always continue to do hands-on UI/UX testing, surveys, issue tracking an
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.
However, these above actions alone are often insufficient
- To maintain an overall picture of the product usage.
- Prioritising the efforts.
- Impact of any breaking changes.
- To understand whether UI improvements are helpful to users.
## What we collect ?
The following data is collected:
We collect actions made on models (project, table, view, sharedView, user, hook, image, sharedBase etc) periodically with :
- 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.
- Failures.
Here is an example :
```
{
"machine_id" : "a0885e8e6a38d9fbb5d39e7d04a44da7773d4f",
"evt_type": "project:created"
"package_id" : "0.84.15",
"os_type" : "Linux",
"os_platform" : "linux",
"os_release" : "5.10.25-linuxkit",
"node_version" : "14.18.2",
"docker" : "true",
"xc_version" : "0.84.15",
"env" : "dev",
}
```
Our UI Dashboard is a Vuejs-Nuxtjs app. Actions taken on UI with completely anonymized route names are sent as payload.
Here is an example :
```
{
"id": "a0885e8e6a38d9fbb5d39e7d04a44da7773d4f",
"event": "table:create",
"path": "/nc/:project_id",
}
```
## What we DO NOT collect ?
We do not collect private or sensitive information, such as:
We do not collect any private or sensitive information, such as:
- Personally identifiable information
- Credential information (endpoints, ports, DB connections, username/password)
- User data
@ -39,4 +69,3 @@ We do not collect private or sensitive information, such as:
## Opt-out
To disable usage information collection please set following environment variable.
> NC_DISABLE_TELE=true

33
packages/noco-docs/content/en/developer-resources/accessing-apis.md

@ -6,13 +6,13 @@ category: 'Developer Resources'
menuTitle: 'Accessing APIs'
---
## REST APIs
NocoDB APIs can be authorized by either Auth Token or API Token.
- Go to NocoDB Project, click the rightmost button and click ``Copy Auth Token``.
## Auth Token
Auth Token is a JWT Token generated based on the logged-in user. By default, the token is only valid for 10 hours. However, you can change the value by defining it using environment variable `NC_JWT_EXPIRES_IN`. If you are passing Auth Token, make sure that the header is called `xc-auth`.
<alert>
Auth Token is a JWT Token generated based on the logged-in user. By default, the token is only valid for 10 hours. However, you can change the value by defining it using environment variable NC_JWT_EXPIRES_IN. If you are passing Auth Token, make sure that the header is called xc-auth.
</alert>
- Go to NocoDB Project, click the rightmost button and click ``Copy Auth Token``.
![image](https://user-images.githubusercontent.com/35857179/161957971-e4888983-25e1-46a4-8419-7b9fae6cb6fa.png)
@ -28,4 +28,25 @@ Auth Token is a JWT Token generated based on the logged-in user. By default, the
- Paste the token you just copy in step 1 and click Authorize
![image](https://user-images.githubusercontent.com/35857179/126188510-b3790348-6809-4182-911a-a4031ace2fd2.png)
![image](https://user-images.githubusercontent.com/35857179/126188510-b3790348-6809-4182-911a-a4031ace2fd2.png)
## API Token
NocoDB allows creating API tokens which allow it to be integrated seamlessly with 3rd party apps. API Token is a Nano ID with a length of 40. If you are passing API Token, make sure that the header is called `xc-token`.
- Go to `Team & Settings` from the left navigation drawer
![image](https://user-images.githubusercontent.com/35857179/161902474-fd06678c-a171-4237-b171-dc028b3753de.png)
- Click `API Tokens Management`
![image](https://user-images.githubusercontent.com/35857179/161958345-83cb60bf-80f1-4d11-9e9c-52d0b05c7677.png)
- Click Add New Token
![image](https://user-images.githubusercontent.com/35857179/161958563-dc5d380a-26c5-4b78-9d4b-e40188bef05a.png)
- Type an recognizable name for your token and click `Generate`
![image](https://user-images.githubusercontent.com/35857179/161958676-e4faa321-13ca-4b11-8d22-1332c522dde7.png)
- Copy API token to your clipboard
![image](https://user-images.githubusercontent.com/35857179/161958822-b0689a6a-a864-429f-8bb2-71eb92808339.png)

36
packages/noco-docs/content/en/developer-resources/api-tokens.md

@ -1,36 +0,0 @@
---
title: 'API Tokens'
description: 'API Tokens'
position: 1040
category: 'Developer Resources'
menuTitle: 'API Tokens'
---
## API Tokens
NocoDB allows creating API tokens which allow it to be integrated seamlessly with 3rd party apps.
<alert>
API Token is a Nano ID with a length of 40. If you are passing API Token, make sure that the header is called xc-token.
</alert>
### Which HTTP Header to use ?
- ```xc-token``` header should be set when invoking the NocoDB APIs with the token.
### How to create a token ?
1. Go to `Team & Settings` from the left navigation drawer
![image](https://user-images.githubusercontent.com/35857179/161902474-fd06678c-a171-4237-b171-dc028b3753de.png)
2. Click `API Tokens Management`
![image](https://user-images.githubusercontent.com/35857179/161958345-83cb60bf-80f1-4d11-9e9c-52d0b05c7677.png)
3. Click Add New Token
![image](https://user-images.githubusercontent.com/35857179/161958563-dc5d380a-26c5-4b78-9d4b-e40188bef05a.png)
4. Type an recognizable name for your token and click `Generate`
![image](https://user-images.githubusercontent.com/35857179/161958676-e4faa321-13ca-4b11-8d22-1332c522dde7.png)
5. Copy API token to your clipboard
![image](https://user-images.githubusercontent.com/35857179/161958822-b0689a6a-a864-429f-8bb2-71eb92808339.png)

9
packages/noco-docs/content/en/developer-resources/caching.md

@ -1,9 +0,0 @@
---
title: 'Caching'
description: 'Caching'
position: 1300
category: 'Developer Resources'
menuTitle: 'Caching'
---
We introduced a Caching layer to store meta data by utilising Redis. By default, caching is enabled. If you prefer not to cache, you can configure it by setting environment variable `NC_DISABLE_CACHE` to `true`. You can also use your own Redis instance by setting environment variable `NC_REDIS_URL` (e.g. `redis://:authpassword@127.0.0.1:6380/4`). If you don't specify it, by default, it will be cached in memory.

9
packages/noco-docs/content/en/developer-resources/data-apis.md

@ -1,9 +0,0 @@
---
title: 'Data APIs'
description: 'Data APIs'
position: 1200
category: 'Developer Resources'
menuTitle: 'Data APIs'
---
TBC

9
packages/noco-docs/content/en/developer-resources/meta-apis.md

@ -1,9 +0,0 @@
---
title: 'Meta APIs'
description: 'Meta APIs'
position: 1100
category: 'Developer Resources'
menuTitle: 'Meta APIs'
---
TBC

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

File diff suppressed because it is too large Load Diff

55
packages/noco-docs/content/en/developer-resources/sdk.md

@ -1,26 +1,67 @@
---
title: 'SDK'
title: 'NocoDB SDK'
description: 'SDK'
position: 1400
category: 'Developer Resources'
menuTitle: 'SDK'
menuTitle: 'NocoDB SDK'
---
We provide SDK for users to integrated with their applications. Currently only Javascript is supported.
We provide SDK for users to integrate with their applications. Currently only SDK for Javascript is supported.
### SDK For Javascript
<alert>
Note: The NocoDB SDK requires authorization token. If you haven't created one, please check out <a href="./accessing-apis" target="_blank">Accessing APIs</a> for details.
</alert>
## SDK For Javascript
### Install nocodb-sdk
```bash
npm i nocodb-sdk
```
### Import Api
```js
import { Api } from 'nocodb-sdk'
```
### Configure Api
The Api can be authorizated by either Auth Token or API Token.
#### Example: Auth Token
```js
const api = new Api({
baseURL: 'http://<HOST>:<PORT>',
baseURL: 'https://<HOST>:<PORT>',
headers: {
'xc-auth': '<AUTH_TOKEN>'
}
})
```
// await api.meta.something()
// await api.data.something()
#### Example: API Token
```js
const api = new Api({
baseURL: 'https://<HOST>:<PORT>',
headers: {
'xc-token': '<API_TOKEN>'
}
})
```
### Call Functions
Once you have configured `api`, you can call different types of APIs by `api.<Tag>.<FunctionName>`.
<alert>
For Tag and FunctionName, please check out the API table <a href="./rest-apis" target="_blank">here</a>.
</alert>
#### Example: Calling API - /api/v1/db/meta/projects/{projectId}/tables
```js
await api.dbTable.create(params)
```

2
packages/noco-docs/content/en/developer-resources/webhooks.md

@ -1,7 +1,7 @@
---
title: "Webhooks"
description: "Webhooks"
position: 1030
position: 1500
category: "Developer Resources"
menuTitle: "Webhooks"
---

18
packages/noco-docs/content/en/engineering/architecture.md

@ -0,0 +1,18 @@
---
title: "NocoDB Architecture"
description: "NocoDB Architecture"
position: 4000
category: "Engineering"
menuTitle: "NocoDB Architecture"
---
By default, if `NC_DB` is not specified, then SQLite will be used to store your meta data. We suggest users to separate the meta data and user data in different databases.
<!-- TODO: update diagram -->
<img src="../architecture.png" style="background: white;border-radius:4px;padding :10px">
| Project Type | Metadata stored in | Data stored in |
|---------|-----------|--------|
| Create new project | NC_DB | NC_DB |
| Create new project with External Database | NC_DB | External Database |
| Create new project from Excel | NC_DB | NC_DB |

31
packages/noco-docs/content/en/engineering/repository-structure.md

@ -0,0 +1,31 @@
---
title: "Repository Structure"
description: "Repository Structure"
position: 3000
category: "Engineering"
menuTitle: "Repository Structure"
---
We use ``Lerna`` to manage multi-packages. We have the following [packages](https://github.com/nocodb/nocodb/tree/master/packages).
- ``packages/nc-cli`` : A CLI to create NocoDB app.
- ``packages/nc-common``: A common library package used internally.
- ``packages/nc-gui``: NocoDB Frontend.
- ``packages/nc-lib-gui``: The build version of ``nc-gui`` which will be used in ``packages/nocodb``.
- ``packages/nc-migrator-archived``: SQL based schema migrations or evolutions.
- ``packages/nc-plugin``: Plugin template.
- ``packages/noco-blog``: NocoDB Blog which will be auto-released to [nocodb/noco-blog](https://github.com/nocodb/noco-blog).
- ``packages/noco-book``: NocoDB Handbook which will be auto-released to [nocodb/noco-book](https://github.com/nocodb/noco-book).
- ``packages/noco-docs``: NocoDB Documentation which will be auto-released to [nocodb/noco-docs](https://github.com/nocodb/noco-docs).
- ``packages/noco-docs-prev``: NocoDB Documentation for previous versions which will be auto-released to [nocodb/noco-docs-prev](https://github.com/nocodb/noco-docs-prev) and will be completely removed on 30 Jun 2022.
- ``packages/nocodb``: NocoDB Backend, hosted in [NPM](https://www.npmjs.com/package/nocodb).

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

@ -65,7 +65,10 @@ If you are a Docker user, you may try this way!
<code-block label="SQLite" active>
```bash
docker run -d --name nocodb -p 8080:8080 nocodb/nocodb:latest
docker run -d --name nocodb \
-v /local/path:/usr/app/data/ \
-p 8080:8080 \
nocodb/nocodb:latest
```
</code-block>
@ -73,10 +76,12 @@ If you are a Docker user, you may try this way!
<code-block label="MySQL">
```bash
docker run -d -p 8080:8080 \
-e NC_DB="mysql2://host.docker.internal:3306?u=root&p=password&d=d1" \
-e NC_AUTH_JWT_SECRET="569a1821-0a93-45e8-87ab-eb857f20a010" \
nocodb/nocodb:latest
docker run -d --name nocodb-mysql \
-v /local/path:/usr/app/data/ \
-p 8080:8080 \
-e NC_DB="mysql2://host.docker.internal:3306?u=root&p=password&d=d1" \
-e NC_AUTH_JWT_SECRET="569a1821-0a93-45e8-87ab-eb857f20a010" \
nocodb/nocodb:latest
```
</code-block>
@ -84,10 +89,12 @@ If you are a Docker user, you may try this way!
<code-block label="Postgres">
```bash
docker run -d -p 8080:8080 \
-e NC_DB="pg://host.docker.internal:5432?u=root&p=password&d=d1" \
-e NC_AUTH_JWT_SECRET="569a1821-0a93-45e8-87ab-eb857f20a010" \
nocodb/nocodb:latest
docker run -d --name nocodb-postgres \
-v /local/path:/usr/app/data/ \
-p 8080:8080 \
-e NC_DB="pg://host.docker.internal:5432?u=root&p=password&d=d1" \
-e NC_AUTH_JWT_SECRET="569a1821-0a93-45e8-87ab-eb857f20a010" \
nocodb/nocodb:latest
```
</code-block>
@ -95,10 +102,12 @@ If you are a Docker user, you may try this way!
<code-block label="SQL Server">
```bash
docker run -d -p 8080:8080 \
-e NC_DB="mssql://host.docker.internal:1433?u=root&p=password&d=d1" \
-e NC_AUTH_JWT_SECRET="569a1821-0a93-45e8-87ab-eb857f20a010" \
nocodb/nocodb:latest
docker run -d --name nocodb-mssql \
-v /local/path:/usr/app/data/ \
-p 8080:8080 \
-e NC_DB="mssql://host.docker.internal:1433?u=root&p=password&d=d1" \
-e NC_AUTH_JWT_SECRET="569a1821-0a93-45e8-87ab-eb857f20a010" \
nocodb/nocodb:latest
```
</code-block>

77
packages/noco-docs/content/en/index.md

@ -13,7 +13,7 @@ menuTitle: 'Introduction'
## Welcome!
NocoDB is an open source Airtable alternative.
NocoDB is a no-code database platform that allows teams to collaborate and build applications with ease of a familiar and intuitive spreadsheet interface. This allows even non-developers or business users to become software creators.
NocoDB works by connecting to any relational database and transforming them into a smart spreadsheet interface! This allows you to build no-code applications collaboratively with teams. NocoDB currently works with MySQL, PostgreSQL, Microsoft SQL Server, SQLite, Amazon Aurora & MariaDB databases.
@ -25,68 +25,43 @@ Also NocoDB's app store allows you to build business workflows on views with com
### Rich Spreadsheet Interface
- ⚡ &nbsp;Search, sort, filter, hide columns with uber ease
- ⚡ &nbsp;Create Views : Grid, Gallery, Form
- ⚡ &nbsp;Share Views : public & password protected
- ⚡ &nbsp;Collaborative & locked Views
- ⚡ &nbsp;Upload images to cells (Works with S3, Minio, GCP, Azure, DigitalOcean, Linode, OVH, BackBlaze)
- ⚡ &nbsp;Roles : Owner, Creator, Editor, Commenter, Viewer
- ⚡ &nbsp;Access Control : Fine-grained access control even at database, table & column level
### App Store for workflow automations
- ⚡ &nbsp;Chat : Microsoft Teams, Slack, Discord, Mattermost
- ⚡ &nbsp;Email : SMTP, SES, Mailchimp
- ⚡ &nbsp;SMS : Twilio
- ⚡ &nbsp;Whatsapp
- ⚡ &nbsp;Any 3rd Party APIs
### Programmatic API access via
- ⚡ &nbsp;REST APIs
- ⚡ &nbsp;Includes JWT Authentication & Social Auth
- ⚡ &nbsp;API tokens to integrate with Zapier, Integromat
## Why are we building this?
Most internet businesses equip themselves with either spreadsheet or a database to solve their business needs. Spreadsheets are used by a Billion+ humans collaboratively every single day. However, we are way off working at similar speeds on databases which are way more powerful tools when it comes to computing. Attempts to solve this with SaaS offerings has meant horrible access controls, vendor lockin, data lockin, abrupt price changes & most importantly a glass ceiling on what's possible in future.
## Our Mission
Our mission is to provide the most powerful no-code interface for databases which is open source to every single internet business in the world. This would not only democratise access to a powerful computing tool but also bring forth a billion+ people who will have radical tinkering-and-building abilities on internet.
## Architecture - Simple Overview
<img src="architecture.png" style="background: white;border-radius:4px;padding :10px">
- ⚡ &nbsp;Basic Operations: Create, Read, Update and Delete on Tables, Columns, and Rows
- ⚡ &nbsp;Fields Operations: Sort, Filter, Hide / Unhide Columns
- ⚡ &nbsp;Multiple Views Types: Grid (By default), Gallery and Form View
- ⚡ &nbsp;View Permissions Types: Collaborative Views, & Locked Views
- ⚡ &nbsp;Share Bases / Views: either Public or Private (with Password Protected)
- ⚡ &nbsp;Variant Cell Types: ID, LinkToAnotherRecord, Lookup, Rollup, SingleLineText, Attachement, Currency, Formula and etc
- ⚡ &nbsp;Access Control with Roles : Fine-grained Access Control at different levels
- ⚡ &nbsp;and more ...
| Project Type | Metadata stored in | Data stored in |
|---------|-----------|--------|
| Create new project | NC_DB | NC_DB |
| Create new project with External Database | NC_DB | External Database |
| Create new project from Excel | NC_DB | NC_DB |
### App Store for Workflow Automations
## NocoDB repository structure
We provide different integrations in three main categories. See <a href="./setup-and-usages/app-store" target="_blank">App Store</a> for details.
We use ``Lerna`` to manage multi-packages. We have the following [packages](https://github.com/nocodb/nocodb/tree/master/packages).
- ⚡ &nbsp;Chat : Slack, Discord, Mattermost, and etc
- ⚡ &nbsp;Email : AWS SES, SMTP, MailerSend, and etc
- ⚡ &nbsp;Storage : AWS S3, Google Cloud Storage, Minio, and etc
- ``packages/nc-cli`` : A CLI to create NocoDB app.
### Programmatic Access
- ``packages/nc-common``: A common library package used internally.
We provide the following ways to let users to invoke actions in a programmatic way. You can use a token (either JWT or Social Auth) to sign your requests for authorization to NocoDB.
- ``packages/nc-gui``: NocoDB Frontend.
- ``packages/nc-lib-gui``: The build version of ``nc-gui`` which will be used in ``packages/nocodb``.
- ``packages/nc-migrator-archived``: SQL based schema migrations or evolutions.
- ``packages/nc-plugin``: Plugin template.
- ⚡ &nbsp;REST APIs
- ⚡ &nbsp;NocoDB SDK
- ``packages/noco-blog``: NocoDB Blog which will be auto-released to [nocodb/noco-blog](https://github.com/nocodb/noco-blog).
### Sync Schema
- ``packages/noco-book``: NocoDB Handbook which will be auto-released to [nocodb/noco-book](https://github.com/nocodb/noco-book).
We allow you to sync schema changes if you have made changes outside NocoDB GUI. However, it has to be noted then you will have to bring your own schema migrations for moving from environment to others. See <a href="./setup-and-usages/sync-schema" target="_blank">Sync Schema</a> for details.
- ``packages/noco-docs``: NocoDB Documentation which will be auto-released to [nocodb/noco-docs](https://github.com/nocodb/noco-docs).
### Audit
- ``packages/noco-docs-prev``: NocoDB Documentation for previous versions which will be auto-released to [nocodb/noco-docs-prev](https://github.com/nocodb/noco-docs-prev) and will be completely removed on 30 Jun 2022.
We are keeping all the user operation logs under one place. See <a href="./setup-and-usages/audit" target="_blank">Audit</a> for details.
- ``packages/nocodb``: NocoDB Backend, hosted in [NPM](https://www.npmjs.com/package/nocodb).
## Why are we building this?
Most internet businesses equip themselves with either spreadsheet or a database to solve their business needs. Spreadsheets are used by a Billion+ humans collaboratively every single day. However, we are way off working at similar speeds on databases which are way more powerful tools when it comes to computing. Attempts to solve this with SaaS offerings has meant horrible access controls, vendor lockin, data lockin, abrupt price changes & most importantly a glass ceiling on what's possible in future.
## Our Mission
Our mission is to provide the most powerful no-code interface for databases which is open source to every single internet business in the world. This would not only democratise access to a powerful computing tool but also bring forth a billion+ people who will have radical tinkering-and-building abilities on internet.
## Contributions

17
packages/noco-docs/content/en/setup-and-usages/app-store.md

@ -0,0 +1,17 @@
---
title: 'App Store'
description: 'App Store'
position: 1200
category: 'Product'
menuTitle: 'App Store'
---
## Overview
We provide different integrations in three main categories.
| Category | App Name |
|---|---|
| Chat | Microsoft Teams <br/> Discord <br/> Twilio <br/> Whatsapp Twilio<br/> Mattermost<br/> Slack |
| Email | SMTP<br/> MailerSend<br/> AWS SES |
| Storage | AWS S3 <br/> Minio <br/> Google Cloud Storage <br/> Spaces <br/> Backblaze B2 <br/> Vultr Object Storage <br/> OvhCloud Object Storage <br/> Linode Object Storage <br/> UpCloud Object Storage <br/> Scaleway Object Storage |

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

@ -1,7 +1,7 @@
---
title: "Column Operations"
description: "Column Operations"
position: 530
position: 520
category: "Product"
menuTitle: "Column Operations"
---

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

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

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

@ -6,27 +6,27 @@ category: "Product"
menuTitle: "Primary value"
---
## What is a `Primary Value` ?
## What is a Primary Value ?
- Primary value as the name stands is the primary or main value within a row of a table that you generally associate that row with.
- It should be usually associated with a column which is uniquely identifiable. However, this uniqueness is not enforced at the database level.
## What is the use of `Primary Value` ?
## What is the use of Primary Value ?
- Within a spreadsheet, primary value are always highlighted so that it is easier to recognise what row we are in.
- And when LinkToAnotherRecord is created between two tables - it is the primary value that appears in LinkToAnotheRecord column.
#### Example : ```Primary value```highlighted in actor table
#### Example : Primary Value highlighted in actor table
<img width="547" alt="actor" src="https://user-images.githubusercontent.com/5435402/152645708-92b83985-4a0a-42b2-9d01-d26be70fd3aa.png">
#### Example : ```Primary value``` highlighted in film table
#### Example : Primary Value highlighted in film table
<img width="1406" alt="film-table" src="https://user-images.githubusercontent.com/5435402/152645713-b4df99b2-4eb7-4fea-85f9-0baf47470ef3.png">
#### Example : ```Primary value``` associated when ```LinkToAnotherRecord``` is created
#### Example : Primary Value associated when LinkToAnotherRecord is created
<img width="753" alt="actor-film" src="https://user-images.githubusercontent.com/5435402/152645714-4061c94a-4cfb-44e5-b112-63cf4ed869fe.png">
## How is ```Primary value``` identfied for existing database tables ?
## How is Primary Value identfied for existing database tables ?
- It is usually the first column after the primary key which is not a number.
- If there is no column which is not a number then the column adjacent to primary key is chosen.
## Can I change the ```Primary Value``` to another column within tables ?
## Can I change the Primary Value to another column within tables ?
- Yes, you can. Hover over column which you want as primary column and click ```Set as Primary Value```

4
packages/noco-docs/content/en/setup-and-usages/share-view.md

@ -6,7 +6,7 @@ category: "Product"
menuTitle: "Share View"
---
## Generate `Share View`
## Generate Share View
- Open a table or a view
@ -22,7 +22,7 @@ menuTitle: "Share View"
![image](https://user-images.githubusercontent.com/35857179/161970131-0fa83989-0673-493d-968f-76913a09cc06.png)
## Access `Share View`
## Access Share View
- Access the link. If it is password-protected, enter the password to unlock.

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

@ -20,14 +20,14 @@ On click, in modal popup, enter the table name, enable/disable default columns a
![table_create_modal](https://user-images.githubusercontent.com/61551451/126772859-5a301c45-d830-4df2-a05a-43b15dd77728.png)
> You can't disable the `id` column since NocoDB need's a primary column for every table.
<alert>
You can't disable the `id` column since NocoDB needs a primary column for every table.
</alert>
After the successful submission, the table will be created and open as a new tab.
![TableCreated](https://user-images.githubusercontent.com/86527202/144402089-b5e35564-80d5-4105-9e00-7e3e1c4a5030.png)
### Table Rename
Right click on Table name on left hand project-tree menu, select `Rename`
@ -35,13 +35,11 @@ In modal popup, enter new table name and click `Submit` button
<img src="https://user-images.githubusercontent.com/86527202/144403447-1b2e4368-eb2b-40c0-901a-54e8adf9a80c.png" width="60%"/>
### Table Delete
The table can be deleted using the `delete` icon present in the toolbar within the table tab.
<img src="https://user-images.githubusercontent.com/86527202/144403591-5d3d36eb-64b7-4057-9244-56a95b47b97b.png" width="60%"/>
## Column
### Column Add
@ -109,4 +107,14 @@ Right-click on anywhere in the row and then from the context menu select `Delete
Bulk delete is also possible by selecting multiple rows by using the checkbox in first column and then `Delete Selected Rows` options from the right click context menu.
<img src="https://user-images.githubusercontent.com/86527202/144406191-ccff1382-e808-44e8-babe-bd937faf1b3d.png" width="40%"/>
## Export Data
You can export your data from a table as a CSV file by clicking `More` and `Download as CSV`.
![image](https://user-images.githubusercontent.com/35857179/163556138-2aa0a782-12e9-49c7-aadf-b7778e91557f.png)
## Import Data
You can import your data in CSV format to a table by clicking `More` and `Upload CSV`.
![image](https://user-images.githubusercontent.com/35857179/163556175-116b12c2-ca2e-4b54-a65a-39250541d873.png)

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

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

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

@ -6,38 +6,66 @@ 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.
<announcement></announcement>
NocoDB is a fast growing open source project which is UI heavy 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
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.
However, these above actions alone are often insufficient
- To maintain an overall picture of the product usage.
- Prioritising the efforts.
- Impact of any breaking changes.
- To understand whether UI improvements are helpful to users.
## What we collect ?
The following data is collected:
We collect actions made on models (project, table, view, sharedView, user, hook, image, sharedBase etc) periodically with :
- 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.
- Failures.
Here is an example :
```
{
"machine_id" : "a0885e8e6a38d9fbb5d39e7d04a44da7773d4f",
"evt_type": "project:created"
"package_id" : "0.84.15",
"os_type" : "Linux",
"os_platform" : "linux",
"os_release" : "5.10.25-linuxkit",
"node_version" : "14.18.2",
"docker" : "true",
"xc_version" : "0.84.15",
"env" : "dev",
}
```
Our UI Dashboard is a Vuejs-Nuxtjs app. Actions taken on UI with completely anonymized route names are sent as payload.
Here is an example :
```
{
"id": "a0885e8e6a38d9fbb5d39e7d04a44da7773d4f",
"event": "table:create",
"path": "/nc/:project_id",
}
```
## What we DO NOT collect ?
We do not collect private or sensitive information, such as:
- Personally identifiable information
We do not collect any 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.
```bash
NC_DISABLE_TELE=true
```
> NC_DISABLE_TELE=true

93
packages/noco-docs/content/en/setup-and-usages/views.md

@ -0,0 +1,93 @@
---
title: 'Views'
description: 'Views'
position: 600
category: 'Product'
menuTitle: 'Views'
---
## What's a View?
In a table, you can use different views to display your data. You can show specific fields in a View. You can also apply Sorting or Filtering to the View. Each View is independent, which means the configuration applying to View 1 will not apply to View 2.
To navigate different views, we can select the target one in the view sidebar. By default, Grid View will be created for you after creating the table.You can create multiple views with the same type as you wish, as long as they have unique View names.
![image](https://user-images.githubusercontent.com/35857179/163340916-d1101709-2051-4d0e-9d86-dd14eced49e9.png)
## View Types
### Grid View
Grid View, as a default type of view, allows you to display your data in a spreadsheet-like interface.
![image](https://user-images.githubusercontent.com/35857179/163343433-f6594d6e-5874-45ae-b403-5774247659bb.png)
### Form View
Form View allows you to arrange fields in a form to input data.
![image](https://user-images.githubusercontent.com/35857179/163355269-73d2a9d4-bafb-47c0-8c0d-d0e66503b47a.png)
You can show and hide some fields using drag-and-drop fashion.
![image](https://user-images.githubusercontent.com/35857179/163355377-6b365472-efae-4f73-a103-5dde7c1f8ea7.png)
### Gallery View
Gallery View allows you to display images as thumbnails with other fields just like a gallery.
<!-- TODO: add screenshots -->
## View Permission Types
We can apply permission to each View. By default, Collaborative Views will be used. To see or change the view type, check the first icon above the View sidebar.
![image](https://user-images.githubusercontent.com/35857179/163343598-fd81edea-f160-41ee-8bb2-3ef1eee5348d.png)
### Collaborative Views
Collaborative View allows you to work with your collaborators with edit permissions.
![image](https://user-images.githubusercontent.com/35857179/163343959-7e2f43cb-1a1f-4f36-985c-ca91db262f98.png)
### Locked Views
Locked View allows you to lock the current View so that no one can edit the View including applying operations such as Sorting or Filtering.
![image](https://user-images.githubusercontent.com/35857179/163343845-b07f9d3f-5a83-4dfd-8d45-9cc59b3512c3.png)
## View Operations
### Create a View
Click '+' in View sidebar.
![image](https://user-images.githubusercontent.com/35857179/163353610-ae85967c-91ac-404f-b3b3-bd122e09f492.png)
### Rename a View
Hover the target View, click the icon and enter the new name.
![image](https://user-images.githubusercontent.com/35857179/163353802-1da52cec-ae17-4ced-8679-62d7180683ec.png)
### Delete a View
Hover the target View and click the delete icon.
<alert>
You cannot delete the very first Grid View.
</alert>
![image](https://user-images.githubusercontent.com/35857179/163359795-f4420402-b2a6-41d8-b48c-f0dea8b9abbe.png)
### Duplicate a View
Hover the target View and click the icon and enter the new name.
![image](https://user-images.githubusercontent.com/35857179/163353865-7275499e-c685-44f4-906c-ba08f0ee419e.png)
### Reorder a View
Hover the target View and re-order it as needed by dragging and dropping the drag icon.
![image](https://user-images.githubusercontent.com/35857179/163359674-c4aeff74-1cb4-498d-b79c-c6ddf84ad352.png)

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

File diff suppressed because it is too large Load Diff

2
packages/nocodb-sdk/package.json

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

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

@ -620,6 +620,15 @@ export type ColumnReqType =
}
| { uidt?: string; formula_raw?: string; formula?: string; title?: string };
export interface UserInfoType {
id?: string;
email?: string;
email_verified?: string;
firstname?: string;
lastname?: string;
roles?: any;
}
import axios, { AxiosInstance, AxiosRequestConfig, ResponseType } from 'axios';
export type QueryParamsType = Record<string | number, any>;
@ -798,7 +807,7 @@ export class Api<
* @summary Signup
* @request POST:/api/v1/db/auth/user/signup
* @response `200` `{ token?: string }` OK
* @response `400` `void` Bad Request
* @response `400` `{ msg?: string }` Bad Request
* @response `401` `void` Unauthorized
* @response `403` `void` Forbidden
*/
@ -806,7 +815,7 @@ export class Api<
data: { email?: string; password?: string },
params: RequestParams = {}
) =>
this.request<{ token?: string }, void>({
this.request<{ token?: string }, { msg?: string } | void>({
path: `/api/v1/db/auth/user/signup`,
method: 'POST',
body: data,
@ -822,12 +831,13 @@ export class Api<
* @summary Signin
* @request POST:/api/v1/db/auth/user/signin
* @response `200` `{ token?: string }` OK
* @response `400` `{ msg?: string }` Bad Request
*/
signin: (
data: { email: string; password: string },
params: RequestParams = {}
) =>
this.request<{ token?: string }, any>({
this.request<{ token?: string }, { msg?: string }>({
path: `/api/v1/db/auth/user/signin`,
method: 'POST',
body: data,
@ -843,12 +853,13 @@ export class Api<
* @name Me
* @summary User Info
* @request GET:/api/v1/db/auth/user/me
* @response `200` `UserType` OK
* @response `200` `UserInfoType` OK
*/
me: (params: RequestParams = {}) =>
this.request<UserType, any>({
me: (query?: { project_id?: string }, params: RequestParams = {}) =>
this.request<UserInfoType, any>({
path: `/api/v1/db/auth/user/me`,
method: 'GET',
query: query,
format: 'json',
...params,
}),
@ -861,9 +872,10 @@ export class Api<
* @summary Password Forgot
* @request POST:/api/v1/db/auth/password/forgot
* @response `200` `void` OK
* @response `401` `void` Unauthorized
*/
passwordForgot: (data: { email?: string }, params: RequestParams = {}) =>
this.request<void, any>({
this.request<void, void>({
path: `/api/v1/db/auth/password/forgot`,
method: 'POST',
body: data,
@ -878,21 +890,19 @@ export class Api<
* @name PasswordChange
* @summary Password Change
* @request POST:/api/v1/db/auth/password/change
* @response `200` `void` OK
* @response `200` `{ msg?: string }` OK
* @response `400` `{ msg?: string }` Bad request
*/
passwordChange: (
data: {
currentPassword?: string;
newPassword?: string;
verifyPassword?: string;
},
data: { currentPassword?: string; newPassword?: string },
params: RequestParams = {}
) =>
this.request<void, any>({
this.request<{ msg?: string }, { msg?: string }>({
path: `/api/v1/db/auth/password/change`,
method: 'POST',
body: data,
type: ContentType.Json,
format: 'json',
...params,
}),
@ -1310,7 +1320,7 @@ export class Api<
*
* @tags Project
* @name AuditList
* @request GET:/api/v1/db/meta/project/{projectId}/audits
* @request GET:/api/v1/db/meta/projects/{projectId}/audits
* @response `200` `{ list: (AuditType)[], pageInfo: PaginatedType }` OK
*/
auditList: (
@ -1319,7 +1329,7 @@ export class Api<
params: RequestParams = {}
) =>
this.request<{ list: AuditType[]; pageInfo: PaginatedType }, any>({
path: `/api/v1/db/meta/project/${projectId}/audits`,
path: `/api/v1/db/meta/projects/${projectId}/audits`,
method: 'GET',
query: query,
format: 'json',
@ -2466,11 +2476,11 @@ export class Api<
* No description
*
* @tags DB table row
* @name NestedDelete
* @name NestedRemove
* @request DELETE:/api/v1/db/data/{orgs}/{projectName}/{tableName}/{rowId}/{relationType}/{columnName}/{refRowId}
* @response `200` `any` OK
*/
nestedDelete: (
nestedRemove: (
orgs: string,
projectName: string,
tableName: string,
@ -2945,6 +2955,22 @@ export class Api<
...params,
}),
/**
* No description
*
* @tags Utils
* @name AppVersion
* @request GET:/api/v1/db/meta/nocodb/version
* @response `200` `any` OK
*/
appVersion: (params: RequestParams = {}) =>
this.request<any, any>({
path: `/api/v1/db/meta/nocodb/version`,
method: 'GET',
format: 'json',
...params,
}),
/**
* @description Get All K/V pairs in NocoCache
*

25264
packages/nocodb/package-lock.json generated

File diff suppressed because it is too large Load Diff

10
packages/nocodb/package.json

@ -1,6 +1,6 @@
{
"name": "nocodb",
"version": "0.84.16",
"version": "0.90.0",
"description": "NocoDB",
"main": "dist/bundle.js",
"repository": "https://github.com/nocodb/nocodb",
@ -67,7 +67,7 @@
"help:c": "ts-node ./help/a",
"watch:build": "nodemon -e ts,js -w ./src -x npm run build",
"watch:serve": "nodemon -e ts -w ./build -x npm run debug-local ",
"watch:run": "cross-env NC_DISABLE_TELE=true EE=true nodemon -e ts,js -w ./src -x \"ts-node src/example/docker --log-error --project tsconfig.json\"",
"watch:run": "cross-env NC_DISABLE_TELE1=true EE=true nodemon -e ts,js -w ./src -x \"ts-node src/example/docker --log-error --project tsconfig.json\"",
"watch:run:cypress": "cross-env EE=true nodemon -e ts,js -w ./src -x \"ts-node src/example/docker --log-error --project tsconfig.json\"",
"watch:run:mysql": "cross-env NC_DISABLE_TELE=true EE=true nodemon -e ts,js -w ./src -x \"ts-node src/example/dockerRunMysql --log-error --project tsconfig.json\"",
"run": "ts-node src/example/docker",
@ -150,11 +150,11 @@
"mysql2": "^2.2.5",
"nanoid": "^3.1.20",
"nc-common": "0.0.6",
"nc-help": "^0.2.31",
"nc-lib-gui": "0.84.15",
"nc-help": "^0.2.44",
"nc-lib-gui": "0.90.0",
"nc-plugin": "^0.1.1",
"ncp": "^2.0.0",
"nocodb-sdk": "file:../nocodb-sdk",
"nocodb-sdk": "0.90.0",
"nodemailer": "^6.4.10",
"ora": "^4.0.4",
"os-locale": "^5.0.0",

4
packages/nocodb/src/lib/noco-models/Column.ts

@ -207,7 +207,9 @@ export default class Column<T = any> implements ColumnType {
dr: column.dr,
fk_index_name: column.fk_index_name,
fk_related_model_id: column.fk_related_model_id
fk_related_model_id: column.fk_related_model_id,
virtual: column.virtual
},
ncMeta
);

3
packages/nocodb/src/lib/noco-models/LinkToAnotherRecordColumn.ts

@ -107,7 +107,8 @@ export default class LinkToAnotherRecordColumn {
dr: data.dr,
fk_index_name: data.fk_index_name,
fk_related_model_id: data.fk_related_model_id
fk_related_model_id: data.fk_related_model_id,
virtual: data.virtual
});
return this.read(data.fk_column_id, ncMeta);
}

2
packages/nocodb/src/lib/noco/meta/api/auditApis.ts

@ -75,7 +75,7 @@ router.get(
ncMetaAclMw(commentsCount, 'commentsCount')
);
router.get(
'/api/v1/db/meta/project/:projectId/audits',
'/api/v1/db/meta/projects/:projectId/audits',
ncMetaAclMw(auditList, 'auditList')
);
export default router;

70
packages/nocodb/src/lib/noco/meta/api/columnApis.ts

@ -45,6 +45,7 @@ async function createHmAndBtColumn(
childColumn: Column,
type?: RelationTypes,
alias?: string,
virtual = false,
isSystemCol = false
) {
// save bt column
@ -65,6 +66,7 @@ async function createHmAndBtColumn(
fk_child_column_id: childColumn.id,
fk_parent_column_id: parent.primaryKey.id,
fk_related_model_id: parent.id,
virtual,
system: isSystemCol
});
}
@ -82,6 +84,7 @@ async function createHmAndBtColumn(
fk_child_column_id: childColumn.id,
fk_parent_column_id: parent.primaryKey.id,
fk_related_model_id: child.id,
virtual,
system: isSystemCol
});
}
@ -275,23 +278,27 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
childColumn = await Column.get({ colId: id });
// create relation
await sqlMgr.sqlOpPlus(base, 'relationCreate', {
childColumn: fkColName,
childTable: child.table_name,
parentTable: parent.table_name,
onDelete: 'NO ACTION',
onUpdate: 'NO ACTION',
type: 'real',
parentColumn: parent.primaryKey.column_name
});
// ignore relation creation if virtual
if (!req.body.virtual) {
// create relation
await sqlMgr.sqlOpPlus(base, 'relationCreate', {
childColumn: fkColName,
childTable: child.table_name,
parentTable: parent.table_name,
onDelete: 'NO ACTION',
onUpdate: 'NO ACTION',
type: 'real',
parentColumn: parent.primaryKey.column_name
});
}
}
await createHmAndBtColumn(
child,
parent,
childColumn,
req.body.type,
req.body.title
req.body.title,
req.body.virtual
);
} else if (req.body.type === 'mm') {
const aTn = `${project?.prefix ?? ''}_nc_m2m_${randomID()}`;
@ -352,26 +359,27 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
columns: associateTableCols
});
const rel1Args = {
...req.body,
childTable: aTn,
childColumn: parentCn,
parentTable: parent.table_name,
parentColumn: parentPK.column_name,
type: 'real'
};
const rel2Args = {
...req.body,
childTable: aTn,
childColumn: childCn,
parentTable: child.table_name,
parentColumn: childPK.column_name,
type: 'real'
};
await sqlMgr.sqlOpPlus(base, 'relationCreate', rel1Args);
await sqlMgr.sqlOpPlus(base, 'relationCreate', rel2Args);
if (!req.body.virtual) {
const rel1Args = {
...req.body,
childTable: aTn,
childColumn: parentCn,
parentTable: parent.table_name,
parentColumn: parentPK.column_name,
type: 'real'
};
const rel2Args = {
...req.body,
childTable: aTn,
childColumn: childCn,
parentTable: child.table_name,
parentColumn: childPK.column_name,
type: 'real'
};
await sqlMgr.sqlOpPlus(base, 'relationCreate', rel1Args);
await sqlMgr.sqlOpPlus(base, 'relationCreate', rel2Args);
}
const parentCol = (await assocModel.getColumns())?.find(
c => c.column_name === parentCn
);
@ -385,6 +393,7 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
childCol,
null,
null,
req.body.virtual,
true
);
await createHmAndBtColumn(
@ -393,6 +402,7 @@ export async function columnAdd(req: Request, res: Response<TableType>) {
parentCol,
null,
null,
req.body.virtual,
true
);

4
packages/nocodb/src/lib/noco/meta/api/dataApis/dataAliasNestedApis.ts

@ -191,7 +191,7 @@ export async function hmList(req: Request, res: Response, next) {
}
//@ts-ignore
async function relationDataDelete(req, res) {
async function relationDataRemove(req, res) {
const { model, view } = await getViewAndModelFromRequestByAliasOrId(req);
if (!model) NcError.notFound('Table not found');
@ -273,7 +273,7 @@ router.post(
);
router.delete(
'/api/v1/db/data/:orgs/:projectName/:tableName/:rowId/:relationType/:columnName/:refRowId',
ncMetaAclMw(relationDataDelete, 'relationDataDelete')
ncMetaAclMw(relationDataRemove, 'relationDataRemove')
);
router.get(

15
packages/nocodb/src/lib/noco/meta/api/index.ts

@ -44,6 +44,8 @@ import { Tele } from 'nc-help';
import { Server } from 'socket.io';
import passport from 'passport';
import crypto from 'crypto';
export default function(router: Router, server) {
initStrategies(router);
projectApis(router);
@ -106,11 +108,20 @@ export default function(router: Router, server) {
}
)(socket.handshake, {}, next);
}).on('connection', socket => {
const id = getHash(Tele.id + (socket?.handshake as any)?.user?.id);
socket.on('page', args => {
Tele.page(args);
Tele.page({ ...args, id });
});
socket.on('event', args => {
Tele.event(args);
Tele.event({ ...args, id });
});
});
}
function getHash(str) {
return crypto
.createHash('md5')
.update(str)
.digest('hex');
}

14
packages/nocodb/src/lib/noco/meta/api/metaDiffApis.ts

@ -31,8 +31,6 @@ export enum MetaDiffType {
VIEW_COLUMN_REMOVE = 'VIEW_COLUMN_REMOVE',
TABLE_RELATION_ADD = 'TABLE_RELATION_ADD',
TABLE_RELATION_REMOVE = 'TABLE_RELATION_REMOVE',
// TABLE_VIRTUAL_RELATION_ADD = 'TABLE_VIRTUAL_RELATION_ADD',
// TABLE_VIRTUAL_RELATION_REMOVE = 'TABLE_VIRTUAL_RELATION_REMOVE',
TABLE_VIRTUAL_M2M_REMOVE = 'TABLE_VIRTUAL_M2M_REMOVE'
}
@ -718,12 +716,12 @@ export async function metaDiffSync(req, res) {
res.json({ msg: 'success' });
}
async function isMMRelationAvailable(
async function isMMRelationExist(
model: Model,
assocModel: Model,
belongsToCol: Column<LinkToAnotherRecordColumn>
) {
let isAvail = false;
let isExist = false;
const colChildOpt = await belongsToCol.getColOptions<
LinkToAnotherRecordColumn
>();
@ -737,12 +735,12 @@ async function isMMRelationAvailable(
colOpt.fk_child_column_id === colChildOpt.fk_parent_column_id &&
colOpt.fk_mm_child_column_id === colChildOpt.fk_child_column_id
) {
isAvail = true;
isExist = true;
break;
}
}
}
return isAvail;
return isExist;
}
// @ts-ignore
@ -772,12 +770,12 @@ export async function extractAndGenerateManyToManyRelations(
await modelB.getColumns();
// check tableA already have the relation or not
const isRelationAvailInA = await isMMRelationAvailable(
const isRelationAvailInA = await isMMRelationExist(
modelA,
assocModel,
belongsToCols[0]
);
const isRelationAvailInB = await isMMRelationAvailable(
const isRelationAvailInB = await isMMRelationExist(
modelB,
assocModel,
belongsToCols[1]

11
packages/nocodb/src/lib/noco/meta/api/utilApis.ts

@ -7,6 +7,7 @@ import SqlMgrv2 from '../../../sqlMgr/v2/SqlMgrv2';
import { defaultConnectionConfig } from '../../../utils/NcConfigFactory';
import User from '../../../noco-models/User';
import catchError from '../helpers/catchError';
import axios from 'axios';
export async function testConnection(req: Request, res: Response) {
res.json(await SqlMgrv2.testConnection(req.body));
@ -43,10 +44,20 @@ export async function appInfo(_req: Request, res: Response) {
res.json(result);
}
export async function releaseVersion(_req: Request, res: Response) {
const result = await axios.get('https://github.com/nocodb/nocodb/releases/latest')
.then((response) => {
return { releaseVersion: response.request.res.responseUrl.replace('https://github.com/nocodb/nocodb/releases/tag/', '') }
})
res.json(result);
}
export default router => {
router.post(
'/api/v1/db/meta/connection/test',
ncMetaAclMw(testConnection, 'testConnection')
);
router.get('/api/v1/db/meta/nocodb/info', catchError(appInfo));
router.get('/api/v1/db/meta/nocodb/version', catchError(releaseVersion));
};

81
packages/nocodb/src/lib/noco/upgrader/jobs/ncProjectUpgraderV2_0090000.ts

@ -227,7 +227,7 @@ interface LinkToAnotherRecordv1 {
}
interface ModelMetav1 {
id: number;
id: number | string;
project_id: string;
db_alias: string;
title: string;
@ -296,6 +296,7 @@ interface MigrateCtxV1 {
objModelColumnAliasRef: ObjModelColumnAliasRefv1;
objViewRef: ObjViewRefv1;
objViewQPRef: ObjViewQPRefv1;
metas: ModelMetav1[];
}
// @ts-ignore
@ -312,12 +313,36 @@ const filterV1toV2CompOpMap = {
'is not like': 'nlike'
};
interface Relationv1 {
project_id?: string;
db_alias?: string;
tn?: string;
rtn?: string;
_tn?: string;
_rtn?: string;
cn?: string;
rcn?: string;
_cn?: string;
_rcn?: string;
referenced_db_alias?: string;
type?: string;
db_type?: string;
ur?: string;
dr?: string;
}
async function migrateProjectModels(
ncMeta = Noco.ncMeta
): Promise<MigrateCtxV1> {
// @ts-ignore
const metas: ModelMetav1[] = await ncMeta.metaList(null, null, 'nc_models');
// @ts-ignore
const relations: Relationv1[] = await ncMeta.metaList(
null,
null,
'nc_relations'
);
const models: Model[] = [];
// variable for keeping all
@ -443,6 +468,37 @@ async function migrateProjectModels(
fk_mm_parent_column_id =
projectModelColumnRefs[rel.vtn][rel.vrcn].id;
}
let virtual = false;
if (columnMeta.mm) {
const relation = relations.find(
r =>
r.rtn === columnMeta.mm.tn &&
r.rcn === columnMeta.mm.cn &&
r.tn === columnMeta.mm.vtn &&
r.cn === columnMeta.mm.vcn
);
virtual = relation?.type === 'virtual';
} else if (columnMeta.hm) {
virtual =
relations.find(
r =>
r.rtn === columnMeta.hm.rtn &&
r.tn === columnMeta.hm.tn &&
r.rcn === columnMeta.hm.rcn &&
r.cn === columnMeta.hm.cn
)?.type === 'virtual';
} else if (columnMeta.bt) {
virtual =
relations.find(
r =>
r.rtn === columnMeta.bt.rtn &&
r.tn === columnMeta.bt.tn &&
r.rcn === columnMeta.bt.rcn &&
r.cn === columnMeta.bt.cn
)?.type === 'virtual';
}
const column = await Column.insert<LinkToAnotherRecordColumn>(
{
project_id: project.id,
@ -460,7 +516,8 @@ async function migrateProjectModels(
fk_mm_model_id,
fk_mm_child_column_id,
fk_mm_parent_column_id,
fk_related_model_id: columnMeta.hm ? tnId : rtnId
fk_related_model_id: columnMeta.hm ? tnId : rtnId,
virtual
},
ncMeta
);
@ -636,6 +693,15 @@ async function migrateProjectModels(
// const rtnId = projectModelRefs?.[rel.rtn]?.id;
const virtual =
relations.find(
r =>
r.rtn === rel.rtn &&
r.tn === rel.tn &&
r.rcn === rel.rcn &&
r.cn === rel.cn
)?.type === 'virtual';
const column = await Column.insert<LinkToAnotherRecordColumn>(
{
project_id: project.id,
@ -651,7 +717,8 @@ async function migrateProjectModels(
ur: rel.ur,
dr: rel.dr,
fk_related_model_id: tnId,
system: true
system: true,
virtual
},
ncMeta
);
@ -720,6 +787,7 @@ async function migrateProjectModels(
await migrateProjectModelViews(
{
metas,
views,
objModelRef,
objModelColumnAliasRef,
@ -733,6 +801,7 @@ async function migrateProjectModels(
await migrateViewsParams(
{
metas,
views,
objModelRef,
objModelColumnAliasRef,
@ -745,6 +814,7 @@ async function migrateProjectModels(
);
return {
metas,
views,
objModelRef,
objModelColumnAliasRef,
@ -1204,8 +1274,9 @@ async function migrateAutitLog(ctx: MigrateCtxV1, ncMeta: any) {
if (audit.model_name) {
insertObj.fk_model_id = (
ctx.objModelAliasRef?.[audit.project_id]?.[audit.model_name] ||
ctx.objModelRef?.[audit.project_id]?.[audit.model_name]
).id;
ctx.objModelRef?.[audit.project_id]?.[audit.model_name] ||
ctx.metas?.find(m => m.id == audit.model_id)
)?.id;
}
await Audit.insert(insertObj, ncMeta);

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

@ -116,7 +116,15 @@ export default {
xcModelRowAuditAndCommentList: true,
xcAuditCommentInsert: true,
xcAuditModelCommentsCount: true,
xcExportAsCsv: true
xcExportAsCsv: true,
bulkDataInsert: true,
bulkDataUpdate: true,
bulkDataUpdateAll: true,
bulkDataDelete: true,
bulkDataDeleteAll: true,
relationDataRemove: true,
relationDataAdd: true
},
commenter: {
formViewGet: true,
@ -133,8 +141,10 @@ export default {
columnList: true,
mmList: true,
hmList: true,
commentList: true,
commentRow: true,
projectInfoGet: true,
// data
dataList: true,
@ -178,6 +188,7 @@ export default {
// sort & filter
sortList: true,
projectInfoGet: true,
mmList: true,
hmList: true,

2
scripts/bumpNocodbSdkVersion.js

@ -13,6 +13,6 @@ if (process.env.targetEnv === 'DEV') {
packageJson.version = `${packageJson.version}-${process.env.targetVersion}`
packageJson.name += '-daily'
} else {
packageJson.version = version
packageJson.version = process.env.targetVersion
}
fs.writeFileSync(path.join(__dirname, '..', 'packages', 'nocodb-sdk', 'package.json'), JSON.stringify(packageJson, 0, 2))

231
scripts/sdk/swagger.json

@ -26,12 +26,58 @@
"type": "string"
}
}
},
"examples": {
"Successful registration response": {
"value": {
"token": "string"
}
}
}
}
}
},
"400": {
"description": "Bad Request"
"description": "Bad Request",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"msg": {
"type": "string"
}
}
},
"examples": {
"Invalid email": {
"value": {
"msg": "Invalid email"
}
},
"Invalid invite url": {
"value": {
"msg": "Invalid invite url"
}
},
"Expired invite url": {
"value": {
"msg": "Expired invite url, Please contact super admin to get a new invite url"
}
},
"User already exist": {
"value": {
"msg": "User already exist"
}
},
"Invite only signup": {
"value": {
"msg": "Not allowed to signup, contact super admin"
}
}
}
}
}
},
"401": {
"description": "Unauthorized"
@ -68,6 +114,21 @@
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"msg": {
"type": "string"
}
}
}
}
}
}
},
"tags": [
@ -90,6 +151,14 @@
"email",
"password"
]
},
"examples": {
"example-1": {
"value": {
"email": "user@nocodb.com",
"password": "Password"
}
}
}
}
}
@ -109,7 +178,21 @@
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/User"
"$ref": "#/components/schemas/UserInfo"
},
"examples": {
"example-1": {
"value": {
"id": "string",
"email": "string",
"email_verified": "string",
"firstname": "string",
"lastname": "string",
"roles": {
"editor": true
}
}
}
}
}
}
@ -118,7 +201,17 @@
"tags": [
"Auth"
],
"description": "Returns authenticated user info"
"description": "Returns authenticated user info",
"parameters": [
{
"schema": {
"type": "string"
},
"in": "query",
"name": "project_id",
"description": "Pass project id to get project specific roles along with user info"
}
]
}
},
"/api/v1/db/auth/password/forgot": {
@ -128,6 +221,9 @@
"responses": {
"200": {
"description": "OK"
},
"401": {
"description": "Unauthorized"
}
},
"description": "Emails user with a reset url.",
@ -146,7 +242,8 @@
}
}
}
}
},
"description": "Pass registered user email id in request body"
}
},
"parameters": []
@ -157,7 +254,53 @@
"operationId": "auth-password-change",
"responses": {
"200": {
"description": "OK"
"description": "OK",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"msg": {
"type": "string"
}
}
},
"examples": {
"Success response": {
"value": {
"msg": "Password updated successfully"
}
}
}
}
}
},
"400": {
"description": "Bad request",
"content": {
"application/json": {
"schema": {
"type": "object",
"properties": {
"msg": {
"type": "string"
}
}
},
"examples": {
"Missing params": {
"value": {
"msg": "Missing new/old password"
}
},
"Wrong password": {
"value": {
"msg": "Current password is wrong"
}
}
}
}
}
}
},
"description": "Change password of authenticated user with a new one.",
@ -175,14 +318,20 @@
},
"newPassword": {
"type": "string"
},
"verifyPassword": {
"type": "string"
}
}
},
"examples": {
"example-1": {
"value": {
"currentPassword": "string",
"newPassword": "string"
}
}
}
}
}
},
"description": "Old password need to be passed along with new password for changing password."
}
},
"parameters": []
@ -292,7 +441,6 @@
},
"parameters": []
},
"/api/v1/db/meta/projects/{projectId}/users": {
"get": {
"summary": "Project Users",
@ -1522,8 +1670,7 @@
"get": {
"summary": "",
"operationId": "db-view-column-list",
"responses": {
},
"responses": {},
"tags": [
"DB View Column"
]
@ -2281,7 +2428,6 @@
}
}
},
"/api/v1/db/data/{orgs}/{projectName}/{tableName}": {
"parameters": [
{
@ -3104,7 +3250,8 @@
"name": "relationType",
"in": "path",
"required": true
},{
},
{
"schema": {
"type": "string"
},
@ -3245,7 +3392,7 @@
},
"delete": {
"summary": "",
"operationId": "db-table-row-nested-delete",
"operationId": "db-table-row-nested-remove",
"responses": {
"200": {
"description": "OK",
@ -3350,7 +3497,6 @@
]
}
},
"/api/v1/db/public/shared-view/{sharedViewUuid}/rows": {
"parameters": [
{
@ -3421,7 +3567,7 @@
"multipart/form-data": {
"schema": {
"type": "object",
"properties": { }
"properties": {}
}
}
}
@ -3707,7 +3853,6 @@
]
}
},
"/api/v1/db/meta/audits/comments": {
"parameters": [],
"get": {
@ -3830,7 +3975,7 @@
]
}
},
"/api/v1/db/meta/project/{projectId}/audits": {
"/api/v1/db/meta/projects/{projectId}/audits": {
"parameters": [
{
"schema": {
@ -3945,7 +4090,6 @@
}
}
},
"/api/v1/db/meta/tables/{tableId}/hooks": {
"parameters": [
{
@ -4195,7 +4339,6 @@
]
}
},
"/api/v1/db/meta/plugins": {
"parameters": [],
"get": {
@ -4374,7 +4517,6 @@
]
}
},
"/api/v1/db/meta/connection/test": {
"parameters": [],
"post": {
@ -4434,6 +4576,27 @@
"description": ""
}
},
"/api/v1/db/meta/nocodb/version": {
"parameters": [],
"get": {
"summary": "",
"operationId": "utils-app-version",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {}
}
}
}
},
"tags": [
"Utils"
],
"description": ""
}
},
"/api/v1/db/meta/cache": {
"get": {
"summary": "Your GET endpoint",
@ -4459,7 +4622,6 @@
},
"parameters": []
},
"/api/v1/db/meta/projects/{projectId}/api-tokens": {
"get": {
"summary": "Your GET endpoint",
@ -4562,7 +4724,6 @@
}
]
},
"/api/v1/db/storage/upload": {
"post": {
"summary": "Attachment",
@ -7010,6 +7171,28 @@
],
"description": "",
"type": "object"
},
"UserInfo": {
"title": "UserInfo",
"type": "object",
"properties": {
"id": {
"type": "string"
},
"email": {
"type": "string"
},
"email_verified": {
"type": "string"
},
"firstname": {
"type": "string"
},
"lastname": {
"type": "string"
},
"roles": {}
}
}
},
"requestBodies": {

Loading…
Cancel
Save