gristlabs_grist-core/sandbox/grist/treeview.py
Paul Fitzpatrick b82eec714a (core) move data engine code to core
Summary:
this moves sandbox/grist to core, and adds a requirements.txt
file for reconstructing the content of sandbox/thirdparty.

Test Plan:
existing tests pass.
Tested core functionality manually.  Tested docker build manually.

Reviewers: dsagal

Reviewed By: dsagal

Differential Revision: https://phab.getgrist.com/D2563
2020-07-29 08:57:25 -04:00

33 lines
1.6 KiB
Python

"""
Grist supports organizing a list of records as a tree view which allows for grouping records as
children of some other record.
On the client, the .indentation is used to measure the distance between the left margin of the
container and where we want the record to be. The variation of .indentation gives the parent-child
relationship between consecutive records. For instance in ["A0", "B1", "C1"] (where "A0" stands for
the record {'id': "A", 'indentation': 0}), "B" and "C" are children of "A". In ["A0", "B1", "C2"],
"C" is a child of "B", which is a child of "A".
The order for the records is typically handled using a field of type "PositionNumber", ie: .pagePos
in _grist_Pages table.
Because user can remove records that invalidate the tree, the module exposes fix_indents. For
example if user removes "C" from ["A0", "B1", "C0", "D1"] the resulting table holds ["A0", "B1",
"D1"] and "D" became child of "A", which is unfortunate because we'd rather have "C" become a
sibling of "A" instead. Using fix_indents helps with keeping the tree consistent by returning [("D",
0)] which indicate that the indentation of row "D" needs to be set to 0.
"""
# Items is an array of items with .id and .indentation properties. Returns a list of (item_id,
# new_indent) pairs.
def fix_indents(items, deleted_ids):
max_next_indent = 0
adjustments = []
for item in items:
indent = min(max_next_indent, item.indentation)
is_deleted = item.id in deleted_ids
if indent != item.indentation and not is_deleted:
adjustments.append((item.id, indent))
max_next_indent = indent if is_deleted else indent + 1
return adjustments