diff --git a/packages/nc-gui/components/smartsheet/calendar/index.vue b/packages/nc-gui/components/smartsheet/calendar/index.vue index e256831d77..f4b758f09b 100644 --- a/packages/nc-gui/components/smartsheet/calendar/index.vue +++ b/packages/nc-gui/components/smartsheet/calendar/index.vue @@ -41,6 +41,7 @@ provide(IsKanbanInj, ref(false)) provide(IsCalendarInj, ref(true)) const { + calendarRange, calDataType, loadCalendarMeta, loadCalendarData, @@ -256,37 +257,45 @@ const headerText = computed(() => { - - - - - - - + + + + + + + + + + + + + + + + + {{ $t('activity.noRange') }} + - - - []) => const [useProvideCalendarViewStore, useCalendarViewStore] = useInjectionState( ( meta: Ref<((CalendarType & { id: string }) | TableType) | undefined>, - viewMeta: Ref<(ViewType | CalendarType | undefined) & { id: string }> | ComputedRef<(ViewType & { id: string }) | undefined>, + viewMeta: + | Ref<(ViewType | CalendarType | undefined) & { id: string }> + | ComputedRef< + | (ViewType & { + id: string + }) + | undefined + >, shared = false, where?: ComputedRef, ) => { @@ -116,6 +123,8 @@ const [useProvideCalendarViewStore, useCalendarViewStore] = useInjectionState( const sideBarFilter = computed(() => { let combinedFilters: any = [] + if (!calendarRange.value) return [] + if (sideBarFilterOption.value === 'allRecords') { combinedFilters = [] } else if (sideBarFilterOption.value === 'withoutDates') { @@ -329,6 +338,7 @@ const [useProvideCalendarViewStore, useCalendarViewStore] = useInjectionState( } const filterJSON = computed(() => { + if (!calendarRange.value) return [] const combinedFilters: any = { is_group: true, logical_op: 'and', @@ -514,21 +524,24 @@ const [useProvideCalendarViewStore, useCalendarViewStore] = useInjectionState( }) if (!base?.value?.id || !meta.value?.id || !viewMeta.value?.id) return - const res = !isPublic.value - ? await api.dbViewRow.calendarCount('noco', base.value.id!, meta.value!.id!, viewMeta.value.id, { - ...queryParams.value, - ...{}, - ...{}, - ...{ filterArrJson: JSON.stringify([...activeDateFilter]) }, - }) - : await fetchSharedViewActiveDate({ - sortsArr: sorts.value, - filtersArr: activeDateFilter, - }) - if (res) { + + try { + const res = !isPublic.value + ? await api.dbViewRow.calendarCount('noco', base.value.id!, meta.value!.id!, viewMeta.value.id, { + ...queryParams.value, + ...{}, + ...{}, + ...{ filterArrJson: JSON.stringify([...activeDateFilter]) }, + }) + : await fetchSharedViewActiveDate({ + sortsArr: sorts.value, + filtersArr: activeDateFilter, + }) activeDates.value = res.map((dateObj: unknown) => dayjs(dateObj)) - } else { + } catch (e) { activeDates.value = [] + message.error(`${t('msg.error.fetchingActiveDates')} ${await extractSdkResponseErrorMsg(e)}`) + console.log(e) } } @@ -554,44 +567,55 @@ const [useProvideCalendarViewStore, useCalendarViewStore] = useInjectionState( async function loadCalendarMeta() { if (!viewMeta?.value?.id || !meta?.value?.columns) return - const res = isPublic.value ? (sharedView.value?.view as CalendarType) : await $api.dbView.calendarRead(viewMeta.value.id) - calendarMetaData.value = res - const calMeta = typeof res.meta === 'string' ? JSON.parse(res.meta) : res.meta - activeCalendarView.value = calMeta?.active_view - if (!activeCalendarView.value) activeCalendarView.value = 'month' - calendarRange.value = res?.calendar_range!.map((range: any) => { - return { - fk_from_col: meta.value?.columns!.find((col) => col.id === range.fk_from_column_id), - fk_to_col: range.fk_to_column_id ? meta.value?.columns!.find((col) => col.id === range.fk_to_column_id) : null, - } - }) as any + try { + const res = isPublic.value ? (sharedView.value?.view as CalendarType) : await $api.dbView.calendarRead(viewMeta.value.id) + calendarMetaData.value = res + const calMeta = typeof res.meta === 'string' ? JSON.parse(res.meta) : res.meta + activeCalendarView.value = calMeta?.active_view + if (!activeCalendarView.value) activeCalendarView.value = 'month' + calendarRange.value = res?.calendar_range?.map((range: any) => { + return { + fk_from_col: meta.value?.columns?.find((col) => col.id === range.fk_from_column_id), + fk_to_col: range.fk_to_column_id ? meta.value?.columns?.find((col) => col.id === range.fk_to_column_id) : null, + } + }) as any + } catch (e) { + message.error(`Error loading calendar meta ${await extractSdkResponseErrorMsg(e)}`) + } } async function loadCalendarData() { if ((!base?.value?.id || !meta.value?.id || !viewMeta.value?.id || !filterJSON.value) && !isPublic?.value) return - isCalendarDataLoading.value = true - const res = !isPublic.value - ? await api.dbViewRow.list( - 'noco', - base.value.id!, - meta.value!.id!, - viewMeta.value!.id!, - { - ...queryParams.value, - ...(isUIAllowed('filterSync') - ? { filterArrJson: JSON.stringify([...filterJSON.value]) } - : { filterArrJson: JSON.stringify([nestedFilters.value, ...filterJSON.value]) }), - where: where?.value ?? '', - }, - { - headers: { - 'xc-ignore-pagination': true, + try { + isCalendarDataLoading.value = true + + const res = !isPublic.value + ? await api.dbViewRow.list( + 'noco', + base.value.id!, + meta.value!.id!, + viewMeta.value!.id!, + { + ...queryParams.value, + ...(isUIAllowed('filterSync') + ? { filterArrJson: JSON.stringify([...filterJSON.value]) } + : { filterArrJson: JSON.stringify([nestedFilters.value, ...filterJSON.value]) }), + where: where?.value ?? '', }, - }, - ) - : await fetchSharedViewData({ sortsArr: sorts.value, filtersArr: filterJSON.value }) - formattedData.value = formatData(res!.list) - isCalendarDataLoading.value = false + { + headers: { + 'xc-ignore-pagination': true, + }, + }, + ) + : await fetchSharedViewData({ sortsArr: sorts.value, filtersArr: filterJSON.value }) + formattedData.value = formatData(res!.list) + } catch (e) { + message.error(`${t('msg.error.fetchingCalendarData')} ${await extractSdkResponseErrorMsg(e)}`) + console.log(e) + } finally { + isCalendarDataLoading.value = false + } } async function updateCalendarMeta(updateObj: Partial) { @@ -662,18 +686,24 @@ const [useProvideCalendarViewStore, useCalendarViewStore] = useInjectionState( const loadSidebarData = async () => { if (!base?.value?.id || !meta.value?.id || !viewMeta.value?.id) return - isSidebarLoading.value = true - const res = !isPublic.value - ? await api.dbViewRow.list('noco', base.value.id!, meta.value!.id!, viewMeta.value.id, { - ...queryParams.value, - ...{}, - ...{}, - ...{ filterArrJson: JSON.stringify([...sideBarFilter.value]) }, - }) - : await fetchSharedViewData({ sortsArr: sorts.value, filtersArr: sideBarFilter.value }) + try { + isSidebarLoading.value = true + const res = !isPublic.value + ? await api.dbViewRow.list('noco', base.value.id!, meta.value!.id!, viewMeta.value.id, { + ...queryParams.value, + ...{}, + ...{}, + ...{ filterArrJson: JSON.stringify([...sideBarFilter.value]) }, + }) + : await fetchSharedViewData({ sortsArr: sorts.value, filtersArr: sideBarFilter.value }) - formattedSideBarData.value = formatData(res!.list) - isSidebarLoading.value = false + formattedSideBarData.value = formatData(res!.list) + } catch (e) { + message.error(`${t('msg.error.fetchingCalendarData')} ${await extractSdkResponseErrorMsg(e)}`) + console.log(e) + } finally { + isSidebarLoading.value = false + } } async function updateRowProperty(toUpdate: Row, property: string[], undo = false) { diff --git a/packages/nc-gui/lang/en.json b/packages/nc-gui/lang/en.json index 5018386fa2..b769565cdb 100644 --- a/packages/nc-gui/lang/en.json +++ b/packages/nc-gui/lang/en.json @@ -692,6 +692,7 @@ "showFieldOnConditionsMet":"Shows field only when conditions are met" }, "activity": { + "noRange": "Calendar view requires a date range", "goToToday": "Go to Today", "toggleSidebar": "Toggle Sidebar", "addEndDate": "Add end date", @@ -1296,6 +1297,8 @@ "upgradeToEnterpriseEdition": "Upgrade to Enterprise Edition {extraInfo}" }, "error": { + "fetchingCalendarData": "Error fetching calendar data", + "fetchingActiveDates": "Error fetching active dates", "scopesRequired": "Scopes required", "authUrlRequired": "Auth URL is required", "userNameAttributeRequired": "Username attribute is required", diff --git a/packages/nocodb/src/services/datas.service.ts b/packages/nocodb/src/services/datas.service.ts index 533adca734..07250afc22 100644 --- a/packages/nocodb/src/services/datas.service.ts +++ b/packages/nocodb/src/services/datas.service.ts @@ -221,9 +221,9 @@ export class DatasService { if (view.type !== ViewTypes.CALENDAR) NcError.badRequest('View is not a calendar view'); - const { ranges } = await CalendarRange.read(view.id); + const calendarRange = await CalendarRange.read(view.id); - if (!ranges.length) NcError.badRequest('No ranges found'); + if (!calendarRange?.ranges?.length) NcError.badRequest('No ranges found'); const model = await Model.getByIdOrName({ id: view.fk_model_id, @@ -239,7 +239,7 @@ export class DatasService { const dates: Array = []; - ranges.forEach((range: any) => { + calendarRange.ranges.forEach((range: any) => { data.list.forEach((date) => { const from = date[ diff --git a/packages/nocodb/src/services/public-datas.service.ts b/packages/nocodb/src/services/public-datas.service.ts index 338e4a879c..d3c21e66d3 100644 --- a/packages/nocodb/src/services/public-datas.service.ts +++ b/packages/nocodb/src/services/public-datas.service.ts @@ -12,7 +12,7 @@ import { nocoExecute } from 'nc-help'; import dayjs from 'dayjs'; import type { LinkToAnotherRecordColumn } from '~/models'; -import { CalendarRange } from '~/models'; +import { CalendarRange, Column, Model, Source, View } from '~/models'; import { NcError } from '~/helpers/catchError'; import getAst from '~/helpers/getAst'; import NcPluginMgrv2 from '~/helpers/NcPluginMgrv2'; @@ -20,7 +20,6 @@ import { PagedResponseImpl } from '~/helpers/PagedResponse'; import { getColumnByIdOrName } from '~/modules/datas/helpers'; import NcConnectionMgrv2 from '~/utils/common/NcConnectionMgrv2'; import { mimeIcons } from '~/utils/mimeTypes'; -import { Column, Model, Source, View } from '~/models'; import { utf8ify } from '~/helpers/stringHelpers'; // todo: move to utils @@ -121,7 +120,10 @@ export class PublicDatasService { if (view.type !== ViewTypes.CALENDAR) NcError.badRequest('View is not a calendar view'); - const { ranges } = await CalendarRange.read(view.id); + const calendarRange = await CalendarRange.read(view.id); + + if (!calendarRange?.ranges?.length) + NcError.notFound('Calendar ranges are required in a calendar view'); const model = await Model.getByIdOrName({ id: view.fk_model_id, @@ -139,7 +141,7 @@ export class PublicDatasService { const dates: Array = []; - ranges.forEach((range: any) => { + calendarRange.ranges.forEach((range: any) => { data.list.forEach((date) => { const from = date[columns.find((c) => c.id === range.fk_from_column_id).title];