Browse Source

Merge pull request #4007 from nocodb/feat/gallery-share-view

feat: gallery share view
pull/4026/head
աɨռɢӄաօռɢ 2 years ago committed by GitHub
parent
commit
f527652561
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 32
      packages/nc-gui/components/shared-view/Gallery.vue
  2. 2
      packages/nc-gui/components/smartsheet/Toolbar.vue
  3. 8
      packages/nc-gui/components/smartsheet/toolbar/ShareView.vue
  4. 35
      packages/nc-gui/pages/[projectType]/gallery/[viewId]/index.vue
  5. 12
      packages/nocodb/src/lib/meta/api/publicApis/publicDataApis.ts
  6. 16
      packages/nocodb/src/lib/meta/api/publicApis/publicDataExportApis.ts

32
packages/nc-gui/components/shared-view/Gallery.vue

@ -0,0 +1,32 @@
<script setup lang="ts">
import { ActiveViewInj, FieldsInj, IsPublicInj, MetaInj, ReadonlyInj, ReloadViewDataHookInj } from '#imports'
const { sharedView, meta, sorts, nestedFilters } = useSharedView()
const reloadEventHook = createEventHook()
provide(ReloadViewDataHookInj, reloadEventHook)
provide(ReadonlyInj, true)
provide(MetaInj, meta)
provide(ActiveViewInj, sharedView)
provide(FieldsInj, ref(meta.value?.columns || []))
provide(IsPublicInj, ref(true))
useProvideSmartsheetStore(sharedView, meta, true, sorts, nestedFilters)
</script>
<template>
<div class="nc-container h-full mt-1.5 px-12">
<div class="flex flex-col h-full flex-1 min-w-0">
<LazySmartsheetToolbar />
<div class="h-full flex-1 min-w-0 min-h-0 bg-gray-50">
<LazySmartsheetGallery />
</div>
</div>
</div>
</template>

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

@ -35,7 +35,7 @@ const { allowCSVDownload } = useSharedView()
<LazySmartsheetToolbarSortListMenu v-if="isGrid || isGallery || isKanban" /> <LazySmartsheetToolbarSortListMenu v-if="isGrid || isGallery || isKanban" />
<LazySmartsheetToolbarShareView v-if="(isForm || isGrid || isKanban) && !isPublic" /> <LazySmartsheetToolbarShareView v-if="(isForm || isGrid || isKanban || isGallery) && !isPublic" />
<LazySmartsheetToolbarExport v-if="(!isPublic && !isUIAllowed('dataInsert')) || (isPublic && allowCSVDownload)" /> <LazySmartsheetToolbarExport v-if="(!isPublic && !isUIAllowed('dataInsert')) || (isPublic && allowCSVDownload)" />
<div class="flex-1" /> <div class="flex-1" />

8
packages/nc-gui/components/smartsheet/toolbar/ShareView.vue

@ -98,6 +98,9 @@ const sharedViewUrl = computed(() => {
case ViewTypes.KANBAN: case ViewTypes.KANBAN:
viewType = 'kanban' viewType = 'kanban'
break break
case ViewTypes.GALLERY:
viewType = 'gallery'
break
default: default:
viewType = 'view' viewType = 'view'
} }
@ -314,7 +317,10 @@ watch(passwordProtected, (value) => {
<div> <div>
<!-- Allow Download --> <!-- Allow Download -->
<a-checkbox <a-checkbox
v-if="shared && (shared.type === ViewTypes.GRID || shared.type === ViewTypes.KANBAN)" v-if="
shared &&
(shared.type === ViewTypes.GRID || shared.type === ViewTypes.KANBAN || shared.type === ViewTypes.GALLERY)
"
v-model:checked="allowCSVDownload" v-model:checked="allowCSVDownload"
data-cy="nc-modal-share-view__with-csv-download" data-cy="nc-modal-share-view__with-csv-download"
class="!text-sm" class="!text-sm"

35
packages/nc-gui/pages/[projectType]/gallery/[viewId]/index.vue

@ -0,0 +1,35 @@
<script setup lang="ts">
import { message } from 'ant-design-vue'
import { definePageMeta } from '#imports'
definePageMeta({
public: true,
requiresAuth: false,
layout: 'shared-view',
})
const route = useRoute()
const { loadSharedView } = useSharedView()
const showPassword = ref(false)
try {
await loadSharedView(route.params.viewId as string)
} catch (e: any) {
if (e?.response?.status === 403) {
showPassword.value = true
} else {
message.error(await extractSdkResponseErrorMsg(e))
}
}
</script>
<template>
<NuxtLayout id="content" class="flex" name="shared-view">
<div v-if="showPassword">
<LazySharedViewAskPassword v-model="showPassword" />
</div>
<LazySharedViewGallery v-else />
</NuxtLayout>
</template>

12
packages/nocodb/src/lib/meta/api/publicApis/publicDataApis.ts

@ -24,7 +24,11 @@ export async function dataList(req: Request, res: Response) {
const view = await View.getByUUID(req.params.sharedViewUuid); const view = await View.getByUUID(req.params.sharedViewUuid);
if (!view) NcError.notFound('Not found'); if (!view) NcError.notFound('Not found');
if (view.type !== ViewTypes.GRID && view.type !== ViewTypes.KANBAN) { if (
view.type !== ViewTypes.GRID &&
view.type !== ViewTypes.KANBAN &&
view.type !== ViewTypes.GALLERY
) {
NcError.notFound('Not found'); NcError.notFound('Not found');
} }
@ -88,7 +92,11 @@ async function groupedDataList(req: Request, res: Response) {
if (!view) NcError.notFound('Not found'); if (!view) NcError.notFound('Not found');
if (view.type !== ViewTypes.GRID && view.type !== ViewTypes.KANBAN) { if (
view.type !== ViewTypes.GRID &&
view.type !== ViewTypes.KANBAN &&
view.type !== ViewTypes.GALLERY
) {
NcError.notFound('Not found'); NcError.notFound('Not found');
} }

16
packages/nocodb/src/lib/meta/api/publicApis/publicDataExportApis.ts

@ -16,7 +16,12 @@ import getAst from '../../../db/sql-data-mapper/lib/sql/helpers/getAst';
async function exportExcel(req: Request, res: Response) { async function exportExcel(req: Request, res: Response) {
const view = await View.getByUUID(req.params.publicDataUuid); const view = await View.getByUUID(req.params.publicDataUuid);
if (!view) NcError.notFound('Not found'); if (!view) NcError.notFound('Not found');
if (view.type !== ViewTypes.GRID && view.type !== ViewTypes.KANBAN) NcError.notFound('Not found'); if (
view.type !== ViewTypes.GRID &&
view.type !== ViewTypes.KANBAN &&
view.type !== ViewTypes.GALLERY
)
NcError.notFound('Not found');
if (view.password && view.password !== req.headers?.['xc-password']) { if (view.password && view.password !== req.headers?.['xc-password']) {
NcError.forbidden(ErrorMessages.INVALID_SHARED_VIEW_PASSWORD); NcError.forbidden(ErrorMessages.INVALID_SHARED_VIEW_PASSWORD);
@ -30,7 +35,7 @@ async function exportExcel(req: Request, res: Response) {
const data = XLSX.utils.json_to_sheet(dbRows); const data = XLSX.utils.json_to_sheet(dbRows);
const wb = XLSX.utils.book_new(); const wb = XLSX.utils.book_new();
XLSX.utils.book_append_sheet(wb, data, view.title); XLSX.utils.book_append_sheet(wb, data, view.title);
const buf = XLSX.write(wb, { type: "base64", bookType: "xlsx" }); const buf = XLSX.write(wb, { type: 'base64', bookType: 'xlsx' });
res.set({ res.set({
'Access-Control-Expose-Headers': 'nc-export-offset', 'Access-Control-Expose-Headers': 'nc-export-offset',
'nc-export-offset': offset, 'nc-export-offset': offset,
@ -47,7 +52,12 @@ async function exportCsv(req: Request, res: Response) {
const fields = req.query.fields; const fields = req.query.fields;
if (!view) NcError.notFound('Not found'); if (!view) NcError.notFound('Not found');
if (view.type !== ViewTypes.GRID && view.type !== ViewTypes.KANBAN) NcError.notFound('Not found'); if (
view.type !== ViewTypes.GRID &&
view.type !== ViewTypes.KANBAN &&
view.type !== ViewTypes.GALLERY
)
NcError.notFound('Not found');
if (view.password && view.password !== req.headers?.['xc-password']) { if (view.password && view.password !== req.headers?.['xc-password']) {
NcError.forbidden(ErrorMessages.INVALID_SHARED_VIEW_PASSWORD); NcError.forbidden(ErrorMessages.INVALID_SHARED_VIEW_PASSWORD);

Loading…
Cancel
Save