mirror of
https://github.com/gristlabs/grist-core.git
synced 2026-03-02 04:09:24 +00:00
(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:
@@ -12,6 +12,8 @@ import {docBreadcrumbs} from 'app/client/ui2018/breadcrumbs';
|
||||
import {basicButton} from 'app/client/ui2018/buttons';
|
||||
import {cssHideForNarrowScreen, testId, theme} from 'app/client/ui2018/cssVars';
|
||||
import {IconName} from 'app/client/ui2018/IconList';
|
||||
import {menuAnnotate} from 'app/client/ui2018/menus';
|
||||
import {COMMENTS} from 'app/client/models/features';
|
||||
import {waitGrainObs} from 'app/common/gutil';
|
||||
import * as roles from 'app/common/roles';
|
||||
import {Computed, dom, DomElementArg, makeTestId, MultiHolder, Observable, styled} from 'grainjs';
|
||||
@@ -92,6 +94,14 @@ export function createTopBarDoc(owner: MultiHolder, appModel: AppModel, pageMode
|
||||
|
||||
buildShareMenuButton(pageModel),
|
||||
|
||||
dom.maybe(use =>
|
||||
(
|
||||
use(pageModel.gristDoc)
|
||||
&& !use(use(pageModel.gristDoc)!.isReadonly)
|
||||
&& use(COMMENTS())
|
||||
),
|
||||
() => buildShowDiscussionButton(pageModel)),
|
||||
|
||||
dom.update(
|
||||
buildNotifyMenuButton(appModel.notifier, appModel),
|
||||
cssHideForNarrowScreen.cls(''),
|
||||
@@ -101,6 +111,22 @@ export function createTopBarDoc(owner: MultiHolder, appModel: AppModel, pageMode
|
||||
];
|
||||
}
|
||||
|
||||
function buildShowDiscussionButton(pageModel: DocPageModel) {
|
||||
return cssHoverCircle({ style: `margin: 5px; position: relative;` },
|
||||
cssTopBarBtn('Chat', dom.cls('tour-share-icon')),
|
||||
cssBeta('Beta'),
|
||||
testId('open-discussion'),
|
||||
dom.on('click', () => pageModel.gristDoc.get()!.showTool('discussion'))
|
||||
);
|
||||
}
|
||||
|
||||
const cssBeta = styled(menuAnnotate, `
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: -9px;
|
||||
font-weight: bold;
|
||||
`);
|
||||
|
||||
// Given the GristDoc instance, returns a rename function for the current active page.
|
||||
// If the current page is not able to be renamed or the new name is invalid, the function is a noop.
|
||||
function getRenamePageFn(gristDoc: GristDoc): (val: string) => Promise<void> {
|
||||
|
||||
Reference in New Issue
Block a user