Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(Feature Request) Collaboration Features (comments on findings; tracked changes) #425

Open
includesec-nick opened this issue Apr 30, 2024 · 12 comments
Labels
enhancement New feature or request in progress On the road map and being actively worked

Comments

@includesec-nick
Copy link

Our internal QA workflow involves a combination of inline editing and comments by our Technical Writers, which are then reviewed by consultants. It would be awesome if Ghostwriter supported comment threads and tracked changes/version history on individual findings so that consultants and reviewers can easily iterate on findings throughout the QA process.

If you have any thoughts on how this could be implemented please let me know--we might be able to help!

@includesec-nick includesec-nick changed the title Collaboration Features (comments on findings; tracked changes) (Feature Request) Collaboration Features (comments on findings; tracked changes) Apr 30, 2024
@domwhewell-sage
Copy link
Contributor

+1 for this feature.
We're finding ourselves generating docx's QA'ing those then making changes in ghostwriter which can get complex. It would really help if there was a system for in-line comments!

@domwhewell-sage
Copy link
Contributor

Hmm looks like the editor in use currently "tinymce" has a comments plugin tinycomments this looks to be very nifty as it adds a <span> containing an ID that can map to a record in the database containing the comment. However it looks to be a premium plugin

@domwhewell-sage
Copy link
Contributor

Looking around abit more and I found LANCE a plugin to add inline comments to the editor. It works similar to the other one wrapping the selected text in an <annotation> tag and storing the comments in a dictionary in the annotations-data attribute. It seemed promising as I was able to add the plugin into my configuration but the editor was striping the <annotation> tag upon save.
There is also FLITE to track changes in your editor field.

The implimentation seems abit difficult to me as there is not much documentation out there and what does exist is rather vague
@chrismaddalena I dont know if you could help at all? A way these features could be implemented using these plugins or another way?

@includesec-nick
Copy link
Author

Hmm looks like the editor in use currently "tinymce" has a comments plugin tinycomments this looks to be very nifty as it adds a <span> containing an ID that can map to a record in the database containing the comment. However it looks to be a premium plugin

Hey @domwhewell-sage , thanks for looking into this! We reached out to TinyMCE and unfortunately tinycomments cannot be used in open source projects.

@chrismaddalena
Copy link
Collaborator

Tracking changes, keeping history, enabling comments, and collaborative editing are all things I have tracked on my wishlist. The implementation is tricky. TinyMCE supports these features, but they're all paid plugins and require TinyMCE Cloud.

Some Ghostwriter servers need to be run without an active internet connection, so a cloud service isn't an option. A service like TinyMCE cloud is also something that a lot of data handling policies wouldn't allow for some of the data stored in a Ghostwriter instance. That means it needs to be local to the server and scratch built. Maybe not entirely from scratch, but there aren't many good open-source options to use as a foundation.

@domwhewell-sage
Copy link
Contributor

domwhewell-sage commented Jun 27, 2024

I have quickly mocked up a comments system based from what I saw in the LANCE comment system and tinymce
image
image

<p>This is the description of the <span class="comment" comment-data="%5B%7B%22author%22%3A%22646f6d2e77686577656c6c%22%2C%22comment%22%3A%22Is%20this%20not%20too%20short%3F%22%7D%2C%7B%22author%22%3A%2261646d696e%22%2C%22comment%22%3A%22No%22%7D%5D">vulnerability</span></p>

It needs alot more thought and cleaning up. But I think this should provide a good base

editor.ui.registry.addMenuItem('comment', {
    icon: 'comment',
    text: 'Comment',
    onAction: function () {
        const hex2ascii = (hexString) => {
            let decodedStr = '';
            for (let i = 0; i < hexString.length; i += 2) {
                const byte = parseInt(hexString.substr(i, 2), 16);
                decodedStr += String.fromCharCode(byte);
            }
            return decodedStr
        }

        const selection = editor.selection.getContent();
        const commentNode = editor.selection.getNode();
        let commentsThread = '';
        if (commentNode.nodeName === 'SPAN' && commentNode.hasAttribute('comment-data')) {
            commentDataDecoded = decodeURIComponent(commentNode.getAttribute('comment-data'));
            commentData = JSON.parse(commentDataDecoded);
            commentData.forEach(item => {
                const author = hex2ascii(item.author);
                const comment = item.comment;
                const float = author === hex2ascii(username) ? 'right' : 'left';
                commentsThread += `<div id="commentThread" style="float: ${float}; clear: both;">
                    <h1>${author}</h1>
                    <p>${comment}</p>
                </div>`;
            });
        }

        if (selection) {
            const commentBox = editor.windowManager.open({
                title: 'Add Comment',
                body: {
                    type: 'panel',
                    items: [
                        { type: 'htmlpanel', name: 'existingComments', html: commentsThread},
                        { type: 'textarea', name: 'comment', label: 'Comment' },
                    ]
                },
                buttons: [
                    { type: 'cancel', text: 'Cancel' },
                    { type: 'submit', text: 'Save' }
                ],
                onSubmit: (api) => {
                    const comment = api.getData().comment;
                    let commentThread = [];
                    const commentNode = editor.selection.getNode();
                    if (commentNode.nodeName === 'SPAN' && commentNode.hasAttribute('comment-data')) {
                        commentDataDecoded = decodeURIComponent(commentNode.getAttribute('comment-data'));
                        commentData = JSON.parse(commentDataDecoded);
                        commentData.forEach(item => {
                            const author = item.author;
                            const comment = item.comment;
                            commentThread.push({ author: author, comment: comment });
                        });
                    }
                    commentThread.push({ author: username, comment: comment });
                    editor.execCommand('mceInsertContent', false, `<span class="comment" comment-data="${encodeURIComponent(JSON.stringify(commentThread))}">${selection}</span>`);
                    api.close();
                }
            });
        }
    }
});

editor.on('click', function (e) {
    const node = editor.selection.getNode();
    if (node.nodeName === 'SPAN' && node.hasAttribute('comment-data')) {
        editor.selection.select(node.firstChild);
        editor.ui.registry.getAll().menuItems.comment.onAction();
    }
});

@chrismaddalena
Copy link
Collaborator

That looks great @domwhewell-sage. If we did something like this, we'll also need to update the reporting engine so it knows to ignore span elements with that class or comment-data attribute.

FLITE looks great for an editor solution. We'd probably want to do tracked changes on the server side to allow for sharing the tracking, showing diffs, and making it easy to revert to a specific version, but we could start with something like FLITE.

@domwhewell-sage
Copy link
Contributor

Hi @chrismaddalena / @includesec-nick, I have started a PR for the comments plugin it needs abit more work before its ready but its a base, I'm not a CSS master so help styling the comments thread would be appreciated. I also have a question about notifying the user that their report/finding has received a comment.

I have also had more time to checkout the FLITE plugin in my development environment
image
It seems to work well allowing you to toggle tracked changes, view tracked changes, and accept all changes (In the current editor).

However "Reject all changes", "Accept change" and "Reject change" are locked and cannot be used in the demo version.

Instead of the FLITE route it might be possible to also create a custom plugin for tracked changes in the same way I have started the comments plugin

@chrismaddalena
Copy link
Collaborator

The PR you started looks great, @domwhewell-sage. I tried some of the changes locally and the comments were working. That's exciting. Thanks for getting that started!

Copy link

This issue has been labeled as stale because it has been open for 30 days with no activity.

@github-actions github-actions bot added the stale label Aug 18, 2024
@felix-caboff
Copy link

Just keeping this "fresh" and noting an extra +1 request for this.

@github-actions github-actions bot removed the stale label Aug 24, 2024
@chrismaddalena
Copy link
Collaborator

This is being actively worked on and attached to the road map so no fear of the issue being forgotten about.

@chrismaddalena chrismaddalena added enhancement New feature or request in progress On the road map and being actively worked labels Sep 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request in progress On the road map and being actively worked
Projects
Status: In Progress
Development

No branches or pull requests

4 participants