Browse Source

Merge pull request #6450 from nocodb/fix/gellery

Fix: shared view gallery
pull/6460/head
Raju Udava 1 year ago committed by GitHub
parent
commit
b8c3b6d396
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      packages/nc-gui/components/dashboard/TreeView/CreateViewBtn.vue
  2. 1
      packages/nc-gui/components/dashboard/TreeView/ProjectNode.vue
  3. 2
      packages/nc-gui/components/dashboard/TreeView/ViewsList.vue
  4. 2
      packages/nc-gui/components/dlg/ViewCreate.vue
  5. 15
      packages/nc-gui/components/smartsheet/Gallery.vue
  6. 5
      packages/nc-gui/components/smartsheet/expanded-form/Header.vue
  7. 5
      packages/nc-gui/components/smartsheet/expanded-form/index.vue
  8. 2
      packages/nc-gui/components/smartsheet/toolbar/FieldsMenu.vue
  9. 2
      packages/nc-gui/components/tabs/Smartsheet.vue
  10. 28
      packages/nc-gui/composables/useExpandedFormStore.ts
  11. 20
      packages/nocodb/src/services/public-datas.service.ts

2
packages/nc-gui/components/dashboard/TreeView/CreateViewBtn.vue

@ -4,8 +4,6 @@ import { ViewTypes } from 'nocodb-sdk'
const { $e } = useNuxtApp() const { $e } = useNuxtApp()
const router = useRouter()
const { refreshCommandPalette } = useCommandPalette() const { refreshCommandPalette } = useCommandPalette()
const viewsStore = useViewsStore() const viewsStore = useViewsStore()
const { views } = storeToRefs(viewsStore) const { views } = storeToRefs(viewsStore)

1
packages/nc-gui/components/dashboard/TreeView/ProjectNode.vue

@ -11,7 +11,6 @@ import {
ProjectRoleInj, ProjectRoleInj,
ToggleDialogInj, ToggleDialogInj,
extractSdkResponseErrorMsg, extractSdkResponseErrorMsg,
isElementInvisible,
openLink, openLink,
storeToRefs, storeToRefs,
useProjects, useProjects,

2
packages/nc-gui/components/dashboard/TreeView/ViewsList.vue

@ -51,8 +51,6 @@ const views = computed(() => viewsByTable.value.get(table.value.id!)?.filter((v)
const { api } = useApi() const { api } = useApi()
const router = useRouter()
const { refreshCommandPalette } = useCommandPalette() const { refreshCommandPalette } = useCommandPalette()
const { addUndo, defineModelScope } = useUndoRedo() const { addUndo, defineModelScope } = useUndoRedo()

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

@ -4,7 +4,7 @@ import type { Form as AntForm, SelectProps } from 'ant-design-vue'
import { capitalize } from '@vue/runtime-core' import { capitalize } from '@vue/runtime-core'
import type { FormType, GalleryType, GridType, KanbanType, MapType, TableType, ViewType } from 'nocodb-sdk' import type { FormType, GalleryType, GridType, KanbanType, MapType, TableType, ViewType } from 'nocodb-sdk'
import { UITypes, ViewTypes } from 'nocodb-sdk' import { UITypes, ViewTypes } from 'nocodb-sdk'
import { computed, message, nextTick, onBeforeMount, reactive, ref, unref, useApi, useI18n, useVModel, watch } from '#imports' import { computed, message, nextTick, onBeforeMount, reactive, ref, useApi, useI18n, useVModel, watch } from '#imports'
interface Props { interface Props {
modelValue: boolean modelValue: boolean

15
packages/nc-gui/components/smartsheet/Gallery.vue

@ -73,7 +73,7 @@ const { getPossibleAttachmentSrc } = useAttachment()
const fieldsWithoutDisplay = computed(() => fields.value.filter((f) => !isPrimary(f))) const fieldsWithoutDisplay = computed(() => fields.value.filter((f) => !isPrimary(f)))
const displayField = computed(() => meta.value?.columns?.find((c) => c.pv) ?? null) const displayField = computed(() => meta.value?.columns?.find((c) => c.pv && fields.value.includes(c)) ?? null)
const coverImageColumn: any = computed(() => const coverImageColumn: any = computed(() =>
meta.value?.columnsById meta.value?.columnsById
@ -124,13 +124,9 @@ const attachments = (record: any): Attachment[] => {
} }
const expandForm = (row: RowType, state?: Record<string, any>) => { const expandForm = (row: RowType, state?: Record<string, any>) => {
if (isPublic.value) {
return
}
const rowId = extractPkFromRow(row.row, meta.value!.columns!) const rowId = extractPkFromRow(row.row, meta.value!.columns!)
if (rowId) { if (rowId && !isPublic.value) {
router.push({ router.push({
query: { query: {
...route.query, ...route.query,
@ -248,10 +244,9 @@ watch(
<div v-for="(record, rowIndex) in data" :key="`record-${record.row.id}`"> <div v-for="(record, rowIndex) in data" :key="`record-${record.row.id}`">
<LazySmartsheetRow :row="record"> <LazySmartsheetRow :row="record">
<a-card <a-card
class="!rounded-lg h-full border-gray-200 border-1 group overflow-hidden break-all max-w-[450px] shadow-sm hover:shadow-md" class="!rounded-lg h-full border-gray-200 border-1 group overflow-hidden break-all max-w-[450px] shadow-sm hover:shadow-md cursor-pointer"
:body-style="{ padding: '0px' }" :body-style="{ padding: '0px' }"
:data-testid="`nc-gallery-card-${record.row.id}`" :data-testid="`nc-gallery-card-${record.row.id}`"
:style="isPublic ? { cursor: 'default' } : { cursor: 'pointer' }"
@click="expandFormClick($event, record)" @click="expandFormClick($event, record)"
@contextmenu="showContextMenu($event, { row: rowIndex })" @contextmenu="showContextMenu($event, { row: rowIndex })"
> >
@ -299,7 +294,7 @@ watch(
<img class="object-contain w-[48px] h-[48px]" src="~assets/icons/FileIconImageBox.png" /> <img class="object-contain w-[48px] h-[48px]" src="~assets/icons/FileIconImageBox.png" />
</div> </div>
</template> </template>
<h2 v-if="displayField" class="text-base mt-6 mx-3 font-bold"> <h2 v-if="displayField" class="text-base mt-3 mx-3 font-bold">
<LazySmartsheetVirtualCell <LazySmartsheetVirtualCell
v-if="isVirtualCol(displayField)" v-if="isVirtualCol(displayField)"
v-model="record.row[displayField.title]" v-model="record.row[displayField.title]"
@ -319,7 +314,7 @@ watch(
</h2> </h2>
<div v-for="col in fieldsWithoutDisplay" :key="`record-${record.row.id}-${col.id}`"> <div v-for="col in fieldsWithoutDisplay" :key="`record-${record.row.id}-${col.id}`">
<div class="flex flex-col ml-2 !pr-3.5 !mb-[0.75rem] rounded-lg w-full"> <div class="flex flex-col first:mt-3 ml-2 !pr-3.5 !mb-[0.75rem] rounded-lg w-full">
<div class="flex flex-row w-full justify-start scale-75"> <div class="flex flex-row w-full justify-start scale-75">
<div class="w-full pb-1 text-gray-300"> <div class="w-full pb-1 text-gray-300">
<LazySmartsheetHeaderVirtualCell <LazySmartsheetHeaderVirtualCell

5
packages/nc-gui/components/smartsheet/expanded-form/Header.vue

@ -2,6 +2,7 @@
import { message } from 'ant-design-vue' import { message } from 'ant-design-vue'
import type { ViewType } from 'nocodb-sdk' import type { ViewType } from 'nocodb-sdk'
import { import {
IsPublicInj,
ReloadRowDataHookInj, ReloadRowDataHookInj,
iconMap, iconMap,
isMac, isMac,
@ -20,6 +21,8 @@ const route = useRoute()
const { meta, isSqlView } = useSmartsheetStoreOrThrow() const { meta, isSqlView } = useSmartsheetStoreOrThrow()
const isPublic = inject(IsPublicInj, ref(false))
const { commentsDrawer, displayValue, primaryKey, save: _save, loadRow, deleteRowById } = useExpandedFormStoreOrThrow() const { commentsDrawer, displayValue, primaryKey, save: _save, loadRow, deleteRowById } = useExpandedFormStoreOrThrow()
const { isNew, syncLTARRefs, state } = useSmartsheetRowStoreOrThrow() const { isNew, syncLTARRefs, state } = useSmartsheetRowStoreOrThrow()
@ -98,7 +101,7 @@ const onConfirmDeleteRowClick = async () => {
</h5> </h5>
<div class="flex-1" /> <div class="flex-1" />
<a-tooltip placement="bottom"> <a-tooltip v-if="!isPublic" placement="bottom">
<template #title> <template #title>
<!-- todo: i18n --> <!-- todo: i18n -->
<div class="text-center w-full">Copy record URL</div> <div class="text-center w-full">Copy record URL</div>

5
packages/nc-gui/components/smartsheet/expanded-form/index.vue

@ -8,6 +8,7 @@ import {
FieldsInj, FieldsInj,
IsExpandedFormOpenInj, IsExpandedFormOpenInj,
IsKanbanInj, IsKanbanInj,
IsPublicInj,
MetaInj, MetaInj,
ReloadRowDataHookInj, ReloadRowDataHookInj,
computedInject, computedInject,
@ -57,6 +58,8 @@ const meta = toRef(props, 'meta')
const router = useRouter() const router = useRouter()
const isPublic = inject(IsPublicInj, ref(false))
const { isUIAllowed } = useRoles() const { isUIAllowed } = useRoles()
// override cell click hook to avoid unexpected behavior at form fields // override cell click hook to avoid unexpected behavior at form fields
@ -360,6 +363,7 @@ export default {
:column="col" :column="col"
:edit-enabled="true" :edit-enabled="true"
:active="true" :active="true"
:read-only="isPublic"
@update:model-value="changedColumns.add(col.title)" @update:model-value="changedColumns.add(col.title)"
/> />
</LazySmartsheetDivDataCell> </LazySmartsheetDivDataCell>
@ -401,6 +405,7 @@ export default {
:column="col" :column="col"
:edit-enabled="true" :edit-enabled="true"
:active="true" :active="true"
:read-only="isPublic"
@update:model-value="changedColumns.add(col.title)" @update:model-value="changedColumns.add(col.title)"
/> />
</LazySmartsheetDivDataCell> </LazySmartsheetDivDataCell>

2
packages/nc-gui/components/smartsheet/toolbar/FieldsMenu.vue

@ -316,7 +316,7 @@ useMenuCloseOnEsc(open)
<template #overlay> <template #overlay>
<div class="p-4 pr-0 bg-white w-90 rounded-2xl nc-table-toolbar-menu" data-testid="nc-fields-menu" @click.stop> <div class="p-4 pr-0 bg-white w-90 rounded-2xl nc-table-toolbar-menu" data-testid="nc-fields-menu" @click.stop>
<div <div
v-if="!filterQuery && (activeView?.type === ViewTypes.GALLERY || activeView?.type === ViewTypes.KANBAN)" v-if="!filterQuery && !isPublic && (activeView?.type === ViewTypes.GALLERY || activeView?.type === ViewTypes.KANBAN)"
class="flex flex-col gap-y-2 pr-6 mb-6" class="flex flex-col gap-y-2 pr-6 mb-6"
> >
<div class="flex text-sm select-none">Select cover image field</div> <div class="flex text-sm select-none">Select cover image field</div>

2
packages/nc-gui/components/tabs/Smartsheet.vue

@ -36,8 +36,6 @@ const { metas, getMeta } = useMetas()
useSidebar('nc-right-sidebar') useSidebar('nc-right-sidebar')
const isPublic = inject(IsPublicInj, ref(false))
const activeTab = toRef(props, 'activeTab') const activeTab = toRef(props, 'activeTab')
const fields = ref<ColumnType[]>([]) const fields = ref<ColumnType[]>([])

28
packages/nc-gui/composables/useExpandedFormStore.ts

@ -25,8 +25,6 @@ import {
import type { Row } from '#imports' import type { Row } from '#imports'
const [useProvideExpandedFormStore, useExpandedFormStore] = useInjectionState((meta: Ref<TableType>, row: Ref<Row>) => { const [useProvideExpandedFormStore, useExpandedFormStore] = useInjectionState((meta: Ref<TableType>, row: Ref<Row>) => {
const { loadKanbanData, addOrEditStackRow } = useKanbanViewStoreOrThrow()
const { $e, $state, $api } = useNuxtApp() const { $e, $state, $api } = useNuxtApp()
const { api, isLoading: isCommentsLoading, error: commentsError } = useApi() const { api, isLoading: isCommentsLoading, error: commentsError } = useApi()
@ -121,6 +119,13 @@ const [useProvideExpandedFormStore, useExpandedFormStore] = useInjectionState((m
return $state.user?.value?.email === email return $state.user?.value?.email === email
} }
const loadKanbanData = async () => {
if (activeView.value?.type === ViewTypes.KANBAN) {
const { loadKanbanData: _loadKanbanData } = useKanbanViewStoreOrThrow()
await _loadKanbanData()
}
}
const saveComment = async () => { const saveComment = async () => {
try { try {
if (!row.value || !comment.value) return if (!row.value || !comment.value) return
@ -180,9 +185,7 @@ const [useProvideExpandedFormStore, useExpandedFormStore] = useInjectionState((m
redo: { redo: {
fn: async (rowData: any) => { fn: async (rowData: any) => {
await $api.dbTableRow.create('noco', project.value.id as string, meta.value.id, { ...pkData, ...rowData }) await $api.dbTableRow.create('noco', project.value.id as string, meta.value.id, { ...pkData, ...rowData })
if (activeView.value?.type === ViewTypes.KANBAN) { await loadKanbanData()
await loadKanbanData()
}
reloadTrigger?.trigger() reloadTrigger?.trigger()
}, },
args: [clone(insertObj)], args: [clone(insertObj)],
@ -199,9 +202,8 @@ const [useProvideExpandedFormStore, useExpandedFormStore] = useInjectionState((m
if (res.message) { if (res.message) {
throw new Error(res.message) throw new Error(res.message)
} }
if (activeView.value?.type === ViewTypes.KANBAN) {
await loadKanbanData() await loadKanbanData()
}
reloadTrigger?.trigger() reloadTrigger?.trigger()
}, },
args: [id], args: [id],
@ -233,9 +235,8 @@ const [useProvideExpandedFormStore, useExpandedFormStore] = useInjectionState((m
redo: { redo: {
fn: async (id: string, data: Record<string, any>) => { fn: async (id: string, data: Record<string, any>) => {
await $api.dbTableRow.update(NOCO, project.value.id as string, meta.value.id, encodeURIComponent(id), data) await $api.dbTableRow.update(NOCO, project.value.id as string, meta.value.id, encodeURIComponent(id), data)
if (activeView.value?.type === ViewTypes.KANBAN) { await loadKanbanData()
await loadKanbanData()
}
reloadTrigger?.trigger() reloadTrigger?.trigger()
}, },
args: [id, clone(updateOrInsertObj)], args: [id, clone(updateOrInsertObj)],
@ -243,9 +244,7 @@ const [useProvideExpandedFormStore, useExpandedFormStore] = useInjectionState((m
undo: { undo: {
fn: async (id: string, data: Record<string, any>) => { fn: async (id: string, data: Record<string, any>) => {
await $api.dbTableRow.update(NOCO, project.value.id as string, meta.value.id, encodeURIComponent(id), data) await $api.dbTableRow.update(NOCO, project.value.id as string, meta.value.id, encodeURIComponent(id), data)
if (activeView.value?.type === ViewTypes.KANBAN) { await loadKanbanData()
await loadKanbanData()
}
reloadTrigger?.trigger() reloadTrigger?.trigger()
}, },
args: [id, clone(undoObject)], args: [id, clone(undoObject)],
@ -265,6 +264,7 @@ const [useProvideExpandedFormStore, useExpandedFormStore] = useInjectionState((m
} }
if (activeView.value?.type === ViewTypes.KANBAN) { if (activeView.value?.type === ViewTypes.KANBAN) {
const { addOrEditStackRow } = useKanbanViewStoreOrThrow()
addOrEditStackRow(row.value, isNewRow) addOrEditStackRow(row.value, isNewRow)
} }

20
packages/nocodb/src/services/public-datas.service.ts

@ -27,7 +27,8 @@ export class PublicDatasService {
password?: string; password?: string;
query: any; query: any;
}) { }) {
const view = await View.getByUUID(param.sharedViewUuid); const { sharedViewUuid, password, query = {} } = param;
const view = await View.getByUUID(sharedViewUuid);
if (!view) NcError.notFound('Not found'); if (!view) NcError.notFound('Not found');
if ( if (
@ -39,7 +40,7 @@ export class PublicDatasService {
NcError.notFound('Not found'); NcError.notFound('Not found');
} }
if (view.password && view.password !== param.password) { if (view.password && view.password !== password) {
return NcError.forbidden(ErrorMessages.INVALID_SHARED_VIEW_PASSWORD); return NcError.forbidden(ErrorMessages.INVALID_SHARED_VIEW_PASSWORD);
} }
@ -55,24 +56,23 @@ export class PublicDatasService {
dbDriver: await NcConnectionMgrv2.get(base), dbDriver: await NcConnectionMgrv2.get(base),
}); });
const listArgs: any = { ...param.query }; const { ast, dependencyFields } = await getAst({
model,
query: {},
view,
});
const listArgs: any = { ...query, ...dependencyFields };
try { try {
listArgs.filterArr = JSON.parse(listArgs.filterArrJson); listArgs.filterArr = JSON.parse(listArgs.filterArrJson);
} catch (e) {} } catch (e) {}
try { try {
listArgs.sortArr = JSON.parse(listArgs.sortArrJson); listArgs.sortArr = JSON.parse(listArgs.sortArrJson);
} catch (e) {} } catch (e) {}
let data = []; let data = [];
let count = 0; let count = 0;
try { try {
const { ast } = await getAst({
query: param.query,
model,
view,
});
data = await nocoExecute( data = await nocoExecute(
ast, ast,
await baseModel.list(listArgs), await baseModel.list(listArgs),

Loading…
Cancel
Save