Browse Source

geodata: add MapViewColumn (swagger, model, migration, API)

pull/4140/head
flisowna 2 years ago
parent
commit
bb7e3d5b27
  1. 4
      packages/nc-gui/components/smartsheet/Toolbar.vue
  2. 9
      packages/nocodb-sdk/src/lib/Api.ts
  3. 5
      packages/nocodb/src/lib/meta/api/dataApis/dataAliasApis.ts
  4. 1
      packages/nocodb/src/lib/meta/api/viewColumnApis.ts
  5. 4
      packages/nocodb/src/lib/migrations/XcMigrationSourcev2.ts
  6. 34
      packages/nocodb/src/lib/migrations/v2/nc_022_map_view_column.ts
  7. 106
      packages/nocodb/src/lib/models/MapViewColumn.ts
  8. 92
      packages/nocodb/src/lib/models/View.ts
  9. 3
      packages/nocodb/src/lib/utils/globals.ts
  10. 28
      scripts/sdk/swagger.json

4
packages/nc-gui/components/smartsheet/Toolbar.vue

@ -1,7 +1,7 @@
<script setup lang="ts">
import { IsPublicInj, inject, ref, useSharedView, useSidebar, useSmartsheetStoreOrThrow, useUIPermission } from '#imports'
const { isGrid, isForm, isGallery, isKanban, isSqlView } = useSmartsheetStoreOrThrow()
const { isGrid, isForm, isGallery, isKanban, isMap, isSqlView } = useSmartsheetStoreOrThrow()
const isPublic = inject(IsPublicInj, ref(false))
@ -29,7 +29,7 @@ const { allowCSVDownload } = useSharedView()
<LazySmartsheetToolbarKanbanStackEditOrAdd v-if="isKanban" />
<LazySmartsheetToolbarFieldsMenu v-if="isGrid || isGallery || isKanban" :show-system-fields="false" />
<LazySmartsheetToolbarFieldsMenu v-if="isGrid || isGallery || isKanban || isMap" :show-system-fields="false" />
<LazySmartsheetToolbarColumnFilterMenu v-if="isGrid || isGallery || isKanban" />

9
packages/nocodb-sdk/src/lib/Api.ts

@ -402,9 +402,18 @@ export interface MapType {
initial_geo_position?: GeoLocationType;
fk_model_id?: string;
fk_geo_data_col_id?: string | null;
columns?: MapColumnType[];
meta?: string | object;
}
export interface MapColumnType {
id?: string;
label?: string;
help?: string;
fk_col_id?: string;
fk_gallery_id?: string;
}
export interface FormType {
id?: string;
title?: string;

5
packages/nocodb/src/lib/meta/api/dataApis/dataAliasApis.ts

@ -14,7 +14,10 @@ import getAst from '../../../db/sql-data-mapper/lib/sql/helpers/getAst';
// todo: Handle the error case where view doesnt belong to model
async function dataList(req: Request, res: Response) {
const { model, view } = await getViewAndModelFromRequestByAliasOrId(req);
res.json(await getDataList(model, view, req));
const FOO_DATA = await getDataList(model, view, req);
console.log('FOO_DATA');
console.log(FOO_DATA);
res.json(FOO_DATA);
}
async function dataFindOne(req: Request, res: Response) {

1
packages/nocodb/src/lib/meta/api/viewColumnApis.ts

@ -8,6 +8,7 @@ export async function columnList(req: Request, res: Response) {
res.json(await View.getColumns(req.params.viewId));
}
export async function columnAdd(req: Request, res: Response) {
console.log('FOO - columnAdd');
const viewColumn = await View.insertOrUpdateColumn(
req.params.viewId,
req.body.fk_column_id,

4
packages/nocodb/src/lib/migrations/XcMigrationSourcev2.ts

@ -9,6 +9,7 @@ import * as nc_018_add_meta_in_view from './v2/nc_018_add_meta_in_view';
import * as nc_019_add_meta_in_meta_tables from './v2/nc_019_add_meta_in_meta_tables';
import * as nc_020_kanban_view from './v2/nc_020_kanban_view';
import * as nc_021_map_view from './v2/nc_021_map_view';
import * as nc_022_map_view_column from './v2/nc_022_map_view_column';
// Create a custom migration source class
export default class XcMigrationSourcev2 {
@ -29,6 +30,7 @@ export default class XcMigrationSourcev2 {
'nc_019_add_meta_in_meta_tables',
'nc_020_kanban_view',
'nc_021_map_view',
'nc_022_map_view_column',
]);
}
@ -60,6 +62,8 @@ export default class XcMigrationSourcev2 {
return nc_020_kanban_view;
case 'nc_021_map_view':
return nc_021_map_view;
case 'nc_022_map_view_column':
return nc_022_map_view_column;
}
}
}

34
packages/nocodb/src/lib/migrations/v2/nc_022_map_view_column.ts

@ -0,0 +1,34 @@
import { MetaTable } from '../../utils/globals';
const up = async (knex) => {
await knex.schema.createTable(MetaTable.MAP_VIEW_COLUMNS, (table) => {
table.string('id', 20).primary().notNullable();
table.string('base_id', 20);
// table.foreign('base_id').references(`${MetaTable.BASES}.id`);
table.string('project_id', 128);
// table.foreign('project_id').references(`${MetaTable.PROJECT}.id`);
table.string('fk_view_id', 20);
table.foreign('fk_view_id').references(`${MetaTable.MAP_VIEW}.fk_view_id`);
table.string('fk_column_id', 20);
table.foreign('fk_column_id').references(`${MetaTable.COLUMNS}.id`);
table.string('uuid');
// todo: type
table.string('label');
table.string('help');
table.boolean('show');
table.float('order');
table.timestamps(true, true);
});
};
const down = async (knex) => {
await knex.schema.dropTable(MetaTable.MAP_VIEW_COLUMNS);
};
export { up, down };

106
packages/nocodb/src/lib/models/MapViewColumn.ts

@ -0,0 +1,106 @@
import Noco from '../Noco';
import { CacheGetType, CacheScope, MetaTable } from '../utils/globals';
import View from './View';
import NocoCache from '../cache/NocoCache';
export default class MapViewColumn {
id: string;
title?: string;
show?: boolean;
order?: number;
fk_view_id: string;
fk_column_id: string;
project_id?: string;
base_id?: string;
constructor(data: MapViewColumn) {
Object.assign(this, data);
}
public static async get(mapViewColumnId: string, ncMeta = Noco.ncMeta) {
let view =
mapViewColumnId &&
(await NocoCache.get(
`${CacheScope.MAP_VIEW_COLUMN}:${mapViewColumnId}`,
CacheGetType.TYPE_OBJECT
));
if (!view) {
view = await ncMeta.metaGet2(
null,
null,
MetaTable.MAP_VIEW_COLUMNS,
mapViewColumnId
);
await NocoCache.set(
`${CacheScope.MAP_VIEW_COLUMN}:${mapViewColumnId}`,
view
);
}
return view && new MapViewColumn(view);
}
static async insert(column: Partial<MapViewColumn>, ncMeta = Noco.ncMeta) {
const insertObj = {
fk_view_id: column.fk_view_id,
fk_column_id: column.fk_column_id,
order: await ncMeta.metaGetNextOrder(MetaTable.MAP_VIEW_COLUMNS, {
fk_view_id: column.fk_view_id,
}),
show: column.show,
project_id: column.project_id,
base_id: column.base_id,
};
if (!(column.project_id && column.base_id)) {
const viewRef = await View.get(column.fk_view_id, ncMeta);
insertObj.project_id = viewRef.project_id;
insertObj.base_id = viewRef.base_id;
}
const { id, fk_column_id } = await ncMeta.metaInsert2(
null,
null,
MetaTable.MAP_VIEW_COLUMNS,
insertObj
);
await NocoCache.set(`${CacheScope.MAP_VIEW_COLUMN}:${fk_column_id}`, id);
// if cache is not present skip pushing it into the list to avoid unexpected behaviour
if (
(await NocoCache.getList(CacheScope.MAP_VIEW_COLUMN, [column.fk_view_id]))
?.length
)
await NocoCache.appendToList(
CacheScope.MAP_VIEW_COLUMN,
[column.fk_view_id],
`${CacheScope.MAP_VIEW_COLUMN}:${id}`
);
return this.get(id, ncMeta);
}
public static async list(
viewId: string,
ncMeta = Noco.ncMeta
): Promise<MapViewColumn[]> {
let views = await NocoCache.getList(CacheScope.MAP_VIEW_COLUMN, [viewId]);
if (!views.length) {
views = await ncMeta.metaList2(null, null, MetaTable.MAP_VIEW_COLUMNS, {
condition: {
fk_view_id: viewId,
},
orderBy: {
order: 'asc',
},
});
await NocoCache.setList(CacheScope.MAP_VIEW_COLUMN, [viewId], views);
}
views.sort(
(a, b) =>
(a.order != null ? a.order : Infinity) -
(b.order != null ? b.order : Infinity)
);
return views?.map((v) => new MapViewColumn(v));
}
}

92
packages/nocodb/src/lib/models/View.ts

@ -20,6 +20,8 @@ import KanbanViewColumn from './KanbanViewColumn';
import Column from './Column';
import NocoCache from '../cache/NocoCache';
import { extractProps } from '../meta/helpers/extractProps';
import MapView from './MapView';
import MapViewColumn from './MapViewColumn';
const { v4: uuidv4 } = require('uuid');
export default class View implements ViewType {
@ -35,9 +37,13 @@ export default class View implements ViewType {
fk_model_id: string;
model?: Model;
view?: FormView | GridView | KanbanView | GalleryView;
view?: FormView | GridView | KanbanView | GalleryView | MapView;
columns?: Array<
FormViewColumn | GridViewColumn | GalleryViewColumn | KanbanViewColumn
| FormViewColumn
| GridViewColumn
| GalleryViewColumn
| KanbanViewColumn
| MapViewColumn
>;
sorts: Sort[];
@ -76,6 +82,9 @@ export default class View implements ViewType {
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;
@ -96,6 +105,9 @@ export default class View implements ViewType {
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;
@ -223,7 +235,7 @@ export default class View implements ViewType {
static async insert(
view: Partial<View> &
Partial<FormView | GridView | GalleryView | KanbanView> & {
Partial<FormView | GridView | GalleryView | KanbanView | MapView> & {
copy_from_id?: string;
fk_grp_col_id?: string;
created_at?;
@ -289,6 +301,15 @@ export default class View implements ViewType {
ncMeta
);
break;
case ViewTypes.MAP:
await MapView.insert(
{
...(view as MapView),
fk_view_id: view_id,
},
ncMeta
);
break;
case ViewTypes.GALLERY:
await GalleryView.insert(
{
@ -395,7 +416,9 @@ export default class View implements ViewType {
} else {
show = false;
}
} else if (view.type === ViewTypes.KANBAN && !copyFromView) {
}
// TODO: Check whether/what we need to do here for properly integrate MapView
else if (view.type === ViewTypes.KANBAN && !copyFromView) {
const kanbanView = await KanbanView.get(view_id, ncMeta);
if (vCol.id === kanbanView?.fk_grp_col_id) {
// include grouping field if it exists
@ -475,6 +498,16 @@ export default class View implements ViewType {
ncMeta
);
break;
case ViewTypes.MAP:
await MapViewColumn.insert(
{
...insertObj,
fk_view_id: view.id,
},
ncMeta
);
break;
case ViewTypes.KANBAN:
await KanbanViewColumn.insert(
{
@ -524,6 +557,17 @@ export default class View implements ViewType {
);
}
break;
case ViewTypes.MAP:
{
col = await MapViewColumn.insert(
{
...param,
fk_view_id: view.id,
},
ncMeta
);
}
break;
case ViewTypes.FORM:
{
col = await FormViewColumn.insert(
@ -564,7 +608,11 @@ export default class View implements ViewType {
ncMeta = Noco.ncMeta
): Promise<
Array<
GridViewColumn | FormViewColumn | GalleryViewColumn | KanbanViewColumn
| GridViewColumn
| FormViewColumn
| GalleryViewColumn
| KanbanViewColumn
| MapViewColumn
>
> {
let columns: Array<GridViewColumn | any> = [];
@ -578,6 +626,9 @@ export default class View implements ViewType {
case ViewTypes.GALLERY:
columns = await GalleryViewColumn.list(viewId, ncMeta);
break;
case ViewTypes.MAP:
columns = await MapViewColumn.list(viewId, ncMeta);
break;
case ViewTypes.FORM:
columns = await FormViewColumn.list(viewId, ncMeta);
break;
@ -611,6 +662,10 @@ export default class View implements ViewType {
table = MetaTable.GRID_VIEW_COLUMNS;
cacheScope = CacheScope.GRID_VIEW_COLUMN;
break;
case ViewTypes.MAP:
table = MetaTable.MAP_VIEW_COLUMNS;
cacheScope = CacheScope.MAP_VIEW_COLUMN;
break;
case ViewTypes.GALLERY:
table = MetaTable.GALLERY_VIEW_COLUMNS;
cacheScope = CacheScope.GALLERY_VIEW_COLUMN;
@ -649,7 +704,12 @@ export default class View implements ViewType {
},
ncMeta = Noco.ncMeta
): Promise<
GridViewColumn | FormViewColumn | GalleryViewColumn | KanbanViewColumn | any
| GridViewColumn
| FormViewColumn
| GalleryViewColumn
| KanbanViewColumn
| MapViewColumn
| any
> {
const view = await this.get(viewId);
const table = this.extractViewColumnsTableName(view);
@ -696,6 +756,14 @@ export default class View implements ViewType {
show: colData.show,
});
break;
case ViewTypes.MAP:
return await MapViewColumn.insert({
fk_view_id: viewId,
fk_column_id: fkColId,
order: colData.order,
show: colData.show,
});
break;
case ViewTypes.FORM:
return await FormViewColumn.insert({
fk_view_id: viewId,
@ -915,6 +983,9 @@ export default class View implements ViewType {
case ViewTypes.FORM:
table = MetaTable.FORM_VIEW_COLUMNS;
break;
case ViewTypes.MAP:
table = MetaTable.MAP_VIEW_COLUMNS;
break;
}
return table;
}
@ -934,6 +1005,9 @@ export default class View implements ViewType {
case ViewTypes.FORM:
table = MetaTable.FORM_VIEW;
break;
case ViewTypes.MAP:
table = MetaTable.MAP_VIEW;
break;
}
return table;
}
@ -947,6 +1021,9 @@ export default class View implements ViewType {
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;
@ -966,6 +1043,9 @@ export default class View implements ViewType {
case ViewTypes.GALLERY:
scope = CacheScope.GALLERY_VIEW;
break;
case ViewTypes.MAP:
scope = CacheScope.MAP_VIEW;
break;
case ViewTypes.KANBAN:
scope = CacheScope.KANBAN_VIEW;
break;

3
packages/nocodb/src/lib/utils/globals.ts

@ -38,6 +38,7 @@ export enum MetaTable {
SYNC_SOURCE = 'nc_sync_source_v2',
SYNC_LOGS = 'nc_sync_logs_v2',
MAP_VIEW = 'nc_map_view_v2',
MAP_VIEW_COLUMNS = 'nc_map_view_columns_v2',
}
export const orderedMetaTables = [
@ -50,6 +51,7 @@ export const orderedMetaTables = [
MetaTable.PROJECT_USERS,
MetaTable.USERS,
MetaTable.MAP_VIEW,
MetaTable.MAP_VIEW_COLUMNS,
MetaTable.KANBAN_VIEW_COLUMNS,
MetaTable.KANBAN_VIEW,
MetaTable.GRID_VIEW_COLUMNS,
@ -99,6 +101,7 @@ export enum CacheScope {
GRID_VIEW_COLUMN = 'gridViewColumn',
KANBAN_VIEW = 'kanbanView',
MAP_VIEW = 'mapView',
MAP_VIEW_COLUMN = 'mapViewColumn',
KANBAN_VIEW_COLUMN = 'kanbanViewColumn',
USER = 'user',
ORGS = 'orgs',

28
scripts/sdk/swagger.json

@ -8071,6 +8071,12 @@
"null"
]
},
"columns": {
"type": "array",
"items": {
"$ref": "#/components/schemas/MapColumn"
}
},
"meta": {
"type": [
"string",
@ -8079,6 +8085,28 @@
}
}
},
"MapColumn": {
"title": "MapColumn",
"type": "object",
"description": "",
"properties": {
"id": {
"type": "string"
},
"label": {
"type": "string"
},
"help": {
"type": "string"
},
"fk_col_id": {
"type": "string"
},
"fk_gallery_id": {
"type": "string"
}
}
},
"Form": {
"title": "Form",
"type": "object",

Loading…
Cancel
Save