Browse Source

Merge branch 'develop' into feat/backend-refactoring-nest

pull/5444/head
Wing-Kam Wong 2 years ago
parent
commit
735b7568f0
  1. 2
      packages/nc-gui/components/cell/attachment/Image.vue
  2. 2
      packages/nc-gui/components/dlg/TableCreate.vue
  3. 2
      packages/nc-gui/components/smartsheet/Cell.vue
  4. 1
      packages/nc-gui/composables/useAttachment.ts
  5. 2
      packages/nc-gui/lang/pt_BR.json
  6. 2
      packages/noco-docs/content/en/developer-resources/rest-apis.md
  7. 4
      packages/noco-docs/content/en/developer-resources/sdk.md
  8. 2
      packages/noco-docs/content/en/getting-started/upgrading.md
  9. 6
      packages/noco-docs/content/en/index.md
  10. 2
      packages/noco-docs/content/en/setup-and-usages/meta-management.md
  11. 6
      packages/noco-docs/content/en/setup-and-usages/table-operations.md
  12. 1
      packages/nocodb/src/lib/controllers/publicControllers/publicData.ctl.ts
  13. 10
      packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/pg.ts
  14. 4
      packages/nocodb/src/lib/services/attachment.svc.ts
  15. 17
      packages/nocodb/src/lib/services/public/publicData.svc.ts
  16. 15
      packages/nocodb/src/schema/swagger.json
  17. 12
      tests/playwright/tests/columnFormula.spec.ts

2
packages/nc-gui/components/cell/attachment/Image.vue

@ -1,4 +1,6 @@
<script setup lang="ts">
import { iconMap } from '#imports'
interface Props {
srcs: string[]
alt?: string

2
packages/nc-gui/components/dlg/TableCreate.vue

@ -53,7 +53,7 @@ const validators = computed(() => {
validator: (_: any, value: any) => {
// validate duplicate alias
return new Promise((resolve, reject) => {
if ((tables.value || []).some((t) => t.title === (value || ''))) {
if ((tables.value || []).some((t) => t.title === (value || '') && t.base_id === props.baseId)) {
return reject(new Error('Duplicate table alias'))
}
return resolve(true)

2
packages/nc-gui/components/smartsheet/Cell.vue

@ -193,7 +193,7 @@ onUnmounted(() => {
`nc-cell-${(column?.uidt || 'default').toLowerCase()}`,
{ 'text-blue-600': isPrimary(column) && !props.virtual && !isForm },
{ 'nc-grid-numeric-cell': isGrid && !isForm && isNumericField },
{ 'h-[40px]': !props.editEnabled && isForm && !isSurveyForm },
{ 'h-[40px]': !props.editEnabled && isForm && !isSurveyForm && !isAttachment(column) },
]"
@keydown.enter.exact="navigate(NavigateDir.NEXT, $event)"
@keydown.shift.enter.exact="navigate(NavigateDir.PREV, $event)"

1
packages/nc-gui/composables/useAttachment.ts

@ -5,6 +5,7 @@ const useAttachment = () => {
const getPossibleAttachmentSrc = (item: Record<string, any>) => {
const res: string[] = []
if (item?.data) res.push(item.data)
if (item?.path) res.push(`${appInfo.value.ncSiteUrl}/${item.path}`)
if (item?.url) res.push(item.url)
return res

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

@ -698,7 +698,7 @@
"allowedSpecialCharList": "Lista de caracteres especiais permitidos"
},
"invalidURL": "URL inválido",
"invalidEmail": "Invalid Email",
"invalidEmail": "E-mail inválido",
"internalError": "Ocorreu algum erro interno",
"templateGeneratorNotFound": "O Gerador de Modelos não pode ser encontrado!",
"fileUploadFailed": "Falha no carregamento do ficheiro",

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

@ -12,7 +12,7 @@ Once you've created the schemas, you can manipulate the data or invoke actions u
Here's the overview of all APIs. For the details, please check out <a href="https://all-apis.nocodb.com/" target="_blank">NocoDB API Documentation</a>.
You may also interact with the API's resources via <a href="./accessing-apis#swagger-ui" target="_blank">Swagger UI</a>.
You may also interact with the API's resources via <NuxtLink to="/developer-resources/accessing-apis#swagger-ui" target="_blank">Swagger UI</NuxtLink>.
<alert type="success">
Currently, the default value for {orgs} is <b>noco</b>. Users will be able to change it in the future release.

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

@ -9,7 +9,7 @@ menuTitle: 'NocoDB SDK'
We provide SDK for users to integrate with their applications. Currently only SDK for Javascript is supported.
<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.
Note: The NocoDB SDK requires authorization token. If you haven't created one, please check out <NuxtLink to="/developer-resources/accessing-apis" target="_blank">Accessing APIs</NuxtLink> for details.
</alert>
## SDK For Javascript
@ -57,7 +57,7 @@ const api = new Api({
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>.
For Tag and FunctionName, please check out the API table <NuxtLink to="/developer-resources/rest-apis" target="_blank">here</NuxtLink>.
</alert>
#### Example: Calling API - /api/v1/db/meta/projects/{projectId}/tables

2
packages/noco-docs/content/en/getting-started/upgrading.md

@ -8,7 +8,7 @@ link: https://codesandbox.io/embed/vigorous-firefly-80kq5?hidenavigation=1&theme
---
By default, if `NC_DB` is not specified upon
<a href="./installation" target="_blank">installation</a>, then SQLite will be used to store metadata. We suggest users to separate the metadata and user data in different databases as pictured in our <a href="../engineering/architecture" target="_blank">architecture</a>.
<NuxtLink to="/getting-started/installation" target="_blank">installation</NuxtLink>, then SQLite will be used to store metadata. We suggest users to separate the metadata and user data in different databases as pictured in our <NuxtLink to="/engineering/architecture" target="_blank">architecture</NuxtLink>.
## Docker

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

@ -31,7 +31,7 @@ Also NocoDB's app store allows you to build business workflows on views with com
### App Store for Workflow Automations
We provide different integrations in three main categories. See <a href="./setup-and-usages/app-store" target="_blank">App Store</a> for details.
We provide different integrations in three main categories. See <NuxtLink to="/setup-and-usages/account-settings#app-store" target="_blank">App Store</NuxtLink> for details.
- ⚡ &nbsp;Chat : Slack, Discord, Mattermost, and etc
- ⚡ &nbsp;Email : AWS SES, SMTP, MailerSend, and etc
@ -46,11 +46,11 @@ We provide the following ways to let users to invoke actions in a programmatic w
### 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="./setup-and-usages/sync-schema" target="_blank">Sync Schema</a> for details.
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 <NuxtLink to="/setup-and-usages/sync-schema" target="_blank">Sync Schema</NuxtLink> for details.
### Audit
We are keeping all the user operation logs under one place. See <a href="./setup-and-usages/audit" target="_blank">Audit</a> for details.
We are keeping all the user operation logs under one place. See <NuxtLink to="/setup-and-usages/audit" target="_blank">Audit</NuxtLink> for details.
## 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.

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

@ -28,7 +28,7 @@ To access it, click the down arrow button next to Project Name on the top left s
## Sync Metadata
Go to `Data Sources`, click ``Sync Metadata``, you can see your metadata sync status. If it is out of sync, you can sync the schema. See <a href="./sync-schema">Sync Schema</a> for more.0
Go to `Data Sources`, click ``Sync Metadata``, you can see your metadata sync status. If it is out of sync, you can sync the schema. See <NuxtLink to="/setup-and-usages/sync-schema">Sync Schema</NuxtLink> for more.
![image](https://user-images.githubusercontent.com/35857179/219833485-3bcaa6ec-88bc-47cc-b938-5abb4835dc31.png)

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

@ -155,7 +155,7 @@ You can use Quick Import when you have data from external sources such as Airtab
### Import Airtable into an Existing Project
- See <a href="./import-airtable-to-sql-database-within-a-minute-for-free">here</a>
- See <NuxtLink to="/setup-and-usages/import-airtable-to-sql-database-within-a-minute-for-free">here</NuxtLink>
### Import CSV data into an Existing Project
@ -165,7 +165,7 @@ You can use Quick Import when you have data from external sources such as Airtab
- **Use First Row as Headers**: If it is checked, the first row will be treated as header row.
- **Import Data**: If it is checked, all data will be imported. Otherwise, only table will be created.
![image](https://user-images.githubusercontent.com/35857179/197454479-1ed18dce-1d0b-4ee3-88b3-9b6a132dea2a.png)
- You can revise the table name by double clicking it, column name and column type. By default, the first column will be chosen as <a href="./display-value" target="_blank">Display Value</a> and cannot be deleted.
- You can revise the table name by double clicking it, column name and column type. By default, the first column will be chosen as <NuxtLink to="/setup-and-usages/display-value" target="_blank">Display Value</NuxtLink> and cannot be deleted.
![image](https://user-images.githubusercontent.com/35857179/197454633-5b30323e-2b13-4c55-843a-948c093d373e.png)
- Click `Import` to start importing process. The table will be created and the data will be imported.
![image](https://user-images.githubusercontent.com/35857179/197455547-2d93df5e-a7f0-4c88-af53-990067625967.png)
@ -178,7 +178,7 @@ You can use Quick Import when you have data from external sources such as Airtab
- **Use First Row as Headers**: If it is checked, the first row will be treated as header row.
- **Import Data**: If it is checked, all data will be imported. Otherwise, only table will be created.
![image](https://user-images.githubusercontent.com/35857179/197455788-8dd8a7d1-38f3-48c3-a05e-6ab0cf25045c.png)
- You can revise the table name, column name and column type. By default, the first column will be chosen as <a href="./display-value" target="_blank">Display Value</a> and cannot be deleted.
- You can revise the table name, column name and column type. By default, the first column will be chosen as <NuxtLink to="/setup-and-usages/display-value" target="_blank">Display Value</NuxtLink> and cannot be deleted.
<alert>
Note: If your Excel file contains multiple sheets, each sheet will be stored in a separate table.
</alert>

1
packages/nocodb/src/lib/controllers/publicControllers/publicData.ctl.ts

@ -31,6 +31,7 @@ async function dataInsert(req: Request & { files: any[] }, res: Response) {
password: req.headers?.['xc-password'] as string,
body: req.body?.data,
siteUrl: (req as any).ncSiteUrl,
// req.files is enriched by multer
files: req.files,
});

10
packages/nocodb/src/lib/db/sql-data-mapper/lib/sql/functionMappings/pg.ts

@ -157,11 +157,13 @@ const pg = {
builder: args.knex.raw(
`CASE WHEN ${args.knex
.raw(
`${args.pt.arguments
.map(async (ar) =>
(await args.fn(ar, '', 'OR')).builder.toQuery()
`${(
await Promise.all(
args.pt.arguments.map(async (ar) =>
(await args.fn(ar, '', 'OR')).builder.toQuery()
)
)
.join(' OR ')}`
).join(' OR ')}`
)
.wrap('(', ')')
.toQuery()} THEN TRUE ELSE FALSE END ${args.colAlias}`

4
packages/nocodb/src/lib/services/attachment.svc.ts

@ -30,8 +30,8 @@ export async function upload(param: {
// if `url` is null, then it is local attachment
if (!url) {
// then store the attachement path only
// url will be constructued in `useAttachmentCell`
// then store the attachment path only
// url will be constructed in `useAttachmentCell`
attachmentPath = `download/${filePath.join('/')}/${fileName}`;
}

17
packages/nocodb/src/lib/services/public/publicData.svc.ts

@ -235,7 +235,7 @@ export async function dataInsert(param: {
const fieldName = file?.fieldname?.replace(/^_|\[\d*]$/g, '');
const filePath = sanitizeUrlPath([
'v1',
'noco',
project.title,
model.title,
fieldName,
@ -243,18 +243,25 @@ export async function dataInsert(param: {
if (fieldName in fields && fields[fieldName].uidt === UITypes.Attachment) {
attachments[fieldName] = attachments[fieldName] || [];
const fileName = `${nanoid(6)}_${file.originalname}`;
let url = await storageAdapter.fileCreate(
const fileName = `${nanoid(18)}${path.extname(file.originalname)}`;
const url = await storageAdapter.fileCreate(
slash(path.join('nc', 'uploads', ...filePath, fileName)),
file
);
let attachmentPath;
// if `url` is null, then it is local attachment
if (!url) {
url = `${param.siteUrl}/download/${filePath.join('/')}/${fileName}`;
// then store the attachment path only
// url will be constructed in `useAttachmentCell`
attachmentPath = `download/${filePath.join('/')}/${fileName}`;
}
attachments[fieldName].push({
url,
...(url ? { url } : {}),
...(attachmentPath ? { path: attachmentPath } : {}),
title: file.originalname,
mimetype: file.mimetype,
size: file.size,

15
packages/nocodb/src/schema/swagger.json

@ -10886,20 +10886,7 @@
},
"requestBody": {
"content": {
"application/json": {
"schema": {
"type": "object",
"description": "Data Object where the key is column and the value is the data value"
},
"examples": {
"Example 1": {
"value": {
"col1": "foo",
"col2": "bar"
}
}
}
}
"multipart/form-data": {}
},
"description": ""
},

12
tests/playwright/tests/columnFormula.spec.ts

@ -122,6 +122,18 @@ const formulaDataByDbType = (context: NcContext) => [
formula: `NOW()`,
result: ['1', '1', '1', '1', '1'],
},
{
formula: `OR(true, false)`,
result: isPg(context) ? ['true', 'true', 'true', 'true', 'true'] : ['1', '1', '1', '1', '1'],
},
{
formula: `AND(false, false)`,
result: isPg(context) ? ['false', 'false', 'false', 'false', 'false'] : ['0', '0', '0', '0', '0'],
},
{
formula: `IF((SEARCH({Address List}, "Parkway") != 0), "2.0","WRONG")`,
result: ['WRONG', 'WRONG', 'WRONG', '2.0', '2.0'],
},
];
test.describe('Virtual Columns', () => {

Loading…
Cancel
Save