Browse Source

Merge pull request #7687 from nocodb/nc-feat/calendar-data-controller

fix(nc-gui): error handling
pull/7704/head
Pranav C 7 months ago committed by GitHub
parent
commit
5e00b832a2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 69
      packages/nc-gui/components/smartsheet/calendar/index.vue
  2. 146
      packages/nc-gui/composables/useCalendarViewStore.ts
  3. 3
      packages/nc-gui/lang/en.json
  4. 6
      packages/nocodb/src/services/datas.service.ts
  5. 10
      packages/nocodb/src/services/public-datas.service.ts

69
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(() => {
</NcButton>
</NcTooltip>
</div>
<LazySmartsheetCalendarYearView v-if="activeCalendarView === 'year'" />
<template v-if="!isCalendarDataLoading">
<LazySmartsheetCalendarMonthView
v-if="activeCalendarView === 'month'"
@expand-record="expandRecord"
@new-record="newRecord"
/>
<LazySmartsheetCalendarWeekViewDateField
v-else-if="activeCalendarView === 'week' && calDataType === UITypes.Date"
@expand-record="expandRecord"
@new-record="newRecord"
/>
<LazySmartsheetCalendarWeekViewDateTimeField
v-else-if="activeCalendarView === 'week' && calDataType === UITypes.DateTime"
@expand-record="expandRecord"
@new-record="newRecord"
/>
<LazySmartsheetCalendarDayViewDateField
v-else-if="activeCalendarView === 'day' && calDataType === UITypes.Date"
@expand-record="expandRecord"
@new-record="newRecord"
/>
<LazySmartsheetCalendarDayViewDateTimeField
v-else-if="activeCalendarView === 'day' && calDataType === UITypes.DateTime"
@expand-record="expandRecord"
@new-record="newRecord"
/>
<template v-if="calendarRange">
<LazySmartsheetCalendarYearView v-if="activeCalendarView === 'year'" />
<template v-if="!isCalendarDataLoading">
<LazySmartsheetCalendarMonthView
v-if="activeCalendarView === 'month'"
@expand-record="expandRecord"
@new-record="newRecord"
/>
<LazySmartsheetCalendarWeekViewDateField
v-else-if="activeCalendarView === 'week' && calDataType === UITypes.Date"
@expand-record="expandRecord"
@new-record="newRecord"
/>
<LazySmartsheetCalendarWeekViewDateTimeField
v-else-if="activeCalendarView === 'week' && calDataType === UITypes.DateTime"
@expand-record="expandRecord"
@new-record="newRecord"
/>
<LazySmartsheetCalendarDayViewDateField
v-else-if="activeCalendarView === 'day' && calDataType === UITypes.Date"
@expand-record="expandRecord"
@new-record="newRecord"
/>
<LazySmartsheetCalendarDayViewDateTimeField
v-else-if="activeCalendarView === 'day' && calDataType === UITypes.DateTime"
@expand-record="expandRecord"
@new-record="newRecord"
/>
</template>
<div v-if="isCalendarDataLoading && activeCalendarView !== 'year'" class="flex w-full items-center h-full justify-center">
<GeneralLoader size="xlarge" />
</div>
</template>
<template v-else>
<div class="flex w-full items-center h-full justify-center">
{{ $t('activity.noRange') }}
</div>
</template>
<div v-if="isCalendarDataLoading && activeCalendarView !== 'year'" class="flex w-full items-center h-full justify-center">
<GeneralLoader size="xlarge" />
</div>
</div>
<LazySmartsheetCalendarSideMenu
v-if="!isMobileMode"

146
packages/nc-gui/composables/useCalendarViewStore.ts

@ -25,7 +25,14 @@ const formatData = (list: Record<string, any>[]) =>
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<string | undefined>,
) => {
@ -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<CalendarType>) {
@ -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) {

3
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",

6
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<string> = [];
ranges.forEach((range: any) => {
calendarRange.ranges.forEach((range: any) => {
data.list.forEach((date) => {
const from =
date[

10
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<string> = [];
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];

Loading…
Cancel
Save