Issue #601: implement PUT on columns (#605)

* Also Add includeHidden param for GET on columns
This commit is contained in:
Florent
2023-08-11 15:12:43 +02:00
committed by GitHub
parent 605a3022e9
commit e93ad5a0c5
4 changed files with 197 additions and 4 deletions

View File

@@ -68,6 +68,10 @@ export const ColumnsPatch = t.iface([], {
"columns": t.tuple("RecordWithStringId", t.rest(t.array("RecordWithStringId"))),
});
export const ColumnsPut = t.iface([], {
"columns": t.tuple("RecordWithStringId", t.rest(t.array("RecordWithStringId"))),
});
export const TablePost = t.iface(["ColumnsPost"], {
"id": t.opt("string"),
});
@@ -93,6 +97,7 @@ const exportedTypeSuite: t.ITypeSuite = {
MinimalRecord,
ColumnsPost,
ColumnsPatch,
ColumnsPut,
TablePost,
TablesPost,
TablesPatch,

View File

@@ -88,6 +88,10 @@ export interface ColumnsPatch {
columns: [RecordWithStringId, ...RecordWithStringId[]]; // at least one column is required
}
export interface ColumnsPut {
columns: [RecordWithStringId, ...RecordWithStringId[]]; // at least one column is required
}
/**
* Creating tables requires a list of columns.
* `fields` is not accepted because it's not generally sensible to set the metadata fields on new tables.

View File

@@ -2,7 +2,14 @@ import {concatenateSummaries, summarizeAction} from "app/common/ActionSummarizer
import {createEmptyActionSummary} from "app/common/ActionSummary";
import {ApiError, LimitType} from 'app/common/ApiError';
import {BrowserSettings} from "app/common/BrowserSettings";
import {BulkColValues, ColValues, fromTableDataAction, TableColValues, TableRecordValue} from 'app/common/DocActions';
import {
BulkColValues,
ColValues,
fromTableDataAction,
TableColValues,
TableRecordValue,
UserAction
} from 'app/common/DocActions';
import {isRaisedException} from "app/common/gristTypes";
import {buildUrlId, parseUrlId} from "app/common/gristUrls";
import {isAffirmative} from "app/common/gutil";
@@ -94,7 +101,7 @@ type WithDocHandler = (activeDoc: ActiveDoc, req: RequestWithLogin, resp: Respon
// Schema validators for api endpoints that creates or updates records.
const {
RecordsPatch, RecordsPost, RecordsPut,
ColumnsPost, ColumnsPatch,
ColumnsPost, ColumnsPatch, ColumnsPut,
TablesPost, TablesPatch,
} = t.createCheckers(DocApiTypesTI, GristDataTI);
@@ -357,8 +364,9 @@ export class DocWorkerApi {
this._app.get('/api/docs/:docId/tables/:tableId/columns', canView,
withDoc(async (activeDoc, req, res) => {
const tableId = req.params.tableId;
const includeHidden = isAffirmative(req.query.includeHidden);
const columns = await handleSandboxError('', [],
activeDoc.getTableCols(docSessionFromRequest(req), tableId));
activeDoc.getTableCols(docSessionFromRequest(req), tableId, includeHidden));
res.json({columns});
})
);
@@ -681,6 +689,54 @@ export class DocWorkerApi {
})
);
// Add or update records given in records format
this._app.put('/api/docs/:docId/tables/:tableId/columns', canEdit, validate(ColumnsPut),
withDoc(async (activeDoc, req, res) => {
const tablesTable = activeDoc.docData!.getMetaTable("_grist_Tables");
const columnsTable = activeDoc.docData!.getMetaTable("_grist_Tables_column");
const {tableId} = req.params;
const tableRef = tablesTable.findMatchingRowId({tableId});
if (!tableRef) {
throw new ApiError(`Table not found "${tableId}"`, 404);
}
const body = req.body as Types.ColumnsPut;
const addActions: UserAction[] = [];
const updateActions: UserAction[] = [];
const updatedColumnsIds = new Set();
for (const col of body.columns) {
const id = columnsTable.findMatchingRowId({parentId: tableRef, colId: col.id});
if (id) {
updateActions.push( ['UpdateRecord', '_grist_Tables_column', id, col.fields] );
updatedColumnsIds.add( id );
} else {
addActions.push( ['AddVisibleColumn', tableId, col.id, col.fields] );
}
}
const getRemoveAction = async () => {
const columns = await handleSandboxError('', [],
activeDoc.getTableCols(docSessionFromRequest(req), tableId));
const columnsToRemove = columns
.map(col => col.fields.colRef as number)
.filter(colRef => !updatedColumnsIds.has(colRef));
return [ 'BulkRemoveRecord', '_grist_Tables_column', columnsToRemove ];
};
const actions = [
...(!isAffirmative(req.query.noupdate) ? updateActions : []),
...(!isAffirmative(req.query.noadd) ? addActions : []),
...(isAffirmative(req.query.replaceall) ? [ await getRemoveAction() ] : [] )
];
await handleSandboxError(tableId, [],
activeDoc.applyUserActions(docSessionFromRequest(req), actions)
);
res.json(null);
})
);
// Add a new webhook and trigger
this._app.post('/api/docs/:docId/webhooks', isOwner, validate(WebhookSubscribeCollection),
withDoc(async (activeDoc, req, res) => {