diff --git a/packages/nocodb/src/helpers/getAst.ts b/packages/nocodb/src/helpers/getAst.ts index 45be578e58..a13eb0f363 100644 --- a/packages/nocodb/src/helpers/getAst.ts +++ b/packages/nocodb/src/helpers/getAst.ts @@ -57,8 +57,8 @@ const getAst = async ({ const kanban = await KanbanView.get(view.id); coverImageId = kanban.fk_cover_image_col_id; } else if (view && view.type === ViewTypes.CALENDAR) { - const calendar = await CalendarView.get(view.id); - coverImageId = calendar.fk_cover_image_col_id; + // const calendar = await CalendarView.get(view.id); + // coverImageId = calendar.fk_cover_image_col_id; const calenderRanges = await CalendarRange.read(view.id); if (calenderRanges) { dependencyFieldsForCalenderView = calenderRanges.ranges diff --git a/packages/nocodb/src/models/View.ts b/packages/nocodb/src/models/View.ts index b01781bb3c..7e40d94991 100644 --- a/packages/nocodb/src/models/View.ts +++ b/packages/nocodb/src/models/View.ts @@ -571,6 +571,9 @@ export default class View implements ViewType { case ViewTypes.KANBAN: await KanbanViewColumn.insert(modifiedInsertObj, ncMeta); break; + case ViewTypes.CALENDAR: + await CalendarViewColumn.insert(modifiedInsertObj, ncMeta); + break; } } } @@ -1503,191 +1506,6 @@ export default class View implements ViewType { await NocoCache.del(deleteKeys); } - private static extractViewColumnsTableName(view: View) { - let table; - switch (view.type) { - case ViewTypes.GRID: - table = MetaTable.GRID_VIEW_COLUMNS; - break; - case ViewTypes.GALLERY: - table = MetaTable.GALLERY_VIEW_COLUMNS; - break; - case ViewTypes.KANBAN: - table = MetaTable.KANBAN_VIEW_COLUMNS; - break; - case ViewTypes.FORM: - table = MetaTable.FORM_VIEW_COLUMNS; - break; - case ViewTypes.MAP: - table = MetaTable.MAP_VIEW_COLUMNS; - break; - case ViewTypes.CALENDAR: - table = MetaTable.CALENDAR_VIEW_COLUMNS; - break; - } - return table; - } - - private static extractViewTableName(view: View) { - let table; - switch (view.type) { - case ViewTypes.GRID: - table = MetaTable.GRID_VIEW; - break; - case ViewTypes.GALLERY: - table = MetaTable.GALLERY_VIEW; - break; - case ViewTypes.KANBAN: - table = MetaTable.KANBAN_VIEW; - break; - case ViewTypes.FORM: - table = MetaTable.FORM_VIEW; - break; - case ViewTypes.MAP: - table = MetaTable.MAP_VIEW; - break; - case ViewTypes.CALENDAR: - table = MetaTable.CALENDAR_VIEW; - break; - } - return table; - } - - private static extractViewColumnsTableNameScope(view: View) { - let scope; - switch (view.type) { - case ViewTypes.GRID: - scope = CacheScope.GRID_VIEW_COLUMN; - break; - case ViewTypes.GALLERY: - scope = CacheScope.GALLERY_VIEW_COLUMN; - break; - case ViewTypes.MAP: - scope = CacheScope.MAP_VIEW_COLUMN; - break; - case ViewTypes.KANBAN: - scope = CacheScope.KANBAN_VIEW_COLUMN; - break; - case ViewTypes.FORM: - scope = CacheScope.FORM_VIEW_COLUMN; - break; - case ViewTypes.CALENDAR: - scope = CacheScope.CALENDAR_VIEW_COLUMN; - break; - } - return scope; - } - - private static extractViewTableNameScope(view: View) { - let scope; - switch (view.type) { - case ViewTypes.GRID: - scope = CacheScope.GRID_VIEW; - break; - case ViewTypes.GALLERY: - scope = CacheScope.GALLERY_VIEW; - break; - case ViewTypes.MAP: - scope = CacheScope.MAP_VIEW; - break; - case ViewTypes.KANBAN: - scope = CacheScope.KANBAN_VIEW; - break; - case ViewTypes.FORM: - scope = CacheScope.FORM_VIEW; - break; - case ViewTypes.CALENDAR: - scope = CacheScope.CALENDAR_VIEW; - break; - } - return scope; - } - - async getModel(ncMeta = Noco.ncMeta): Promise { - return (this.model = await Model.getByIdOrName( - { id: this.fk_model_id }, - ncMeta, - )); - } - - async getModelWithInfo(ncMeta = Noco.ncMeta): Promise { - return (this.model = await Model.getWithInfo( - { id: this.fk_model_id }, - ncMeta, - )); - } - - async getView(): Promise { - switch (this.type) { - case ViewTypes.GRID: - this.view = await GridView.get(this.id); - break; - case ViewTypes.KANBAN: - this.view = await KanbanView.get(this.id); - break; - case ViewTypes.GALLERY: - this.view = await GalleryView.get(this.id); - break; - case ViewTypes.MAP: - this.view = await MapView.get(this.id); - break; - case ViewTypes.FORM: - this.view = await FormView.get(this.id); - break; - case ViewTypes.CALENDAR: - this.view = await CalendarView.get(this.id); - break; - } - return this.view; - } - - async getViewWithInfo( - ncMeta = Noco.ncMeta, - ): Promise { - switch (this.type) { - case ViewTypes.GRID: - this.view = await GridView.getWithInfo(this.id, ncMeta); - break; - case ViewTypes.KANBAN: - this.view = await KanbanView.get(this.id, ncMeta); - break; - case ViewTypes.GALLERY: - this.view = await GalleryView.get(this.id, ncMeta); - break; - case ViewTypes.MAP: - this.view = await MapView.get(this.id, ncMeta); - break; - case ViewTypes.FORM: - this.view = await FormView.get(this.id, ncMeta); - break; - case ViewTypes.CALENDAR: - this.view = await CalendarView.get(this.id, ncMeta); - break; - } - return this.view; - } - - public async getFilters(ncMeta = Noco.ncMeta) { - return (this.filter = (await Filter.getFilterObject( - { - viewId: this.id, - }, - ncMeta, - )) as any); - } - - public async getSorts(ncMeta = Noco.ncMeta) { - return (this.sorts = await Sort.list({ viewId: this.id }, ncMeta)); - } - - async getColumns(ncMeta = Noco.ncMeta) { - return (this.columns = await View.getColumns(this.id, ncMeta)); - } - - async delete(ncMeta = Noco.ncMeta) { - await View.delete(this.id, ncMeta); - } - static async bulkColumnInsertToViews( { columns, @@ -1705,6 +1523,7 @@ export default class View implements ViewType { | FormViewColumn | KanbanViewColumn | MapViewColumn + | CalendarViewColumn )[]; }, view: View, @@ -1811,6 +1630,16 @@ export default class View implements ViewType { } } else if (view.type === ViewTypes.FORM && isSystemColumn(column)) { show = false; + } else if (view.type === ViewTypes.CALENDAR && !copyFromView) { + const calendarRange = await CalendarRange.read(view.id, ncMeta); + if (!calendarRange) break; + const calendarRangeColumns = calendarRange.ranges + .map((range) => [range.fk_from_column_id, range.fk_to_column_id]) + .flat(); + + if (calendarRangeColumns.includes(column.id)) { + show = true; + } } insertObjs.push({ @@ -1865,14 +1694,24 @@ export default class View implements ViewType { insertObjs, ); break; + case ViewTypes.CALENDAR: + await ncMeta.bulkMetaInsert( + null, + null, + MetaTable.CALENDAR_VIEW_COLUMNS, + insertObjs, + ); } } static async insertMetaOnly( view: Partial & - Partial & { + Partial< + FormView | GridView | GalleryView | KanbanView | MapView | CalendarView + > & { copy_from_id?: string; fk_grp_col_id?: string; + calendar_range?: Partial[]; }, model: { getColumns: () => Promise; @@ -1979,6 +1818,26 @@ export default class View implements ViewType { ncMeta, ); break; + case ViewTypes.CALENDAR: { + const obj = extractProps(view, ['calendar_range']); + if (!obj.calendar_range) break; + const calendarRange = obj.calendar_range as Partial[]; + calendarRange.forEach((range) => { + range.fk_view_id = view_id; + }); + + await CalendarRange.bulkInsert(calendarRange, ncMeta); + await CalendarView.insert( + { + ...(copyFromView?.view || {}), + ...view, + fk_view_id: view_id, + }, + ncMeta, + ); + + break; + } } // copy from view @@ -2065,4 +1924,189 @@ export default class View implements ViewType { return insertedView; } + + private static extractViewColumnsTableName(view: View) { + let table; + switch (view.type) { + case ViewTypes.GRID: + table = MetaTable.GRID_VIEW_COLUMNS; + break; + case ViewTypes.GALLERY: + table = MetaTable.GALLERY_VIEW_COLUMNS; + break; + case ViewTypes.KANBAN: + table = MetaTable.KANBAN_VIEW_COLUMNS; + break; + case ViewTypes.FORM: + table = MetaTable.FORM_VIEW_COLUMNS; + break; + case ViewTypes.MAP: + table = MetaTable.MAP_VIEW_COLUMNS; + break; + case ViewTypes.CALENDAR: + table = MetaTable.CALENDAR_VIEW_COLUMNS; + break; + } + return table; + } + + private static extractViewTableName(view: View) { + let table; + switch (view.type) { + case ViewTypes.GRID: + table = MetaTable.GRID_VIEW; + break; + case ViewTypes.GALLERY: + table = MetaTable.GALLERY_VIEW; + break; + case ViewTypes.KANBAN: + table = MetaTable.KANBAN_VIEW; + break; + case ViewTypes.FORM: + table = MetaTable.FORM_VIEW; + break; + case ViewTypes.MAP: + table = MetaTable.MAP_VIEW; + break; + case ViewTypes.CALENDAR: + table = MetaTable.CALENDAR_VIEW; + break; + } + return table; + } + + private static extractViewColumnsTableNameScope(view: View) { + let scope; + switch (view.type) { + case ViewTypes.GRID: + scope = CacheScope.GRID_VIEW_COLUMN; + break; + case ViewTypes.GALLERY: + scope = CacheScope.GALLERY_VIEW_COLUMN; + break; + case ViewTypes.MAP: + scope = CacheScope.MAP_VIEW_COLUMN; + break; + case ViewTypes.KANBAN: + scope = CacheScope.KANBAN_VIEW_COLUMN; + break; + case ViewTypes.FORM: + scope = CacheScope.FORM_VIEW_COLUMN; + break; + case ViewTypes.CALENDAR: + scope = CacheScope.CALENDAR_VIEW_COLUMN; + break; + } + return scope; + } + + private static extractViewTableNameScope(view: View) { + let scope; + switch (view.type) { + case ViewTypes.GRID: + scope = CacheScope.GRID_VIEW; + break; + case ViewTypes.GALLERY: + scope = CacheScope.GALLERY_VIEW; + break; + case ViewTypes.MAP: + scope = CacheScope.MAP_VIEW; + break; + case ViewTypes.KANBAN: + scope = CacheScope.KANBAN_VIEW; + break; + case ViewTypes.FORM: + scope = CacheScope.FORM_VIEW; + break; + case ViewTypes.CALENDAR: + scope = CacheScope.CALENDAR_VIEW; + break; + } + return scope; + } + + async getModel(ncMeta = Noco.ncMeta): Promise { + return (this.model = await Model.getByIdOrName( + { id: this.fk_model_id }, + ncMeta, + )); + } + + async getModelWithInfo(ncMeta = Noco.ncMeta): Promise { + return (this.model = await Model.getWithInfo( + { id: this.fk_model_id }, + ncMeta, + )); + } + + async getView(): Promise { + switch (this.type) { + case ViewTypes.GRID: + this.view = await GridView.get(this.id); + break; + case ViewTypes.KANBAN: + this.view = await KanbanView.get(this.id); + break; + case ViewTypes.GALLERY: + this.view = await GalleryView.get(this.id); + break; + case ViewTypes.MAP: + this.view = await MapView.get(this.id); + break; + case ViewTypes.FORM: + this.view = await FormView.get(this.id); + break; + case ViewTypes.CALENDAR: + this.view = await CalendarView.get(this.id); + break; + } + return this.view; + } + + async getViewWithInfo( + ncMeta = Noco.ncMeta, + ): Promise { + switch (this.type) { + case ViewTypes.GRID: + this.view = await GridView.getWithInfo(this.id, ncMeta); + break; + case ViewTypes.KANBAN: + this.view = await KanbanView.get(this.id, ncMeta); + break; + case ViewTypes.GALLERY: + this.view = await GalleryView.get(this.id, ncMeta); + break; + case ViewTypes.MAP: + this.view = await MapView.get(this.id, ncMeta); + break; + case ViewTypes.FORM: + this.view = await FormView.get(this.id, ncMeta); + break; + case ViewTypes.CALENDAR: + this.view = await CalendarView.get(this.id, ncMeta); + break; + } + return this.view; + } + + public async getFilters(ncMeta = Noco.ncMeta) { + return (this.filter = (await Filter.getFilterObject( + { + viewId: this.id, + }, + ncMeta, + )) as any); + } + + public async getSorts(ncMeta = Noco.ncMeta) { + return (this.sorts = await Sort.list({ viewId: this.id }, ncMeta)); + } + + async getColumns(ncMeta = Noco.ncMeta) { + return (this.columns = await View.getColumns(this.id, ncMeta)); + } + + async delete(ncMeta = Noco.ncMeta) { + await View.delete(this.id, ncMeta); + } } diff --git a/packages/nocodb/src/services/calendars.service.ts b/packages/nocodb/src/services/calendars.service.ts index bad0135c5b..dd7c225fae 100644 --- a/packages/nocodb/src/services/calendars.service.ts +++ b/packages/nocodb/src/services/calendars.service.ts @@ -9,7 +9,9 @@ import type { NcRequest } from '~/interface/config'; import { AppHooksService } from '~/services/app-hooks/app-hooks.service'; import { validatePayload } from '~/helpers'; import { NcError } from '~/helpers/catchError'; -import { CalendarView, View } from '~/models'; +import { CalendarView, Model, View } from '~/models'; +import NocoCache from '~/cache/NocoCache'; +import { CacheScope } from '~/utils/globals'; @Injectable() export class CalendarsService { @@ -30,12 +32,26 @@ export class CalendarsService { param.calendar, ); - const view = await View.insert({ - ...param.calendar, - // todo: sanitize - fk_model_id: param.tableId, - type: ViewTypes.CALENDAR, - }); + const model = await Model.get(param.tableId); + + const { id } = await View.insertMetaOnly( + { + ...param.calendar, + fk_model_id: param.tableId, + type: ViewTypes.CALENDAR, + base_id: model.base_id, + source_id: model.source_id, + }, + model, + ); + + const view = await View.get(id); + + await NocoCache.appendToList( + CacheScope.VIEW, + [view.fk_model_id], + `${CacheScope.VIEW}:${id}`, + ); this.appHooksService.emit(AppEvents.VIEW_CREATE, { view,