History tracking "change_log" field using trigger formulas and widgets

Hello ^^

There are some tables where values change over time, and when those changes occurred is significant. For example a todo list, or a kanban board. I know grist has a perfectly good backup and undo/history true, but as far as I could tell, this couldn’t be seen easily at a per-record level, and couldn’t easily be incorporated into, say a custom widget.

I built it using trigger formulas (on new and update records). This feels like a very hacky solution. It would be cool feature if you could turn on history tracking for a record natively in Grist. But for now, this might work :smiley: If you know a better way to do this, please let me know!

The code and a readme are here: GitHub - kindrowboat/grist-change_log: a (probably cursed) way to have changelogs for records in grist

This is what the trigger formula currently looks like:

# ====================8<-----------------------------------
blacklist = ["change_log", "updated_at", "created_at"]
# ----------------------------->8==========================

import json

def jsonify_rec(changed_record):
  def simplify(value):
    if ISREF(value):
      return value.id
    elif ISREFLIST(value):
      return ["L"] + [v.id for v in value]
    elif isinstance(value, tuple):
        return list(value)
    return value

  result = {k: simplify(v) for k, v in changed_record.items() if k not in blacklist}
  return result

# Trigger formula code
current_snapshot = jsonify_rec(RECORD(rec, dates_as_iso=True))
logs_json = current_snapshot.get('change_log') or "[]"
logs = json.loads(logs_json)
previous_snapshot = logs[0]["snapshot"] if logs else {}

changed_fields = [
  field for field in current_snapshot
  if current_snapshot.get(field) != previous_snapshot.get(field)
]

log = {
  "timestamp": NOW().isoformat(),
  "changed": changed_fields,
  "snapshot": current_snapshot
}
logs.insert(0, log)  # Prepend the new log entry
return json.dumps(logs)

There’s also a custom widget you can install to view a concise change log for a given record.

3 Likes