From e5b67fee7eecf18742ae3aeb0508c7c73e6393fa Mon Sep 17 00:00:00 2001 From: Paul Fitzpatrick Date: Tue, 29 Sep 2020 14:53:42 -0400 Subject: [PATCH] (core) visualize simple differences between documents Summary: Render simple differences between documents. * Show cell changes. * Show cell conflicts. * Show row additions/deletions. Doesn't support any schema changes, and is untested in the presence of schema changes. Any widgets that access row data without using `cells` fields won't receive correct data. Not addressed: * Rendering conflicts in mixed row addition/updating/deleting. * Column additions/deletions, option changes, etc. * Document level changes. * Table and column renames (though anticipated in ActionSummary structure). * Page-level changes. * Drawing attention to changes (marking changed pages+views, suppressing unchanged rows, etc). * Rendering differences in views other than GridView. * Adding UI for initiating a comparison. * Editing while comparing. Replaces {D2600} Test Plan: added tests Reviewers: dsagal Reviewed By: dsagal Differential Revision: https://phab.getgrist.com/D2618 --- app/common/DocActions.ts | 6 ++++++ app/common/gristTypes.ts | 14 ++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/app/common/DocActions.ts b/app/common/DocActions.ts index 894c84c9..6800324f 100644 --- a/app/common/DocActions.ts +++ b/app/common/DocActions.ts @@ -6,6 +6,12 @@ import { CellValue } from 'app/plugin/GristData'; export { CellValue, RowRecord } from 'app/plugin/GristData'; +// Part of a special CellValue used for comparisons, embedding several versions of a CellValue. +export type CellVersions = + { parent: CellValue, remote: CellValue } | + { parent: CellValue, local: CellValue } | + { parent: CellValue, local: CellValue, remote: CellValue }; + import map = require('lodash/map'); export type AddRecord = ['AddRecord', string, number, ColValues]; diff --git a/app/common/gristTypes.ts b/app/common/gristTypes.ts index 7e63270a..503cb4a6 100644 --- a/app/common/gristTypes.ts +++ b/app/common/gristTypes.ts @@ -1,4 +1,4 @@ -import {CellValue} from 'app/common/DocActions'; +import { CellValue, CellVersions } from 'app/common/DocActions'; import isString = require('lodash/isString'); // tslint:disable:object-literal-key-quotes @@ -22,6 +22,7 @@ export const enum GristObjCode { Exception = 'E', Pending = 'P', Unmarshallable = 'U', + Versions = 'V', } export const MANUALSORT = 'manualSort'; @@ -110,6 +111,14 @@ export function isRaisedException(value: CellValue): boolean { return getObjCode(value) === GristObjCode.Exception; } +/** + * Returns whether a value (as received in a DocAction) represents a group of versions for + * a comparison or conflict. + */ +export function isVersions(value: CellValue): value is [GristObjCode.Versions, CellVersions] { + return getObjCode(value) === GristObjCode.Versions; +} + /** * Returns whether a value (as received in a DocAction) represents a list or is null, * which is a valid value for list types in grist. @@ -130,7 +139,8 @@ function isNumberOrNull(v: CellValue) { return isNumber(v) || v === null; } function isBoolean(v: CellValue) { return typeof v === 'boolean' || v === 1 || v === 0; } // These values are not regular cell values, even in a column of type Any. -const abnormalValueTypes: string[] = [GristObjCode.Exception, GristObjCode.Pending, GristObjCode.Unmarshallable]; +const abnormalValueTypes: string[] = [GristObjCode.Exception, GristObjCode.Pending, + GristObjCode.Unmarshallable, GristObjCode.Versions]; function isNormalValue(value: CellValue) { return !abnormalValueTypes.includes(getObjCode(value)!);