mirror of https://github.com/nocodb/nocodb
Pranav C
2 years ago
11 changed files with 516 additions and 21 deletions
@ -0,0 +1,75 @@ |
|||||||
|
import { Request, Response, Router } from 'express'; |
||||||
|
import * as XLSX from 'xlsx'; |
||||||
|
import ncMetaAclMw from '../../helpers/ncMetaAclMw'; |
||||||
|
import { |
||||||
|
extractCsvData, |
||||||
|
extractXlsxData, |
||||||
|
getViewAndModelFromRequestByAliasOrId, |
||||||
|
} from './helpers'; |
||||||
|
import apiMetrics from '../../helpers/apiMetrics'; |
||||||
|
import View from '../../../models/View'; |
||||||
|
|
||||||
|
async function excelDataExport(req: Request, res: Response) { |
||||||
|
const { model, view } = await getViewAndModelFromRequestByAliasOrId(req); |
||||||
|
let targetView = view; |
||||||
|
if (!targetView) { |
||||||
|
targetView = await View.getDefaultView(model.id); |
||||||
|
} |
||||||
|
const { offset, elapsed, data } = await extractXlsxData(targetView, req); |
||||||
|
const wb = XLSX.utils.book_new(); |
||||||
|
XLSX.utils.book_append_sheet(wb, data, targetView.title); |
||||||
|
const buf = XLSX.write(wb, { type: 'base64', bookType: 'xlsx' }); |
||||||
|
res.set({ |
||||||
|
'Access-Control-Expose-Headers': 'nc-export-offset', |
||||||
|
'nc-export-offset': offset, |
||||||
|
'nc-export-elapsed-time': elapsed, |
||||||
|
'Content-Disposition': `attachment; filename="${encodeURI( |
||||||
|
targetView.title |
||||||
|
)}-export.xlsx"`,
|
||||||
|
}); |
||||||
|
res.end(buf); |
||||||
|
} |
||||||
|
|
||||||
|
async function csvDataExport(req: Request, res: Response) { |
||||||
|
const { model, view } = await getViewAndModelFromRequestByAliasOrId(req); |
||||||
|
let targetView = view; |
||||||
|
if (!targetView) { |
||||||
|
targetView = await View.getDefaultView(model.id); |
||||||
|
} |
||||||
|
const { offset, elapsed, data } = await extractCsvData(targetView, req); |
||||||
|
|
||||||
|
res.set({ |
||||||
|
'Access-Control-Expose-Headers': 'nc-export-offset', |
||||||
|
'nc-export-offset': offset, |
||||||
|
'nc-export-elapsed-time': elapsed, |
||||||
|
'Content-Disposition': `attachment; filename="${encodeURI( |
||||||
|
targetView.title |
||||||
|
)}-export.csv"`,
|
||||||
|
}); |
||||||
|
res.send(data); |
||||||
|
} |
||||||
|
|
||||||
|
const router = Router({ mergeParams: true }); |
||||||
|
|
||||||
|
router.get( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/export/csv', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(csvDataExport, 'exportCsv') |
||||||
|
); |
||||||
|
router.get( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/views/:viewName/export/csv', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(csvDataExport, 'exportCsv') |
||||||
|
); |
||||||
|
router.get( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/export/excel', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(excelDataExport, 'exportExcel') |
||||||
|
); |
||||||
|
router.get( |
||||||
|
'/api/v1/db/data/:orgs/:projectName/:tableName/views/:viewName/export/excel', |
||||||
|
apiMetrics, |
||||||
|
ncMetaAclMw(excelDataExport, 'exportExcel') |
||||||
|
); |
||||||
|
|
||||||
|
export default router; |
@ -0,0 +1,67 @@ |
|||||||
|
import { |
||||||
|
AuditRowUpdatePayloadType, |
||||||
|
CommentRowPayloadType, |
||||||
|
} from 'nocodb-sdk/build/main/lib/CustomAPI'; |
||||||
|
import Audit from '../models/Audit'; |
||||||
|
import { AuditOperationSubTypes, AuditOperationTypes } from 'nocodb-sdk'; |
||||||
|
import Model from '../models/Model'; |
||||||
|
import { PagedResponseImpl } from '../meta/helpers/PagedResponse'; |
||||||
|
|
||||||
|
import DOMPurify from 'isomorphic-dompurify'; |
||||||
|
|
||||||
|
export async function commentRow(param: { |
||||||
|
rowId: string; |
||||||
|
body: CommentRowPayloadType; |
||||||
|
user: any; |
||||||
|
}) { |
||||||
|
return await Audit.insert({ |
||||||
|
...param.body, |
||||||
|
user: param.user?.email, |
||||||
|
op_type: AuditOperationTypes.COMMENT, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
export async function auditRowUpdate(param: { |
||||||
|
rowId: string; |
||||||
|
body: AuditRowUpdatePayloadType; |
||||||
|
}) { |
||||||
|
const model = await Model.getByIdOrName({ id: param.body.fk_model_id }); |
||||||
|
return await Audit.insert({ |
||||||
|
fk_model_id: param.body.fk_model_id, |
||||||
|
row_id: param.rowId, |
||||||
|
op_type: AuditOperationTypes.DATA, |
||||||
|
op_sub_type: AuditOperationSubTypes.UPDATE, |
||||||
|
description: DOMPurify.sanitize( |
||||||
|
`Table ${model.table_name} : field ${param.body.column_name} got changed from ${param.body.prev_value} to ${param.body.value}` |
||||||
|
), |
||||||
|
details: DOMPurify.sanitize(`<span class="">${param.body.column_name}</span>
|
||||||
|
: <span class="text-decoration-line-through red px-2 lighten-4 black--text">${param.body.prev_value}</span> |
||||||
|
<span class="black--text green lighten-4 px-2">${param.body.value}</span>`),
|
||||||
|
ip: (param as any).clientIp, |
||||||
|
user: (param as any).user?.email, |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
export async function commentList(param: { query: any }) { |
||||||
|
return await Audit.commentsList(param.query); |
||||||
|
} |
||||||
|
|
||||||
|
export async function auditList(param: { query: any; projectId: string }) { |
||||||
|
return new PagedResponseImpl( |
||||||
|
await Audit.projectAuditList(param.projectId, param.query), |
||||||
|
{ |
||||||
|
count: await Audit.projectAuditCount(param.projectId), |
||||||
|
...param.query, |
||||||
|
} |
||||||
|
); |
||||||
|
} |
||||||
|
|
||||||
|
export async function commentsCount(param: { |
||||||
|
fk_model_id: string; |
||||||
|
ids: string[]; |
||||||
|
}) { |
||||||
|
return await Audit.commentsCount({ |
||||||
|
fk_model_id: param.fk_model_id as string, |
||||||
|
ids: param.ids as string[], |
||||||
|
}); |
||||||
|
} |
@ -0,0 +1,10 @@ |
|||||||
|
import NocoCache from '../cache/NocoCache'; |
||||||
|
|
||||||
|
export async function cacheGet() { |
||||||
|
return await NocoCache.export(); |
||||||
|
} |
||||||
|
|
||||||
|
export async function cacheDelete() { |
||||||
|
await NocoCache.destroy() |
||||||
|
return true |
||||||
|
} |
@ -0,0 +1,54 @@ |
|||||||
|
import { Request, Response, Router } from 'express'; |
||||||
|
import { isSystemColumn } from 'nocodb-sdk' |
||||||
|
import * as XLSX from 'xlsx'; |
||||||
|
import getAst from '../../db/sql-data-mapper/lib/sql/helpers/getAst' |
||||||
|
import ncMetaAclMw from '../../helpers/ncMetaAclMw'; |
||||||
|
import { extractXlsxData, serializeCellValue } from '../../meta/api/dataApis/helpers' |
||||||
|
import { |
||||||
|
extractCsvData, getViewAndModelByAliasOrId, |
||||||
|
getViewAndModelFromRequestByAliasOrId, PathParams, |
||||||
|
} from './helpers' |
||||||
|
import apiMetrics from '../../helpers/apiMetrics'; |
||||||
|
import View from '../../../models/View'; |
||||||
|
|
||||||
|
async function excelDataExport(param:PathParams&{ |
||||||
|
query: any; |
||||||
|
}) { |
||||||
|
const { model, view } = await getViewAndModelByAliasOrId(param); |
||||||
|
let targetView = view; |
||||||
|
if (!targetView) { |
||||||
|
targetView = await View.getDefaultView(model.id); |
||||||
|
} |
||||||
|
const { offset, elapsed, data } = await extractXlsxData({view: targetView, query:req.query }); |
||||||
|
const wb = XLSX.utils.book_new(); |
||||||
|
XLSX.utils.book_append_sheet(wb, data, targetView.title); |
||||||
|
const buf = XLSX.write(wb, { type: 'base64', bookType: 'xlsx' }); |
||||||
|
res.set({ |
||||||
|
'Access-Control-Expose-Headers': 'nc-export-offset', |
||||||
|
'nc-export-offset': offset, |
||||||
|
'nc-export-elapsed-time': elapsed, |
||||||
|
'Content-Disposition': `attachment; filename="${encodeURI( |
||||||
|
targetView.title |
||||||
|
)}-export.xlsx"`,
|
||||||
|
}); |
||||||
|
res.end(buf); |
||||||
|
} |
||||||
|
|
||||||
|
async function csvDataExport(req: Request, res: Response) { |
||||||
|
const { model, view } = await getViewAndModelFromRequestByAliasOrId(req); |
||||||
|
let targetView = view; |
||||||
|
if (!targetView) { |
||||||
|
targetView = await View.getDefaultView(model.id); |
||||||
|
} |
||||||
|
const { offset, elapsed, data } = await extractCsvData(targetView, req); |
||||||
|
|
||||||
|
res.set({ |
||||||
|
'Access-Control-Expose-Headers': 'nc-export-offset', |
||||||
|
'nc-export-offset': offset, |
||||||
|
'nc-export-elapsed-time': elapsed, |
||||||
|
'Content-Disposition': `attachment; filename="${encodeURI( |
||||||
|
targetView.title |
||||||
|
)}-export.csv"`,
|
||||||
|
}); |
||||||
|
res.send(data); |
||||||
|
} |
Loading…
Reference in new issue