diff --git a/.github/workflows/publish-api-docs.yml b/.github/workflows/publish-api-docs.yml
index 496d1e5952..89470ae73a 100644
--- a/.github/workflows/publish-api-docs.yml
+++ b/.github/workflows/publish-api-docs.yml
@@ -35,7 +35,7 @@ jobs:
env:
API_TOKEN_GITHUB: ${{ secrets.GH_TOKEN }}
with:
- source_file: 'packages/nocodb/src/schema/swagger.json'
+ source_file: 'packages/nocodb/src/schema/swagger-v2.json'
destination_repo: 'nocodb/noco-apis-doc'
destination_folder: 'data-apis-v2'
user_email: 'oof1lab@gmail.com'
@@ -53,3 +53,15 @@ jobs:
user_email: 'oof1lab@gmail.com'
user_name: 'o1lab'
commit_message: 'Autorelease from github.com/nocodb/nocodb'
+
+ - name: Pushes swagger file to meta-apis-v2
+ uses: dmnemec/copy_file_to_another_repo_action@1b29cbd9a323185f20b175dc6d5f8f31be5c0658
+ env:
+ API_TOKEN_GITHUB: ${{ secrets.GH_TOKEN }}
+ with:
+ source_file: 'packages/nocodb/src/schema/swagger-v2.json'
+ destination_repo: 'nocodb/noco-apis-doc'
+ destination_folder: 'meta-apis-v2'
+ user_email: 'oof1lab@gmail.com'
+ user_name: 'o1lab'
+ commit_message: 'Autorelease from github.com/nocodb/nocodb'
diff --git a/.github/workflows/release-docker.yml b/.github/workflows/release-docker.yml
index efac03f6ff..bf8ccc2322 100644
--- a/.github/workflows/release-docker.yml
+++ b/.github/workflows/release-docker.yml
@@ -90,10 +90,7 @@ jobs:
if: ${{ github.event.inputs.targetEnv == 'DEV' || inputs.targetEnv == 'DEV' }}
run: |
export NODE_OPTIONS="--max_old_space_size=16384"
- NOCODB_SDK_PKG_NAME=nocodb-sdk
- if [[ "${{ github.event.inputs.targetEnv == 'DEV' || inputs.targetEnv == 'DEV' }}" ]]; then
- NOCODB_SDK_PKG_NAME=nocodb-sdk-daily
- fi
+ NOCODB_SDK_PKG_NAME=nocodb-sdk-daily
targetEnv=${{ github.event.inputs.targetEnv || inputs.targetEnv }} targetVersion=${{ github.event.inputs.tag || inputs.tag }} node scripts/bumpNocodbSdkVersion.js &&
pnpm --filter=${NOCODB_SDK_PKG_NAME} install --ignore-scripts --no-frozen-lockfile && pnpm --filter=${NOCODB_SDK_PKG_NAME} run build &&
targetEnv=${{ github.event.inputs.targetEnv || inputs.targetEnv }} node scripts/upgradeNocodbSdk.js &&
@@ -104,6 +101,7 @@ jobs:
- name: Build nocodb and docker files
run: |
+ pnpm install --ignore-scripts --no-frozen-lockfile
pnpm run docker:build
working-directory: ${{ env.working-directory }}
diff --git a/.github/workflows/release-npm.yml b/.github/workflows/release-npm.yml
index fff4f57678..d2b25a696c 100644
--- a/.github/workflows/release-npm.yml
+++ b/.github/workflows/release-npm.yml
@@ -55,9 +55,11 @@ jobs:
- run: |
export NODE_OPTIONS="--max_old_space_size=16384"
NOCODB_SDK_PKG_NAME=nocodb-sdk
- if [[ "${{ github.event.inputs.targetEnv == 'DEV' || inputs.targetEnv == 'DEV' }}" ]]; then
+ # If targetEnv is DEV, then use nocodb-sdk-daily package
+ if [[ ${{ github.event.inputs.targetEnv || inputs.targetEnv }} == 'DEV' ]]; then
NOCODB_SDK_PKG_NAME=nocodb-sdk-daily
fi
+ echo $NOCODB_SDK_PKG_NAME
targetEnv=${{ github.event.inputs.targetEnv || inputs.targetEnv }} targetVersion=${{ github.event.inputs.tag || inputs.tag }} node scripts/bumpNocodbSdkVersion.js &&
pnpm --filter=${NOCODB_SDK_PKG_NAME} install --ignore-scripts --no-frozen-lockfile && pnpm --filter=${NOCODB_SDK_PKG_NAME} run build && pnpm --filter=${NOCODB_SDK_PKG_NAME} publish --no-git-checks &&
sleep 90 &&
diff --git a/README.md b/README.md
index 844253d45e..6ac3a9a388 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@ Turns any MySQL, PostgreSQL, SQL Server, SQLite & MariaDB into a smart spreadshe
-
+
[![Node version](https://img.shields.io/badge/node-%3E%3D%2018.14.0-brightgreen)](http://nodejs.org/download/)
[![Conventional Commits](https://img.shields.io/badge/Conventional%20Commits-1.0.0-green.svg)](https://conventionalcommits.org)
@@ -210,22 +210,22 @@ Access Dashboard using: [http://localhost:8080/dashboard](http://localhost:8080/
# Table of Contents
- [Quick try](#quick-try)
- - [NPX](#npx)
- - [Node Application](#node-application)
- - [Docker](#docker)
- - [Docker Compose](#docker-compose)
+ - [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 Access](#programmatic-access)
- - [Sync Schema](#sync-schema)
- - [Audit](#audit)
+ - [Rich Spreadsheet Interface](#rich-spreadsheet-interface)
+ - [App Store for Workflow Automations](#app-store-for-workflow-automations)
+ - [Programmatic Access](#programmatic-access)
+ - [Sync Schema](#sync-schema)
+ - [Audit](#audit)
- [Production Setup](#production-setup)
- - [Environment variables](#environment-variables)
+ - [Environment variables](#environment-variables)
- [Development Setup](#development-setup)
- [Contributing](#contributing)
- [Why are we building this?](#why-are-we-building-this)
@@ -305,4 +305,4 @@ Thank you for your contributions! We appreciate all the contributions from the c
-
+
\ No newline at end of file
diff --git a/docker-compose/sqlite/nocodb/noco.db b/docker-compose/sqlite/nocodb/noco.db
new file mode 100644
index 0000000000..3283348219
Binary files /dev/null and b/docker-compose/sqlite/nocodb/noco.db differ
diff --git a/packages/nc-gui/assets/style.scss b/packages/nc-gui/assets/style.scss
index cbeb575b6e..c317f29f0c 100644
--- a/packages/nc-gui/assets/style.scss
+++ b/packages/nc-gui/assets/style.scss
@@ -603,7 +603,7 @@ input[type='number'] {
}
.nc-sidebar-node {
- @apply !xs:(min-h-12 max-h-12 hover:bg-gray-50 ml-1.5);
+ @apply !xs:(min-h-12 max-h-12 hover:bg-gray-50 ml-1.5 w-[calc(100%-8px)]);
.nc-emoji {
@apply xs:(text-lg);
diff --git a/packages/nc-gui/assets/style/fonts.css b/packages/nc-gui/assets/style/fonts.css
index 1040373031..3ea76e9a67 100644
--- a/packages/nc-gui/assets/style/fonts.css
+++ b/packages/nc-gui/assets/style/fonts.css
@@ -2,6 +2,7 @@
@font-face {
font-display: swap; /* Check https://developer.mozilla.org/en-US/docs/Web/CSS/@font-face/font-display for other options. */
font-family: 'Manrope';
+ font-weight: 450 900;
src: url('./manrope/Manrope-VariableFont_wght.ttf') format('truetype')
}
diff --git a/packages/nc-gui/components.d.ts b/packages/nc-gui/components.d.ts
index 28575de95a..57affe1553 100644
--- a/packages/nc-gui/components.d.ts
+++ b/packages/nc-gui/components.d.ts
@@ -150,7 +150,6 @@ declare module '@vue/runtime-core' {
MdiReload: typeof import('~icons/mdi/reload')['default']
MdiRocketLaunchOutline: typeof import('~icons/mdi/rocket-launch-outline')['default']
MdiScriptTextOutline: typeof import('~icons/mdi/script-text-outline')['default']
- MdiShieldKeyOutline: typeof import('~icons/mdi/shield-key-outline')['default']
MdiSlack: typeof import('~icons/mdi/slack')['default']
MdiStar: typeof import('~icons/mdi/star')['default']
MdiStarOutline: typeof import('~icons/mdi/star-outline')['default']
diff --git a/packages/nc-gui/components/cell/Checkbox.vue b/packages/nc-gui/components/cell/Checkbox.vue
index edf550808b..be70d8d314 100644
--- a/packages/nc-gui/components/cell/Checkbox.vue
+++ b/packages/nc-gui/components/cell/Checkbox.vue
@@ -91,7 +91,11 @@ useSelectedCellKeyupListener(active, (e) => {
}"
@click="onClick(false, $event)"
>
-
+
| undefined>({
get: () => localValueState.value,
set: (val: undefined | string | Record) => {
@@ -140,6 +143,13 @@ useSelectedCellKeyupListener(active, (e) => {
}
})
+const inputWrapperRef = ref(null)
+
+onClickOutside(inputWrapperRef, (e) => {
+ if ((e.target as HTMLElement)?.closest('.nc-json-action')) return
+ editEnabled.value = false
+})
+
watch(isExpanded, () => {
_isExpanded.value = isExpanded.value
})
@@ -148,7 +158,7 @@ watch(isExpanded, () => {
-
+
@@ -167,6 +177,7 @@ watch(isExpanded, () => {
{
{{ $t('general.null') }}
- {{ vModel }}
+
diff --git a/packages/nc-gui/components/cell/MultiSelect.vue b/packages/nc-gui/components/cell/MultiSelect.vue
index 3a9d02aba9..7a64c35a1a 100644
--- a/packages/nc-gui/components/cell/MultiSelect.vue
+++ b/packages/nc-gui/components/cell/MultiSelect.vue
@@ -43,6 +43,8 @@ const { modelValue, disableOptionCreation } = defineProps()
const emit = defineEmits(['update:modelValue'])
+const { isMobileMode } = useGlobal()
+
const column = inject(ColumnInj)!
const readOnly = inject(ReadonlyInj)!
@@ -383,7 +385,7 @@ const selectedOpts = computed(() => {
:placeholder="isEditColumn ? $t('labels.optional') : ''"
:bordered="false"
clear-icon
- show-search
+ :show-search="!isMobileMode"
:show-arrow="editAllowed && !(readOnly || isLockedMode)"
:open="isOpen && editAllowed"
:disabled="readOnly || !editAllowed || isLockedMode"
@@ -392,6 +394,9 @@ const selectedOpts = computed(() => {
@search="search"
@keydown.stop
>
+
+
+
()
const emit = defineEmits(['update:modelValue'])
+const { isMobileMode } = useGlobal()
+
const column = inject(ColumnInj)!
const readOnly = inject(ReadonlyInj)!
@@ -202,6 +204,8 @@ async function addIfMissingAndSave() {
}
const search = () => {
+ if (isMobileMode.value) return
+
searchVal.value = aselect.value?.$el?.querySelector('.ant-select-selection-search-input')?.value
}
@@ -285,7 +289,7 @@ const selectedOpt = computed(() => {
v-else
ref="aselect"
v-model:value="vModel"
- class="w-full overflow-hidden"
+ class="w-full overflow-hidden xs:min-h-12"
:class="{ 'caret-transparent': !hasEditRoles }"
:placeholder="isEditColumn ? $t('labels.optional') : ''"
:allow-clear="!column.rqd && editAllowed"
@@ -294,7 +298,7 @@ const selectedOpt = computed(() => {
:disabled="readOnly || !editAllowed || isLockedMode"
:show-arrow="hasEditRoles && !(readOnly || isLockedMode) && active && vModel === null"
:dropdown-class-name="`nc-dropdown-single-select-cell ${isOpen && active ? 'active' : ''}`"
- :show-search="isOpen && active"
+ :show-search="!isMobileMode && isOpen && active"
@select="onSelect"
@keydown="onKeydown($event)"
@search="search"
diff --git a/packages/nc-gui/components/cell/attachment/Carousel.vue b/packages/nc-gui/components/cell/attachment/Carousel.vue
index 55c4f8a48e..e42eba2bfb 100644
--- a/packages/nc-gui/components/cell/attachment/Carousel.vue
+++ b/packages/nc-gui/components/cell/attachment/Carousel.vue
@@ -55,7 +55,7 @@ useEventListener(container, 'click', (e) => {
-
+
{
const rowHeight = inject(RowHeightInj, ref())
-const open = () => {
- if (isMobileMode.value) return (isExpandedForm.value = true)
+const open = (e: Event) => {
+ e.stopPropagation()
_open()
}
const openAttachment = (item: any) => {
- if (isMobileMode.value) return
+ if (isMobileMode.value && !isExpandedForm.value) {
+ isExpandedForm.value = true
+
+ return
+ }
_openAttachment(item)
}
@@ -169,6 +173,14 @@ const onExpand = () => {
modalVisible.value = true
}
+
+const onImageClick = (item: any) => {
+ if (isMobileMode.value && !isExpandedForm.value) return
+
+ if (!isMobileMode.value && (isGallery.value || (isKanban.value && !isExpandedForm.value))) return
+
+ selectedImage.value = item
+}
@@ -178,7 +190,7 @@ const onExpand = () => {
:style="{
height: isForm || isExpandedForm ? undefined : `max(${(rowHeight || 1) * 1.8}rem, 41px)`,
}"
- class="nc-attachment-cell relative flex color-transition flex items-center w-full"
+ class="nc-attachment-cell relative flex color-transition flex items-center w-full xs:(min-h-12 max-h-32)"
:class="{ 'justify-center': !active, 'justify-between': active }"
>
@@ -198,26 +210,29 @@ const onExpand = () => {
-
+
{{ $t('activity.attachmentDrop') }}
-
+
{{ $t('activity.addFiles') }}
@@ -245,12 +260,7 @@ const onExpand = () => {
{
- if (isGallery || isMobileMode || (isKanban && !isExpandedForm)) return
- selectedImage = item
- }
- "
+ @click="() => onImageClick(item)"
>
{
diff --git a/packages/nc-gui/components/dashboard/Sidebar.vue b/packages/nc-gui/components/dashboard/Sidebar.vue
index e3e46b432e..2b2c9a6551 100644
--- a/packages/nc-gui/components/dashboard/Sidebar.vue
+++ b/packages/nc-gui/components/dashboard/Sidebar.vue
@@ -47,14 +47,14 @@ onUnmounted(() => {
-
+
diff --git a/packages/nc-gui/components/dashboard/TreeView/ProjectNode.vue b/packages/nc-gui/components/dashboard/TreeView/ProjectNode.vue
index 5ca70d8f5b..49bb750e80 100644
--- a/packages/nc-gui/components/dashboard/TreeView/ProjectNode.vue
+++ b/packages/nc-gui/components/dashboard/TreeView/ProjectNode.vue
@@ -57,7 +57,7 @@ const basesStore = useBases()
const { isMobileMode } = useGlobal()
-const { loadProjects, createProject: _createProject, updateProject, getProjectMetaInfo } = basesStore
+const { createProject: _createProject, updateProject, getProjectMetaInfo } = basesStore
const { bases } = storeToRefs(basesStore)
@@ -65,7 +65,7 @@ const { loadProjectTables } = useTablesStore()
const { activeTable } = storeToRefs(useTablesStore())
-const { appInfo, navigateToProject } = useGlobal()
+const { appInfo } = useGlobal()
const { orgRoles, isUIAllowed } = useRoles()
@@ -351,46 +351,6 @@ const duplicateProject = (base: BaseType) => {
selectedProjectToDuplicate.value = base
isDuplicateDlgOpen.value = true
}
-const { $poller } = useNuxtApp()
-
-const DlgProjectDuplicateOnOk = async (jobData: { id: string; base_id: string }) => {
- await loadProjects('workspace')
-
- $poller.subscribe(
- { id: jobData.id },
- async (data: {
- id: string
- status?: string
- data?: {
- error?: {
- message: string
- }
- message?: string
- result?: any
- }
- }) => {
- if (data.status !== 'close') {
- if (data.status === JobStatus.COMPLETED) {
- await loadProjects('workspace')
-
- const base = bases.value.get(jobData.base_id)
-
- // open base after duplication
- if (base) {
- await navigateToProject({
- baseId: base.id,
- type: base.type,
- })
- }
- } else if (data.status === JobStatus.FAILED) {
- message.error('Failed to duplicate base')
- await loadProjects('workspace')
- }
- }
- },
- )
- $e('a:base:duplicate')
-}
const tableDelete = () => {
isTableDeleteDialogVisible.value = true
@@ -477,7 +437,7 @@ const projectDelete = () => {
-
+