(core) Comments

Summary:
First iteration for comments system for Grist.
- Comments are stored in a generic metatable `_grist_Cells`
- Each comment is connected to a particular cell (hence the generic name of the table)
- Access level works naturally for records stored in this table
-- User can add/read comments for cells he can see
-- User can't update/remove comments that he doesn't own, but he can delete them by removing cells (rows/columns)
-- Anonymous users can't see comments at all.
- Each comment can have replies (but replies can't have more replies)

Comments are hidden by default, they can be enabled by COMMENTS=true env variable.
Some things for follow-up
- Avatars, currently the user's profile image is not shown or retrieved from the server
- Virtual rendering for comments list in creator panel. Currently, there is a limit of 200 comments.

Test Plan: New and existing tests

Reviewers: georgegevoian, paulfitz

Reviewed By: georgegevoian

Subscribers: paulfitz

Differential Revision: https://phab.getgrist.com/D3509
This commit is contained in:
Jarosław Sadziński
2022-10-17 11:47:16 +02:00
parent 8be920dd25
commit bfd7243fe2
41 changed files with 2621 additions and 77 deletions

View File

@@ -56,6 +56,7 @@ declare module "app/client/components/BaseView" {
public gristDoc: GristDoc;
public cursor: Cursor;
public sortedRows: SortedRowSet;
public rowSource: RowSource;
public activeFieldBuilder: ko.Computed<FieldBuilder>;
public selectedColumns: ko.Computed<ViewFieldRec[]>|null;
public disableEditing: ko.Computed<boolean>;
@@ -69,6 +70,7 @@ declare module "app/client/components/BaseView" {
public buildTitleControls(): DomArg;
public getLoadingDonePromise(): Promise<void>;
public activateEditorAtCursor(options?: Options): void;
public openDiscussionAtCursor(discussionId?: number): boolean;
public onResize(): void;
public prepareToPrint(onOff: boolean): void;
public moveEditRowToCursor(): DataRowModel;
@@ -140,10 +142,19 @@ declare module "app/client/models/BaseRowModel" {
declare module "app/client/models/MetaRowModel" {
import BaseRowModel from "app/client/models/BaseRowModel";
import {ColValues} from 'app/common/DocActions';
import {SchemaTypes} from 'app/common/schema';
type NPartial<T> = {
[P in keyof T]?: T[P]|null;
};
type Values<T> = T extends keyof SchemaTypes ? NPartial<SchemaTypes[T]> : ColValues;
namespace MetaRowModel {}
class MetaRowModel extends BaseRowModel {
class MetaRowModel<TName extends (keyof SchemaTypes)|undefined = undefined> extends BaseRowModel {
public _isDeleted: ko.Observable<boolean>;
public events: { trigger: (key: string) => void };
public updateColValues(colValues: Values<TName>): Promise<void>;
}
export = MetaRowModel;
}