Diff view shows all versions. E.g. if you enable/disable a script it shows up in possible diff targets. This PR filters versiont to only show the ones that have the field changed somehow.
68 lines
1.8 KiB
Python
68 lines
1.8 KiB
Python
import json
|
|
from difflib import unified_diff
|
|
|
|
import frappe
|
|
from frappe.utils import pretty_date
|
|
from frappe.utils.data import cstr
|
|
|
|
|
|
@frappe.whitelist()
|
|
def get_version_diff(
|
|
from_version: int | str, to_version: int | str, fieldname: str = "script"
|
|
) -> list[str]:
|
|
|
|
before, before_timestamp = _get_value_from_version(from_version, fieldname)
|
|
after, after_timestamp = _get_value_from_version(to_version, fieldname)
|
|
|
|
if not (before and after):
|
|
return ["Values not available for diff"]
|
|
|
|
before = before.split("\n")
|
|
after = after.split("\n")
|
|
|
|
diff = unified_diff(
|
|
before,
|
|
after,
|
|
fromfile=cstr(from_version),
|
|
tofile=cstr(to_version),
|
|
fromfiledate=before_timestamp,
|
|
tofiledate=after_timestamp,
|
|
)
|
|
return list(diff)
|
|
|
|
|
|
def _get_value_from_version(version_name: int | str, fieldname: str):
|
|
version = frappe.get_list("Version", fields=["data", "modified"], filters={"name": version_name})
|
|
if version:
|
|
data = json.loads(version[0].data)
|
|
changed_fields = data.get("changed", [])
|
|
|
|
# data structure of field: [fieldname, before_save, after_save]
|
|
for field in changed_fields:
|
|
if field[0] == fieldname:
|
|
return field[2], str(version[0].modified)
|
|
|
|
return None, None
|
|
|
|
|
|
@frappe.whitelist()
|
|
@frappe.validate_and_sanitize_search_inputs
|
|
def version_query(doctype, txt, searchfield, start, page_len, filters):
|
|
version_filters = {
|
|
"docname": filters["docname"],
|
|
"ref_doctype": filters["ref_doctype"],
|
|
}
|
|
|
|
if fieldname := filters.get("fieldname"):
|
|
# This helps filter version logs which contain changes to the field.
|
|
version_filters["data"] = ("LIKE", f'%"{fieldname}"%')
|
|
|
|
results = frappe.get_list(
|
|
"Version",
|
|
fields=["name", "modified"],
|
|
filters=version_filters,
|
|
limit_start=start,
|
|
limit_page_length=page_len,
|
|
order_by="modified desc",
|
|
)
|
|
return [(d.name, pretty_date(d.modified), d.modified) for d in results]
|