Add sync-table node

This commit is contained in:
nacho 2025-08-07 16:16:10 -03:00
parent 3b7f1b073d
commit 8e8c9ed7b7
Signed by: nacho
SSH key fingerprint: SHA256:vijZwyV/ggB5iBXxEFr5kvag8tn7s4s8vrPFf9cFKjY
3 changed files with 95 additions and 0 deletions

View file

@ -0,0 +1,68 @@
<script type="text/javascript">
RED.nodes.registerType('grist-sync-table', {
category: 'grist',
color: '#00bb00',
defaults: {
server: { value: "", type: "grist-server", required: true },
document: { value: "", type: "grist-document", required: true },
tableId: { value: "", required: true },
primaryKey: { value: "", required: true },
},
inputs: 1,
outputs: 1,
icon: "font-awesome/fa-rotate",
label: function () {
return this.tableId ? `[Sync] ${this.tableId}` : "Sync table";
},
paletteLabel: "Sync table",
oneditprepare: function () {
}
});
</script>
<script type="text/html" data-template-name="grist-add-records">
<div class="form-row">
<label for="node-input-document"><i class="fa fa-file-text"></i> Document</label>
<input type="text" id="node-input-document" placeholder="Document">
</div>
<div class="form-row">
<label for="node-input-server"><i class="fa fa-server"></i> Server</label>
<input type="text" id="node-input-server" placeholder="Server">
</div>
<div class="form-row">
<label for="node-input-tableId"><i class="fa fa-table"></i> Table Name</label>
<input type="text" id="node-input-tableId" placeholder="Table Name">
</div>
<div class="form-row">
<label for="node-input-tableId"><i class="fa fa-table"></i> Primary Key(s)</label>
<input type="text" id="node-input-primaryKey" placeholder="Primary Key">
</div>
</script>
<script type="text/html" data-help-name="grist-add-records">
<p>Syncs records to a grist table.</p>
<h3>Inputs</h3>
<p>
<code>msg.payload</code> array of records (or a single record object) to sync.
</p>
<h3>Outputs</h3>
<p>
Array of records that have been synced (the same as payload received).
</p>
<h3>Attributes</h3>
<p></p>
<h3>Description</h3>
<p>
Syncs a set of records to a Grist table. It matches records based on the Primary Key
attribute, which must exist in all elements in payload. If the record exists, it is updated,
if it doesn't exist, it is created.
See https://www.npmjs.com/package/grist-api#synctabletablename-records-keycolids-filters for
technical details.
</p>
</script>

View file

@ -0,0 +1,26 @@
const { GristDocAPI } = require('grist-api');
const mustache = require('mustache');
module.exports = function (RED) {
function SyncTableNode(config) {
RED.nodes.createNode(this, config);
let node = this;
this.document = RED.nodes.getNode(config.document);
this.server = RED.nodes.getNode(config.server);
this.table = config.tableId;
this.primaryKey = config.primaryKey;
node.on('input', async function (msg, send, done) {
const protocol = this.server.tlsEnabled === true ? "https" : "http";
const url = protocol + "://" + this.server.hostname + ":" + this.server.port;
const api = new GristDocAPI(this.document.docid, { apiKey: this.server.apiKey, server: url });
const data = Array.isArray(msg.payload) ? msg.payload : [msg.payload]
api.syncTable(this.table, data, this.primaryKey).then(data => {
node.send({ ...msg, payload: data })
}).catch(reason => done(reason, "Failed to perform grist request to " + url));
});
}
RED.nodes.registerType("grist-add-records", SyncTableNode);
}

View file

@ -22,6 +22,7 @@
"grist-document-export": "node-red-grist/document-export.js",
"grist-add-records": "node-red-grist/add-records.js",
"grist-get-records": "node-red-grist/get-records.js",
"grist-sync-table": "node-red-grist/sync-table.js",
"grist-update-records": "node-red-grist/update-records.js",
"grist-document": "node-red-grist/document.js",
"grist-server": "node-red-grist/server.js"