Browse Source

Merge pull request #3589 from nocodb/develop

pull/3590/head
github-actions[bot] 2 years ago committed by GitHub
parent
commit
3a0b3ab61d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      .all-contributorsrc
  2. 3
      README.md
  3. 2
      crowdin.yml
  4. 3
      packages/nc-gui/components/general/ShareBaseButton.vue
  5. 4
      packages/nc-gui/components/general/Sponsors.test.ts
  6. 17
      packages/nc-gui/components/smartsheet-column/LinkedToAnotherRecordOptions.vue
  7. 1
      packages/nc-gui/components/smartsheet-column/RollupOptions.vue
  8. 6
      packages/nc-gui/components/smartsheet-toolbar/LockType.vue
  9. 20
      packages/nc-gui/components/tabs/auth/ApiTokenManagement.vue
  10. 2
      packages/nc-gui/pages/signup/[[token]].vue
  11. 32
      packages/nc-gui/plugins/initializeFeedbackForm.ts
  12. 6
      packages/nocodb/src/lib/meta/api/utilApis.ts
  13. 2
      packages/nocodb/src/lib/utils/NcConfigFactory.ts
  14. 13
      scripts/sdk/swagger.json

9
.all-contributorsrc

@ -855,6 +855,15 @@
"contributions": [ "contributions": [
"code" "code"
] ]
},
{
"login": "asheerrizvi",
"name": "Asheer Rizvi",
"avatar_url": "https://avatars.githubusercontent.com/u/17976252?v=4",
"profile": "http://asheerrizvi.com",
"contributions": [
"code"
]
} }
], ],
"contributorsPerLine": 7, "contributorsPerLine": 7,

3
README.md

@ -330,6 +330,7 @@ Our mission is to provide the most powerful no-code interface for databases whic
<!-- prettier-ignore-start --> <!-- prettier-ignore-start -->
<!-- markdownlint-disable --> <!-- markdownlint-disable -->
<table> <table>
<tbody>
<tr> <tr>
<td align="center"><a href="https://github.com/o1lab"><img src="https://avatars.githubusercontent.com/u/5435402?v=4?s=100" width="100px;" alt=""/><br /><sub><b>o1lab</b></sub></a><br /><a href="https://github.com/nocodb/nocodb/commits?author=o1lab" title="Code">💻</a></td> <td align="center"><a href="https://github.com/o1lab"><img src="https://avatars.githubusercontent.com/u/5435402?v=4?s=100" width="100px;" alt=""/><br /><sub><b>o1lab</b></sub></a><br /><a href="https://github.com/nocodb/nocodb/commits?author=o1lab" title="Code">💻</a></td>
<td align="center"><a href="https://github.com/pranavxc"><img src="https://avatars.githubusercontent.com/u/61551451?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Pranav C</b></sub></a><br /><a href="https://github.com/nocodb/nocodb/commits?author=pranavxc" title="Code">💻</a></td> <td align="center"><a href="https://github.com/pranavxc"><img src="https://avatars.githubusercontent.com/u/61551451?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Pranav C</b></sub></a><br /><a href="https://github.com/nocodb/nocodb/commits?author=pranavxc" title="Code">💻</a></td>
@ -451,7 +452,9 @@ Our mission is to provide the most powerful no-code interface for databases whic
<td align="center"><a href="https://yohanboniface.me"><img src="https://avatars.githubusercontent.com/u/146023?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Yohan Boniface</b></sub></a><br /><a href="#translation-yohanboniface" title="Translation">🌍</a></td> <td align="center"><a href="https://yohanboniface.me"><img src="https://avatars.githubusercontent.com/u/146023?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Yohan Boniface</b></sub></a><br /><a href="#translation-yohanboniface" title="Translation">🌍</a></td>
<td align="center"><a href="https://github.com/drsantam"><img src="https://avatars.githubusercontent.com/u/10681456?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Santam Chakraborty</b></sub></a><br /><a href="#translation-drsantam" title="Translation">🌍</a></td> <td align="center"><a href="https://github.com/drsantam"><img src="https://avatars.githubusercontent.com/u/10681456?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Santam Chakraborty</b></sub></a><br /><a href="#translation-drsantam" title="Translation">🌍</a></td>
<td align="center"><a href="https://bandism.net/"><img src="https://avatars.githubusercontent.com/u/22633385?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ikko Ashimine</b></sub></a><br /><a href="https://github.com/nocodb/nocodb/commits?author=eltociear" title="Code">💻</a></td> <td align="center"><a href="https://bandism.net/"><img src="https://avatars.githubusercontent.com/u/22633385?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Ikko Ashimine</b></sub></a><br /><a href="https://github.com/nocodb/nocodb/commits?author=eltociear" title="Code">💻</a></td>
<td align="center"><a href="http://asheerrizvi.com"><img src="https://avatars.githubusercontent.com/u/17976252?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Asheer Rizvi</b></sub></a><br /><a href="https://github.com/nocodb/nocodb/commits?author=asheerrizvi" title="Code">💻</a></td>
</tr> </tr>
</tbody>
</table> </table>
<!-- markdownlint-restore --> <!-- markdownlint-restore -->

2
crowdin.yml

@ -1,3 +1,3 @@
files: files:
- source: /packages/nc-gui/lang/en.json - source: /packages/nc-gui/lang/en.json
translation: /packages/nc-gui/lang/%two_letters_code%.json translation: /packages/nc-gui/lang/%osx_locale%.json

3
packages/nc-gui/components/general/ShareBaseButton.vue

@ -9,7 +9,7 @@ const { isUIAllowed } = useUIPermission()
</script> </script>
<template> <template>
<div class="flex items-center w-full pl-3 hover:(text-primary bg-primary bg-opacity-5)"> <div class="flex items-center w-full pl-3 hover:(text-primary bg-primary bg-opacity-5)" @click="showUserModal = true">
<div <div
v-if=" v-if="
isUIAllowed('newUser') && isUIAllowed('newUser') &&
@ -18,7 +18,6 @@ const { isUIAllowed } = useUIPermission()
route.name !== 'index-index-create-external' && route.name !== 'index-index-create-external' &&
route.name !== 'index-user-index' route.name !== 'index-user-index'
" "
@click="showUserModal = true"
> >
<div class="flex items-center space-x-1"> <div class="flex items-center space-x-1">
<MdiAccountPlusOutline class="mr-1 nc-share-base" /> <MdiAccountPlusOutline class="mr-1 nc-share-base" />

4
packages/nc-gui/components/general/Sponsors.test.ts

@ -1,16 +1,14 @@
import { mount } from '@vue/test-utils' import { mount } from '@vue/test-utils'
import { expect, test } from 'vitest' import { expect, test } from 'vitest'
import Sponsors from './Sponsors.vue' import Sponsors from './Sponsors.vue'
import { createVuetifyPlugin } from '~/plugins/vuetify'
import { createI18nPlugin } from '~/plugins/a.i18n' import { createI18nPlugin } from '~/plugins/a.i18n'
const mountComponent = async (nav: boolean) => { const mountComponent = async (nav: boolean) => {
const vuetify = createVuetifyPlugin()
const i18n = await createI18nPlugin() const i18n = await createI18nPlugin()
const wrapper = mount(Sponsors, { const wrapper = mount(Sponsors, {
global: { global: {
plugins: [vuetify, i18n], plugins: [i18n],
}, },
props: { props: {
nav, nav,

17
packages/nc-gui/components/smartsheet-column/LinkedToAnotherRecordOptions.vue

@ -52,15 +52,24 @@ const refTables = $computed(() => {
<template> <template>
<div class="w-full flex flex-col mb-2 mt-4"> <div class="w-full flex flex-col mb-2 mt-4">
<div class="border-2 p-6"> <div class="border-2 p-6">
<a-form-item v-bind="validateInfos.type"> <a-form-item v-bind="validateInfos.type" class="nc-ltar-relation-type">
<a-radio-group v-model:value="vModel.type" name="type" v-bind="validateInfos.type"> <a-radio-group v-model:value="vModel.type" name="type" v-bind="validateInfos.type">
<a-radio value="hm">Has Many</a-radio> <a-radio value="hm">Has Many</a-radio>
<a-radio value="mm">Many To Many</a-radio> <a-radio value="mm">Many To Many</a-radio>
</a-radio-group> </a-radio-group>
</a-form-item> </a-form-item>
<a-form-item class="flex w-full pb-2 mt-4" :label="$t('labels.childTable')" v-bind="validateInfos.childId"> <a-form-item
<a-select v-model:value="vModel.childId" @change="onDataTypeChange"> class="flex w-full pb-2 mt-4 nc-ltar-child-table"
<a-select-option v-for="(table, index) in refTables" :key="index" :value="table.id"> :label="$t('labels.childTable')"
v-bind="validateInfos.childId"
>
<a-select
v-model:value="vModel.childId"
show-search
:filter-option="(value, option) => option.key.toLowerCase().includes(value.toLowerCase())"
@change="onDataTypeChange"
>
<a-select-option v-for="table in refTables" :key="table.title" :value="table.id">
{{ table.title }} {{ table.title }}
</a-select-option> </a-select-option>
</a-select> </a-select>

1
packages/nc-gui/components/smartsheet-column/RollupOptions.vue

@ -35,7 +35,6 @@ const aggrFunctionsList = [
{ text: 'min', value: 'min' }, { text: 'min', value: 'min' },
{ text: 'max', value: 'max' }, { text: 'max', value: 'max' },
{ text: 'avg', value: 'avg' }, { text: 'avg', value: 'avg' },
{ text: 'min', value: 'min' },
{ text: 'sum', value: 'sum' }, { text: 'sum', value: 'sum' },
{ text: 'countDistinct', value: 'countDistinct' }, { text: 'countDistinct', value: 'countDistinct' },
{ text: 'sumDistinct', value: 'sumDistinct' }, { text: 'sumDistinct', value: 'sumDistinct' },

6
packages/nc-gui/components/smartsheet-toolbar/LockType.vue

@ -13,17 +13,17 @@ const types = {
[LockType.Personal]: { [LockType.Personal]: {
title: 'title.personalView', title: 'title.personalView',
icon: MdiAccountIcon, icon: MdiAccountIcon,
subtitle: 'msg.info.collabView', subtitle: 'msg.info.personalView',
}, },
[LockType.Collaborative]: { [LockType.Collaborative]: {
title: 'title.collabView', title: 'title.collabView',
icon: MdiAccountGroupIcon, icon: MdiAccountGroupIcon,
subtitle: 'msg.info.lockedView', subtitle: 'msg.info.collabView',
}, },
[LockType.Locked]: { [LockType.Locked]: {
title: 'title.lockedView', title: 'title.lockedView',
icon: MdiLockOutlineIcon, icon: MdiLockOutlineIcon,
subtitle: 'msg.info.personalView', subtitle: 'msg.info.lockedView',
}, },
} }

20
packages/nc-gui/components/tabs/auth/ApiTokenManagement.vue

@ -106,17 +106,29 @@ onMounted(() => {
</template> </template>
</a-button> </a-button>
<!-- Generate Token --> <!-- Generate Token -->
<div class="flex flex-row justify-center w-full -mt-1"> <div class="flex flex-row justify-center w-full -mt-1 mb-3">
<a-typography-title :level="5">{{ $t('title.generateToken') }}</a-typography-title> <a-typography-title :level="5">{{ $t('title.generateToken') }}</a-typography-title>
</div> </div>
<!-- Description --> <!-- Description -->
<div class="flex flex-col mt-3 justify-center space-y-6"> <a-form
ref="form"
:model="selectedTokenData"
name="basic"
layout="vertical"
class="flex flex-col justify-center space-y-6"
no-style
autocomplete="off"
@finish="generateToken"
>
<a-input v-model:value="selectedTokenData.description" :placeholder="$t('labels.description')" /> <a-input v-model:value="selectedTokenData.description" :placeholder="$t('labels.description')" />
<!-- Generate --> <!-- Generate -->
<div class="flex flex-row justify-center"> <div class="flex flex-row justify-center">
<a-button type="primary" @click="generateToken"> {{ $t('general.generate') }} </a-button> <a-button type="primary" html-type="submit">
</div> {{ $t('general.generate') }}
</a-button>
</div> </div>
</a-form>
</div> </div>
</a-modal> </a-modal>
<a-modal v-model:visible="showDeleteTokenModal" :closable="false" width="28rem" centered :footer="null"> <a-modal v-model:visible="showDeleteTokenModal" :closable="false" width="28rem" centered :footer="null">

2
packages/nc-gui/pages/signup/[[token]].vue

@ -113,7 +113,7 @@ function resetError() {
{{ $route.query.redirect_to === '/pricing' ? '& BUY' : '' }} {{ $route.query.redirect_to === '/pricing' ? '& BUY' : '' }}
</h1> </h1>
<h2 v-if="appInfo.firstUser" class="prose !text-primary font-semibold self-center my-4"> <h2 v-if="appInfo.firstUser" class="prose !text-primary font-semibold self-center">
{{ $t('msg.info.signUp.superAdmin') }} {{ $t('msg.info.signUp.superAdmin') }}
</h2> </h2>

32
packages/nc-gui/plugins/initializeFeedbackForm.ts

@ -1,4 +1,3 @@
import type { Dayjs } from 'dayjs'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { defineNuxtPlugin } from '#app' import { defineNuxtPlugin } from '#app'
@ -8,9 +7,18 @@ const handleFeedbackForm = async () => {
const { $api } = useNuxtApp() const { $api } = useNuxtApp()
const fetchFeedbackForm = async (now: Dayjs) => { const isFirstTimePolling = !currentFeedbackForm.lastFormPollDate
const now = dayjs()
const lastFormPolledDate = dayjs(currentFeedbackForm.lastFormPollDate)
if (isFirstTimePolling || dayjs.duration(now.diff(lastFormPolledDate)).days() > 0) {
$api.instance
.get('/api/v1/feedback_form')
.then((response) => {
try { try {
const { data: feedbackForm } = await $api.instance.get('/api/v1/feedback_form') const { data: feedbackForm } = response
if (!feedbackForm.error) {
const isFetchedFormDuplicate = currentFeedbackForm.url === feedbackForm.url const isFetchedFormDuplicate = currentFeedbackForm.url === feedbackForm.url
currentFeedbackForm = { currentFeedbackForm = {
@ -19,21 +27,13 @@ const handleFeedbackForm = async () => {
createdAt: feedbackForm.created_at, createdAt: feedbackForm.created_at,
isHidden: isFetchedFormDuplicate ? currentFeedbackForm.isHidden : false, isHidden: isFetchedFormDuplicate ? currentFeedbackForm.isHidden : false,
} }
} catch (e) {
console.error(e)
}
} }
} catch (e) {}
const isFirstTimePolling = !currentFeedbackForm.lastFormPollDate })
.catch(() => {})
const now = dayjs()
const lastFormPolledDate = dayjs(currentFeedbackForm.lastFormPollDate)
if (isFirstTimePolling || dayjs.duration(now.diff(lastFormPolledDate)).days() > 0) {
await fetchFeedbackForm(now)
} }
} }
export default defineNuxtPlugin(async () => { export default defineNuxtPlugin(() => {
await handleFeedbackForm() handleFeedbackForm()
}) })

6
packages/nocodb/src/lib/meta/api/utilApis.ts

@ -82,12 +82,14 @@ export async function versionInfo(_req: Request, res: Response) {
export async function feedbackFormGet(_req: Request, res: Response) { export async function feedbackFormGet(_req: Request, res: Response) {
axios axios
.get('https://nocodb.com/api/v1/feedback_form') .get('https://nocodb.com/api/v1/feedback_form', {
timeout: 5000,
})
.then((response) => { .then((response) => {
res.json(response.data); res.json(response.data);
}) })
.catch((e) => { .catch((e) => {
res.status(500).json({ error: e.message }); res.json({ error: e.message });
}); });
} }

2
packages/nocodb/src/lib/utils/NcConfigFactory.ts

@ -214,6 +214,7 @@ export default class NcConfigFactory implements NcConfig {
...defaultConnectionConfig, ...defaultConnectionConfig,
...parsedQuery, ...parsedQuery,
host: url.hostname, host: url.hostname,
port: +url.port,
}, },
// pool: { // pool: {
// min: 1, // min: 1,
@ -325,6 +326,7 @@ export default class NcConfigFactory implements NcConfig {
...defaultConnectionConfig, ...defaultConnectionConfig,
...parsedQuery, ...parsedQuery,
host: url.hostname, host: url.hostname,
port: +url.port,
}, },
acquireConnectionTimeout: 600000, acquireConnectionTimeout: 600000,
...(url.searchParams.has('search_path') ...(url.searchParams.has('search_path')

13
scripts/sdk/swagger.json

@ -5821,9 +5821,6 @@
"pageInfo": { "pageInfo": {
"$ref": "#/components/schemas/Paginated" "$ref": "#/components/schemas/Paginated"
} }
},
"": {
"type": "string"
} }
}, },
"Base": { "Base": {
@ -6148,8 +6145,7 @@
"type": "string" "type": "string"
}, },
"title": { "title": {
"type": "string", "type": "string"
"required": true
}, },
"deleted": { "deleted": {
"type": "boolean" "type": "boolean"
@ -6193,7 +6189,8 @@
} }
] ]
} }
} },
"required": ["title"]
}, },
"TableInfo": { "TableInfo": {
"title": "Table", "title": "Table",
@ -6981,10 +6978,12 @@
"properties": { "properties": {
"options": { "options": {
"type": "array", "type": "array",
"required": true,
"$ref": "#/components/schemas/SelectOption" "$ref": "#/components/schemas/SelectOption"
} }
}, },
"required": [
"options"
],
"examples": [ "examples": [
{ {
"options": [ "options": [

Loading…
Cancel
Save