]> BookStack Code Mirror - bookstack/blob - resources/js/components/page-comments.js
Comments: updated component and split out code
[bookstack] / resources / js / components / page-comments.js
1 import {Component} from './component';
2 import {getLoading, htmlToDom} from '../services/dom';
3
4 export class PageComments extends Component {
5
6     setup() {
7         this.elem = this.$el;
8         this.pageId = Number(this.$opts.pageId);
9
10         // Element references
11         this.container = this.$refs.commentContainer;
12         this.commentCountBar = this.$refs.commentCountBar;
13         this.commentsTitle = this.$refs.commentsTitle;
14         this.addButtonContainer = this.$refs.addButtonContainer;
15         this.replyToRow = this.$refs.replyToRow;
16         this.formContainer = this.$refs.formContainer;
17         this.form = this.$refs.form;
18         this.formInput = this.$refs.formInput;
19         this.addCommentButton = this.$refs.addCommentButton;
20         this.hideFormButton = this.$refs.hideFormButton;
21         this.removeReplyToButton = this.$refs.removeReplyToButton;
22
23         // Translations
24         this.createdText = this.$opts.createdText;
25         this.countText = this.$opts.countText;
26
27         // Internal State
28         this.parentId = null;
29
30         this.setupListeners();
31     }
32
33     setupListeners() {
34         this.removeReplyToButton.addEventListener('click', this.removeReplyTo.bind(this));
35         this.hideFormButton.addEventListener('click', this.hideForm.bind(this));
36         this.addCommentButton.addEventListener('click', this.showForm.bind(this));
37
38         this.elem.addEventListener('page-comment-delete', () => {
39             this.updateCount();
40             this.hideForm();
41         });
42
43         this.elem.addEventListener('page-comment-reply', event => {
44             this.setReply(event.detail.id);
45         });
46
47         if (this.form) {
48             this.form.addEventListener('submit', this.saveComment.bind(this));
49         }
50     }
51
52     saveComment(event) {
53         event.preventDefault();
54         event.stopPropagation();
55
56         const loading = getLoading();
57         loading.classList.add('px-l');
58         this.form.after(loading);
59         this.form.toggleAttribute('hidden', true);
60
61         const text = this.formInput.value;
62         const reqData = {
63             text,
64             parent_id: this.parentId || null,
65         };
66
67         window.$http.post(`/comment/${this.pageId}`, reqData).then(resp => {
68             const newElem = htmlToDom(resp.data);
69             this.container.appendChild(newElem);
70             window.$events.success(this.createdText);
71             this.resetForm();
72             this.updateCount();
73         }).catch(err => {
74             this.form.toggleAttribute('hidden', false);
75             window.$events.showValidationErrors(err);
76         });
77
78         loading.remove();
79     }
80
81     updateCount() {
82         const count = this.getCommentCount();
83         this.commentsTitle.textContent = window.trans_plural(this.countText, count, {count});
84     }
85
86     resetForm() {
87         this.formInput.value = '';
88         this.hideForm();
89         this.removeReplyTo();
90     }
91
92     showForm() {
93         this.formContainer.toggleAttribute('hidden', false);
94         this.addButtonContainer.toggleAttribute('hidden', true);
95         this.formInput.focus();
96     }
97
98     hideForm() {
99         this.formContainer.toggleAttribute('hidden', true);
100         if (this.getCommentCount() > 0) {
101             this.elem.appendChild(this.addButtonContainer);
102         } else {
103             this.commentCountBar.appendChild(this.addButtonContainer);
104         }
105         this.addButtonContainer.toggleAttribute('hidden', false);
106     }
107
108     getCommentCount() {
109         return this.container.querySelectorAll('[compontent="page-comment"]').length;
110     }
111
112     setReply(commentLocalId) {
113         this.showForm();
114         this.parentId = commentLocalId;
115         this.replyToRow.toggleAttribute('hidden', false);
116         const replyLink = this.replyToRow.querySelector('a');
117         replyLink.textContent = `#${this.parentId}`;
118         replyLink.href = `#comment${this.parentId}`;
119     }
120
121     removeReplyTo() {
122         this.parentId = null;
123         this.replyToRow.toggleAttribute('hidden', true);
124     }
125
126 }