(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
This commit is contained in:
Paul Fitzpatrick 2020-09-29 14:53:42 -04:00
parent cff02cd3d0
commit e5b67fee7e
2 changed files with 18 additions and 2 deletions

View File

@ -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];

View File

@ -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)!);