diff --git a/.github/workflows/release-nightly-dev.yml b/.github/workflows/release-nightly-dev.yml index 3a4f780804..30bd16e41e 100644 --- a/.github/workflows/release-nightly-dev.yml +++ b/.github/workflows/release-nightly-dev.yml @@ -12,6 +12,11 @@ jobs: set-tag: runs-on: 'ubuntu-latest' steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 1 + ref: ${{ github.ref }} - name: set-tag id: tag-step run: | @@ -21,7 +26,7 @@ jobs: TAG_NAME=${CURRENT_DATE}-${CURRENT_TIME} IS_DAILY='Y' # Get current version - CURRENT_VERSION=$(curl -fs https://docs.nocodb.com/releases | grep article | grep div | grep h2 | grep 'id\="[^"]*' -o | cut -c 5-) + CURRENT_VERSION=$(cat ./packages/nocodb/package.json | jq -r ".version") # Set the tag if [[ ${{ github.event_name }} == 'workflow_dispatch' ]]; then IS_DAILY='N' diff --git a/packages/nc-gui/components/shared-view/Grid.vue b/packages/nc-gui/components/shared-view/Grid.vue index 03d7068f51..b0bc8a6079 100644 --- a/packages/nc-gui/components/shared-view/Grid.vue +++ b/packages/nc-gui/components/shared-view/Grid.vue @@ -23,7 +23,7 @@ const { signedIn } = useGlobal() const { loadProject } = useProject() -useProvideSmartsheetStore(sharedView, meta, true, sorts, nestedFilters) +const { isLocked } = useProvideSmartsheetStore(sharedView, meta, true, sorts, nestedFilters) const reloadEventHook = createEventHook() @@ -33,6 +33,7 @@ provide(MetaInj, meta) provide(ActiveViewInj, sharedView) provide(FieldsInj, ref(meta.value?.columns || [])) provide(IsPublicInj, ref(true)) +provide(IsLockedInj, isLocked) if (signedIn.value) { try { diff --git a/packages/nc-gui/components/smartsheet/toolbar/FieldsMenu.vue b/packages/nc-gui/components/smartsheet/toolbar/FieldsMenu.vue index d2b6eda8cb..ca6a110f90 100644 --- a/packages/nc-gui/components/smartsheet/toolbar/FieldsMenu.vue +++ b/packages/nc-gui/components/smartsheet/toolbar/FieldsMenu.vue @@ -27,7 +27,7 @@ const activeView = inject(ActiveViewInj, ref()) const reloadDataHook = inject(ReloadViewDataHookInj)! -const reloadViewMetaHook = inject(ReloadViewMetaHookInj)! +const reloadViewMetaHook = inject(ReloadViewMetaHookInj, undefined)! const rootFields = inject(FieldsInj) @@ -84,11 +84,31 @@ const onMove = (_event: { moved: { newIndex: number } }) => { $e('a:fields:reorder') } +const coverOptions = computed(() => { + const filterFields = + fields.value + ?.filter((el) => el.fk_column_id && metaColumnById.value[el.fk_column_id].uidt === UITypes.Attachment) + .map((field) => { + return { + value: field.fk_column_id, + label: field.title, + } + }) ?? [] + return [{ value: null, label: 'No Image' }, ...filterFields] +}) + const coverImageColumnId = computed({ - get: () => - (activeView.value?.type === ViewTypes.GALLERY || activeView.value?.type === ViewTypes.KANBAN) && activeView.value?.view - ? (activeView.value?.view as GalleryType).fk_cover_image_col_id - : undefined, + get: () => { + const fk_cover_image_col_id = + (activeView.value?.type === ViewTypes.GALLERY || activeView.value?.type === ViewTypes.KANBAN) && activeView.value?.view + ? (activeView.value?.view as GalleryType).fk_cover_image_col_id + : undefined + // check if `fk_cover_image_col_id` is in `coverOptions` + // e.g. in share view, users may not share the cover image column + if (coverOptions.value?.find((o) => o.value === fk_cover_image_col_id)) return fk_cover_image_col_id + // set to `No Image` + return null + }, set: async (val) => { if ( (activeView.value?.type === ViewTypes.GALLERY || activeView.value?.type === ViewTypes.KANBAN) && @@ -108,24 +128,11 @@ const coverImageColumnId = computed({ }) ;(activeView.value.view as KanbanType).fk_cover_image_col_id = val } - reloadViewMetaHook.trigger() + reloadViewMetaHook?.trigger() } }, }) -const coverOptions = computed(() => { - const filterFields = - fields.value - ?.filter((el) => el.fk_column_id && metaColumnById.value[el.fk_column_id].uidt === UITypes.Attachment) - .map((field) => { - return { - value: field.fk_column_id, - label: field.title, - } - }) ?? [] - return [{ value: null, label: 'No Image' }, ...filterFields] -}) - const getIcon = (c: ColumnType) => h(isVirtualCol(c) ? resolveComponent('SmartsheetHeaderVirtualCellIcon') : resolveComponent('SmartsheetHeaderCellIcon'), { columnMeta: c, diff --git a/packages/nc-gui/components/smartsheet/toolbar/ShareView.vue b/packages/nc-gui/components/smartsheet/toolbar/ShareView.vue index 8df31b707f..156938bca2 100644 --- a/packages/nc-gui/components/smartsheet/toolbar/ShareView.vue +++ b/packages/nc-gui/components/smartsheet/toolbar/ShareView.vue @@ -86,10 +86,17 @@ const genShareLink = async () => { if (!view.value?.id) return const response = (await $api.dbViewShare.create(view.value.id)) as SharedView + const meta = isString(response.meta) ? JSON.parse(response.meta) : response.meta shared.value = { ...response, meta } + if (shared.value.type === ViewTypes.KANBAN) { + const { groupingFieldColumn } = useKanbanViewStoreOrThrow() + shared.value.meta = { ...shared.value.meta, groupingFieldColumn: groupingFieldColumn.value } + await updateSharedViewMeta(true) + } + passwordProtected.value = !!shared.value.password && shared.value.password !== '' showShareModel = true @@ -133,7 +140,7 @@ async function saveTheme() { // const saveTransitionDuration = useDebounceFn(updateSharedViewMeta, 1000, { maxWait: 2000 }) -async function updateSharedViewMeta() { +async function updateSharedViewMeta(silentMessage = false) { try { const meta = shared.value.meta && isString(shared.value.meta) ? JSON.parse(shared.value.meta) : shared.value.meta @@ -141,7 +148,7 @@ async function updateSharedViewMeta() { meta, }) - message.success(t('msg.success.updated')) + if (!silentMessage) message.success(t('msg.success.updated')) } catch (e: any) { message.error(await extractSdkResponseErrorMsg(e)) } diff --git a/packages/nc-gui/composables/useKanbanViewStore.ts b/packages/nc-gui/composables/useKanbanViewStore.ts index e75351e669..b33ddd4f9c 100644 --- a/packages/nc-gui/composables/useKanbanViewStore.ts +++ b/packages/nc-gui/composables/useKanbanViewStore.ts @@ -112,7 +112,10 @@ const [useProvideKanbanViewStore, useKanbanViewStore] = useInjectionState( let res if (isPublic.value) { - res = await fetchSharedViewGroupedData(groupingFieldColumn!.value!.id!) + res = await fetchSharedViewGroupedData(groupingFieldColumn!.value!.id!, { + sortsArr: sorts.value, + filtersArr: nestedFilters.value, + }) } else { res = await api.dbViewRow.groupedDataList( 'noco', @@ -138,6 +141,7 @@ const [useProvideKanbanViewStore, useKanbanViewStore] = useInjectionState( if (stackTitle === null) { where = `(${groupingField.value},is,null)` } + const response = !isPublic.value ? await api.dbViewRow.list('noco', project.value.id!, meta.value!.id!, viewMeta.value!.id!, { ...params, @@ -145,7 +149,7 @@ const [useProvideKanbanViewStore, useKanbanViewStore] = useInjectionState( ...(isUIAllowed('filterSync') ? {} : { filterArrJson: JSON.stringify(nestedFilters.value) }), where, }) - : await fetchSharedViewData({ sortsArr: sorts.value, filtersArr: nestedFilters.value }) + : await fetchSharedViewData({ sortsArr: sorts.value, filtersArr: nestedFilters.value, offset: params.offset }) formattedData.value.set(stackTitle, [...formattedData.value.get(stackTitle)!, ...formatData(response.list)]) } @@ -155,9 +159,12 @@ const [useProvideKanbanViewStore, useKanbanViewStore] = useInjectionState( kanbanMetaData.value = isPublic.value ? (sharedView.value?.view as KanbanType) : await $api.dbView.kanbanRead(viewMeta.value.id) + // set groupingField - groupingFieldColumn.value = - (meta.value.columns as ColumnType[]).filter((f) => f.id === kanbanMetaData.value.fk_grp_col_id)[0] || {} + groupingFieldColumn.value = !isPublic.value + ? (meta.value.columns as ColumnType[]).filter((f) => f.id === kanbanMetaData.value.fk_grp_col_id)[0] || {} + : ((typeof sharedView.value?.meta === 'string' ? JSON.parse(sharedView.value?.meta) : sharedView.value?.meta) + .groupingFieldColumn! as ColumnType) groupingField.value = groupingFieldColumn.value.title! diff --git a/packages/nc-gui/composables/useSharedView.ts b/packages/nc-gui/composables/useSharedView.ts index 89ee00b4b6..6cf0ecfb1f 100644 --- a/packages/nc-gui/composables/useSharedView.ts +++ b/packages/nc-gui/composables/useSharedView.ts @@ -70,6 +70,7 @@ export function useSharedView() { meta.value = { ...viewMeta.model } let order = 1 + meta.value!.columns = [...viewMeta.model.columns] .filter((c) => c.show) .map((c) => ({ ...c, order: order++ })) @@ -92,16 +93,27 @@ export function useSharedView() { Object.keys(relatedMetas).forEach((key) => setMeta(relatedMetas[key])) } - const fetchSharedViewData = async ({ sortsArr, filtersArr }: { sortsArr: SortType[]; filtersArr: FilterType[] }) => { + const fetchSharedViewData = async ({ + sortsArr, + filtersArr, + offset, + }: { + sortsArr: SortType[] + filtersArr: FilterType[] + offset?: number + }) => { if (!sharedView.value) return - const page = paginationData.value.page || 1 - const pageSize = paginationData.value.pageSize || appInfoDefaultLimit + if (!offset) { + const page = paginationData.value.page || 1 + const pageSize = paginationData.value.pageSize || appInfoDefaultLimit + offset = (page - 1) * pageSize + } const { data } = await $api.public.dataList( sharedView.value.uuid!, { - offset: (page - 1) * pageSize, + offset, filterArrJson: JSON.stringify(filtersArr ?? nestedFilters.value), sortArrJson: JSON.stringify(sortsArr ?? sorts.value), } as any, @@ -114,7 +126,10 @@ export function useSharedView() { return data } - const fetchSharedViewGroupedData = async (columnId: string, params: Parameters['dbViewRow']['list']>[4] = {}) => { + const fetchSharedViewGroupedData = async ( + columnId: string, + { sortsArr, filtersArr }: { sortsArr: SortType[]; filtersArr: FilterType[] }, + ) => { if (!sharedView.value) return const page = paginationData.value.page || 1 @@ -125,9 +140,8 @@ export function useSharedView() { columnId, { offset: (page - 1) * pageSize, - filterArrJson: JSON.stringify(nestedFilters.value), - sortArrJson: JSON.stringify(sorts.value), - ...params, + filterArrJson: JSON.stringify(filtersArr ?? nestedFilters.value), + sortArrJson: JSON.stringify(sortsArr ?? sorts.value), } as any, { headers: { diff --git a/packages/nc-gui/composables/useTable.ts b/packages/nc-gui/composables/useTable.ts index 6b9368c0c3..c6638a3b8a 100644 --- a/packages/nc-gui/composables/useTable.ts +++ b/packages/nc-gui/composables/useTable.ts @@ -1,5 +1,5 @@ import type { LinkToAnotherRecordType, TableType } from 'nocodb-sdk' -import { UITypes } from 'nocodb-sdk' +import { UITypes, isSystemColumn } from 'nocodb-sdk' import { Modal, SYSTEM_COLUMNS, @@ -84,7 +84,7 @@ export function useTable(onTableCreate?: (tableMeta: TableType) => void, baseId? async onOk() { try { const meta = (await getMeta(table.id as string, true)) as TableType - const relationColumns = meta?.columns?.filter((c) => c.uidt === UITypes.LinkToAnotherRecord) + const relationColumns = meta?.columns?.filter((c) => c.uidt === UITypes.LinkToAnotherRecord && !isSystemColumn(c)) if (relationColumns?.length) { const refColMsgs = await Promise.all( diff --git a/packages/nc-gui/layouts/shared-view.vue b/packages/nc-gui/layouts/shared-view.vue index 7452ddf963..080de199db 100644 --- a/packages/nc-gui/layouts/shared-view.vue +++ b/packages/nc-gui/layouts/shared-view.vue @@ -1,7 +1,10 @@