Browse Source

fix: proper null value and exception handling

pull/9112/head
Pranav C 4 months ago
parent
commit
96f8a915f1
  1. 2
      packages/nc-gui/components/smartsheet/expanded-form/RichComment.vue
  2. 2
      packages/nc-gui/composables/useKanbanViewStore.ts
  3. 2
      packages/nc-gui/composables/useSmartsheetStore.ts
  4. 105
      packages/nc-gui/composables/useViewData.ts
  5. 38
      packages/nc-gui/store/bases.ts

2
packages/nc-gui/components/smartsheet/expanded-form/RichComment.vue

@ -96,6 +96,8 @@ const editor = useEditor({
onBlur: (e) => {
const targetEl = e?.event.relatedTarget as HTMLElement
if (!targetEl) return;
if (
!targetEl?.closest(
'.comment-bubble-menu, .nc-rich-text-comment, .tippy-box, .nc-comment-save-btn, .rich-text-bottom-bar, .mention, .nc-mention-list, .tippy-content, .nc-comment-rich-editor',

2
packages/nc-gui/composables/useKanbanViewStore.ts

@ -52,7 +52,7 @@ const [useProvideKanbanViewStore, useKanbanViewStore] = useInjectionState(
if (!col) return
if (!search.value.query.trim()) return
if (['text', 'string'].includes(sqlUi.value.getAbstractType(col)) && col.dt !== 'bigint') {
if (sqlUi.value && ['text', 'string'].includes(sqlUi.value.getAbstractType(col)) && col.dt !== 'bigint') {
where = `(${col.title},like,%${search.value.query.trim()}%)`
} else {
where = `(${col.title},eq,${search.value.query.trim()})`

2
packages/nc-gui/composables/useSmartsheetStore.ts

@ -46,7 +46,7 @@ const [useProvideSmartsheetStore, useSmartsheetStore] = useInjectionState(
if (!col) return
if (!search.value.query.trim()) return
if (['text', 'string'].includes(sqlUi.value.getAbstractType(col)) && col.dt !== 'bigint') {
if (sqlUi.value && ['text', 'string'].includes(sqlUi.value.getAbstractType(col)) && col.dt !== 'bigint') {
where = `(${col.title},like,%${search.value.query.trim()}%)`
} else {
where = `(${col.title},eq,${search.value.query.trim()})`

105
packages/nc-gui/composables/useViewData.ts

@ -1,13 +1,22 @@
import { ViewTypes } from 'nocodb-sdk'
import {ViewTypes} from 'nocodb-sdk'
import axios from 'axios'
import type { Api, ColumnType, FormColumnType, FormType, GalleryType, PaginatedType, TableType, ViewType } from 'nocodb-sdk'
import type { ComputedRef, Ref } from 'vue'
import { NavigateDir } from '#imports'
import type {
Api,
ColumnType,
FormColumnType,
FormType,
GalleryType,
PaginatedType,
TableType,
ViewType
} from 'nocodb-sdk'
import type {ComputedRef, Ref} from 'vue'
import {NavigateDir} from '#imports'
const formatData = (list: Record<string, any>[]) =>
list.map((row) => ({
row: { ...row },
oldRow: { ...row },
row: {...row},
oldRow: {...row},
rowMeta: {},
}))
@ -16,26 +25,26 @@ export function useViewData(
viewMeta: Ref<ViewType | undefined> | ComputedRef<(ViewType & { id: string }) | undefined>,
where?: ComputedRef<string | undefined>,
) {
const { activeTableId, activeTable } = storeToRefs(useTablesStore())
const {activeTableId, activeTable} = storeToRefs(useTablesStore())
const meta = computed(() => _meta.value || activeTable.value)
const metaId = computed(() => _meta.value?.id || activeTableId.value)
const { t } = useI18n()
const {t} = useI18n()
const optimisedQuery = useState('optimisedQuery', () => true)
const { api, isLoading, error } = useApi()
const {api, isLoading, error} = useApi()
const router = useRouter()
const route = router.currentRoute
const { appInfo, gridViewPageSize } = useGlobal()
const {appInfo, gridViewPageSize} = useGlobal()
const appInfoDefaultLimit = gridViewPageSize.value || appInfo.value.defaultLimit || 25
const _paginationData = ref<PaginatedType>({ page: 1, pageSize: appInfoDefaultLimit })
const _paginationData = ref<PaginatedType>({page: 1, pageSize: appInfoDefaultLimit})
const aggCommentCount = ref<{ row_id: string; count: string }[]>([])
@ -51,19 +60,19 @@ export function useViewData(
const isPublic = inject(IsPublicInj, ref(false))
const { base } = storeToRefs(useBase())
const {base} = storeToRefs(useBase())
const { sharedView, fetchSharedViewData, paginationData: sharedPaginationData } = useSharedView()
const {sharedView, fetchSharedViewData, paginationData: sharedPaginationData} = useSharedView()
const { $api } = useNuxtApp()
const {$api} = useNuxtApp()
const { sorts, nestedFilters } = useSmartsheetStoreOrThrow()
const {sorts, nestedFilters} = useSmartsheetStoreOrThrow()
const { isUIAllowed } = useRoles()
const {isUIAllowed} = useRoles()
const routeQuery = computed(() => route.value.query as Record<string, string>)
const { isPaginationLoading } = storeToRefs(useViewsStore())
const {isPaginationLoading} = storeToRefs(useViewsStore())
const paginationData = computed({
get: () => (isPublic.value ? sharedPaginationData.value : _paginationData.value),
@ -93,7 +102,7 @@ export function useViewData(
}))
async function syncCount() {
const { count } = await $api.dbViewRow.count(
const {count} = await $api.dbViewRow.count(
NOCO,
base?.value?.id as string,
metaId.value as string,
@ -136,21 +145,25 @@ export function useViewData(
if (isPublic.value) return
const ids = formattedData.value
?.filter(({ rowMeta: { new: isNew } }) => !isNew)
?.map(({ row }) => {
?.filter(({rowMeta: {new: isNew}}) => !isNew)
?.map(({row}) => {
return extractPkFromRow(row, meta?.value?.columns as ColumnType[])
})
if (!ids?.length || ids?.some((id) => !id)) return
aggCommentCount.value = await $api.utils.commentCount({
ids,
fk_model_id: metaId.value as string,
})
try {
aggCommentCount.value = await $api.utils.commentCount({
ids,
fk_model_id: metaId.value as string,
})
for (const row of formattedData.value) {
const id = extractPkFromRow(row.row, meta.value?.columns as ColumnType[])
row.rowMeta.commentCount = +(aggCommentCount.value?.find((c: Record<string, any>) => c.row_id === id)?.count || 0)
for (const row of formattedData.value) {
const id = extractPkFromRow(row.row, meta.value?.columns as ColumnType[])
row.rowMeta.commentCount = +(aggCommentCount.value?.find((c: Record<string, any>) => c.row_id === id)?.count || 0)
}
} catch (e) {
console.error(e)
}
}
@ -173,23 +186,23 @@ export function useViewData(
try {
response = !isPublic.value
? await api.dbViewRow.list(
'noco',
base.value.id!,
metaId.value!,
viewMeta.value!.id!,
{
...queryParams.value,
...params,
...(isUIAllowed('sortSync') ? {} : { sortArrJson: JSON.stringify(sorts.value) }),
...(isUIAllowed('filterSync') ? {} : { filterArrJson: JSON.stringify(nestedFilters.value) }),
where: where?.value,
...(excludePageInfo.value ? { excludeCount: 'true' } : {}),
} as any,
{
cancelToken: controller.value.token,
},
)
: await fetchSharedViewData({ sortsArr: sorts.value, filtersArr: nestedFilters.value, where: where?.value })
'noco',
base.value.id!,
metaId.value!,
viewMeta.value!.id!,
{
...queryParams.value,
...params,
...(isUIAllowed('sortSync') ? {} : {sortArrJson: JSON.stringify(sorts.value)}),
...(isUIAllowed('filterSync') ? {} : {filterArrJson: JSON.stringify(nestedFilters.value)}),
where: where?.value,
...(excludePageInfo.value ? {excludeCount: 'true'} : {}),
} as any,
{
cancelToken: controller.value.token,
},
)
: await fetchSharedViewData({sortsArr: sorts.value, filtersArr: nestedFilters.value, where: where?.value})
} catch (error) {
// if the request is canceled, then do nothing
if (error.code === 'ERR_CANCELED') {
@ -269,7 +282,7 @@ export function useViewData(
async function loadFormView() {
if (!viewMeta?.value?.id) return
try {
const { columns, ...view } = await $api.dbView.formRead(viewMeta.value.id)
const {columns, ...view} = await $api.dbView.formRead(viewMeta.value.id)
let order = 1
const fieldById = (columns || []).reduce((o: Record<string, any>, f: Record<string, any>) => {
if (order < f.order) {
@ -289,7 +302,7 @@ export function useViewData(
fk_column_id: c.id,
fk_view_id: viewMeta.value?.id,
...(fieldById[c.id!] ? fieldById[c.id!] : {}),
meta: { validators: [], ...parseProp(fieldById[c.id!]?.meta), ...parseProp(c.meta) },
meta: {validators: [], ...parseProp(fieldById[c.id!]?.meta), ...parseProp(c.meta)},
order: (fieldById[c.id!] && fieldById[c.id!].order) || order++,
id: fieldById[c.id!] && fieldById[c.id!].id,
}))

38
packages/nc-gui/store/bases.ts

@ -182,29 +182,33 @@ export const useBases = defineStore('basesStore', () => {
// actions
const loadProject = async (baseId: string, force = false) => {
if (!force && isProjectPopulated(baseId)) return bases.value.get(baseId)
try {
if (!force && isProjectPopulated(baseId)) return bases.value.get(baseId)
const _project = await api.base.read(baseId)
const _project = await api.base.read(baseId)
if (!_project) {
await navigateTo(`/`)
return
}
if (!_project) {
await navigateTo(`/`)
return
}
_project.meta = _project?.meta && typeof _project.meta === 'string' ? JSON.parse(_project.meta) : {}
_project.meta = _project?.meta && typeof _project.meta === 'string' ? JSON.parse(_project.meta) : {}
const existingProject = bases.value.get(baseId) ?? ({} as any)
const existingProject = bases.value.get(baseId) ?? ({} as any)
const base = {
...existingProject,
..._project,
isExpanded: route.value.params.baseId === baseId || existingProject.isExpanded,
// isLoading is managed by Sidebar
isLoading: existingProject.isLoading,
meta: { ...parseProp(existingProject.meta), ...parseProp(_project.meta) },
}
const base = {
...existingProject,
..._project,
isExpanded: route.value.params.baseId === baseId || existingProject.isExpanded,
// isLoading is managed by Sidebar
isLoading: existingProject.isLoading,
meta: { ...parseProp(existingProject.meta), ...parseProp(_project.meta) },
}
bases.value.set(baseId, base)
bases.value.set(baseId, base)
} catch (e: any) {
await message.error(await extractSdkResponseErrorMsg(e))
}
}
const getSqlUi = async (baseId: string, sourceId: string) => {

Loading…
Cancel
Save