decidim-posts 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE-AGPLv3.txt +661 -0
- data/README.md +40 -0
- data/Rakefile +9 -0
- data/app/cells/decidim/posts/comments/add_comment.erb +15 -0
- data/app/cells/decidim/posts/comments/comments_loading.erb +1 -0
- data/app/cells/decidim/posts/comments/order_control.erb +13 -0
- data/app/cells/decidim/posts/comments/show.erb +31 -0
- data/app/cells/decidim/posts/comments_cell.rb +158 -0
- data/app/cells/decidim/posts/content_blocks/posts/show.erb +3 -0
- data/app/cells/decidim/posts/content_blocks/posts_cell.rb +50 -0
- data/app/cells/decidim/posts/content_blocks/posts_settings_form/show.erb +3 -0
- data/app/cells/decidim/posts/content_blocks/posts_settings_form_cell.rb +23 -0
- data/app/cells/decidim/posts/feed_dropdown_metadata_cell.rb +19 -0
- data/app/cells/decidim/posts/meeting/show.erb +65 -0
- data/app/cells/decidim/posts/meeting_cell.rb +44 -0
- data/app/cells/decidim/posts/post/show.erb +30 -0
- data/app/cells/decidim/posts/post/survey.erb +68 -0
- data/app/cells/decidim/posts/post_attachments/show.erb +40 -0
- data/app/cells/decidim/posts/post_attachments_cell.rb +17 -0
- data/app/cells/decidim/posts/post_cell.rb +44 -0
- data/app/cells/decidim/posts/post_comment/show.erb +17 -0
- data/app/cells/decidim/posts/post_comment_cell.rb +49 -0
- data/app/cells/decidim/posts/post_header/show.erb +53 -0
- data/app/cells/decidim/posts/post_header_cell.rb +79 -0
- data/app/cells/decidim/posts/post_host/show.erb +74 -0
- data/app/cells/decidim/posts/post_host_cell.rb +73 -0
- data/app/cells/decidim/posts/post_metadata/show.erb +9 -0
- data/app/cells/decidim/posts/post_metadata_cell.rb +67 -0
- data/app/cells/decidim/posts/reaction_menu/show.erb +18 -0
- data/app/cells/decidim/posts/reaction_menu/styles.erb +7 -0
- data/app/cells/decidim/posts/reaction_menu_cell.rb +26 -0
- data/app/cells/decidim/posts/reactions/show.erb +8 -0
- data/app/cells/decidim/posts/reactions_cell.rb +22 -0
- data/app/commands/decidim/posts/add_reaction_to_resource.rb +90 -0
- data/app/commands/decidim/posts/create_post.rb +112 -0
- data/app/commands/decidim/posts/destroy_post.rb +20 -0
- data/app/commands/decidim/posts/remove_reaction_from_resource.rb +41 -0
- data/app/commands/decidim/posts/update_post.rb +72 -0
- data/app/controllers/concerns/decidim/posts/admin/filterable.rb +46 -0
- data/app/controllers/concerns/decidim/posts/reactionable.rb +31 -0
- data/app/controllers/decidim/posts/admin/application_controller.rb +26 -0
- data/app/controllers/decidim/posts/admin/posts_controller.rb +93 -0
- data/app/controllers/decidim/posts/application_controller.rb +18 -0
- data/app/controllers/decidim/posts/meetings_controller.rb +176 -0
- data/app/controllers/decidim/posts/posts_controller.rb +202 -0
- data/app/controllers/decidim/posts/reactions_controller.rb +54 -0
- data/app/controllers/decidim/posts/user_answers_controller.rb +36 -0
- data/app/events/decidim/posts/resource_reacted_event.rb +38 -0
- data/app/forms/decidim/posts/answer_form.rb +13 -0
- data/app/forms/decidim/posts/post_form.rb +121 -0
- data/app/forms/decidim/posts/question_form.rb +20 -0
- data/app/helpers/decidim/posts/admin/posts_helper.rb +8 -0
- data/app/helpers/decidim/posts/application_helper.rb +20 -0
- data/app/helpers/decidim/posts/post_cells_helper.rb +35 -0
- data/app/helpers/decidim/posts/posts_helper.rb +34 -0
- data/app/helpers/decidim/posts/reaction_helper.rb +22 -0
- data/app/models/decidim/posts/answer.rb +13 -0
- data/app/models/decidim/posts/application_record.rb +10 -0
- data/app/models/decidim/posts/post.rb +116 -0
- data/app/models/decidim/posts/question.rb +17 -0
- data/app/models/decidim/posts/reaction.rb +22 -0
- data/app/models/decidim/posts/reaction_type.rb +13 -0
- data/app/models/decidim/posts/user_answer.rb +11 -0
- data/app/packs/entrypoints/decidim_posts.js +5 -0
- data/app/packs/entrypoints/decidim_posts.scss +1 -0
- data/app/packs/images/decidim/posts/icon.svg +1 -0
- data/app/packs/src/decidim/posts/carousel.js +112 -0
- data/app/packs/src/decidim/posts/host_status.js +75 -0
- data/app/packs/src/decidim/posts/newFeeds.js +98 -0
- data/app/packs/src/decidim/posts/posts.js +272 -0
- data/app/packs/src/decidim/posts/submenu.js +46 -0
- data/app/packs/src/decidim/posts/survey.js +94 -0
- data/app/packs/stylesheets/decidim/posts/_variables.scss +10 -0
- data/app/packs/stylesheets/decidim/posts/posts.scss +415 -0
- data/app/permissions/decidim/posts/admin/permissions.rb +23 -0
- data/app/permissions/decidim/posts/permissions.rb +101 -0
- data/app/presenters/decidim/posts/post_presenter.rb +45 -0
- data/app/views/decidim/posts/admin/posts/_post-tr.html.erb +45 -0
- data/app/views/decidim/posts/admin/posts/index.html.erb +54 -0
- data/app/views/decidim/posts/meetings/edit.html.erb +24 -0
- data/app/views/decidim/posts/posts/_admin_options.html.erb +30 -0
- data/app/views/decidim/posts/posts/_attachment.html.erb +24 -0
- data/app/views/decidim/posts/posts/_edit_form.html.erb +16 -0
- data/app/views/decidim/posts/posts/_feed.html.erb +8 -0
- data/app/views/decidim/posts/posts/_form.html.erb +104 -0
- data/app/views/decidim/posts/posts/_index.html.erb +49 -0
- data/app/views/decidim/posts/posts/_meeting_form.erb +18 -0
- data/app/views/decidim/posts/posts/_new.html.erb +33 -0
- data/app/views/decidim/posts/posts/_new_survey.html.erb +20 -0
- data/app/views/decidim/posts/posts/_new_survey_answer.html.erb +11 -0
- data/app/views/decidim/posts/posts/_new_survey_question.html.erb +17 -0
- data/app/views/decidim/posts/posts/_post.html.erb +11 -0
- data/app/views/decidim/posts/posts/_post_form.html.erb +5 -0
- data/app/views/decidim/posts/posts/_sidebar.html.erb +36 -0
- data/app/views/decidim/posts/posts/edit.html.erb +34 -0
- data/app/views/decidim/posts/posts/index.html.erb +1 -0
- data/app/views/decidim/posts/posts/show.html.erb +12 -0
- data/app/views/decidim/posts/reactions/_update_buttons_and_counters.html.erb +1 -0
- data/config/assets.rb +9 -0
- data/config/i18n-tasks.yml +10 -0
- data/config/locales/bs.yml +215 -0
- data/config/locales/de.yml +217 -0
- data/config/locales/en.yml +216 -0
- data/config/locales/hr.yml +219 -0
- data/config/locales/it.yml +215 -0
- data/config/locales/sr.yml +220 -0
- data/config/locales/tr.yml +219 -0
- data/lib/decidim/posts/admin.rb +10 -0
- data/lib/decidim/posts/admin_engine.rb +25 -0
- data/lib/decidim/posts/component.rb +59 -0
- data/lib/decidim/posts/content_blocks/content_blocks_homepage.rb +19 -0
- data/lib/decidim/posts/engine.rb +84 -0
- data/lib/decidim/posts/test/factories.rb +14 -0
- data/lib/decidim/posts/version.rb +9 -0
- data/lib/decidim/posts.rb +13 -0
- metadata +183 -0
|
@@ -0,0 +1,272 @@
|
|
|
1
|
+
import { initSurvey } from './survey.js';
|
|
2
|
+
import carousel from './carousel.js';
|
|
3
|
+
import { host_status } from './host_status.js';
|
|
4
|
+
import { closeDialog, activateCategory, hideAllForms } from './newFeeds.js';
|
|
5
|
+
import Submenu from './submenu.js';
|
|
6
|
+
import CommentsComponent from "src/decidim/comments/comments.component"
|
|
7
|
+
|
|
8
|
+
document.addEventListener('DOMContentLoaded', function () {
|
|
9
|
+
function addEventListeners(rootElement) {
|
|
10
|
+
rootElement.querySelectorAll("[data-decidim-posts-comments]").forEach((el) => {
|
|
11
|
+
const $el = $(el);
|
|
12
|
+
let comments = $(el).data("comments");
|
|
13
|
+
if (!comments) {
|
|
14
|
+
comments = new CommentsComponent($el, $el.data("decidim-posts-comments"));
|
|
15
|
+
}
|
|
16
|
+
comments.mountComponent();
|
|
17
|
+
$(el).data("comments", comments);
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const loadMoreBtn = rootElement.querySelector('#loadMoreBtn');
|
|
21
|
+
if (loadMoreBtn) {
|
|
22
|
+
loadMoreBtn.addEventListener('click', loadMoreButtonClicked);
|
|
23
|
+
observer.observe(loadMoreBtn);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
rootElement
|
|
27
|
+
.querySelectorAll('.posts__post_actions_submenu > button')
|
|
28
|
+
.forEach((button) => {
|
|
29
|
+
const submenuId = button.getAttribute('aria-controls');
|
|
30
|
+
const submenu = rootElement.querySelector(`#${submenuId}`);
|
|
31
|
+
if (submenu) {
|
|
32
|
+
new Submenu(button, submenu);
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
rootElement
|
|
37
|
+
.querySelectorAll('.posts__post_reactions_submenu > button')
|
|
38
|
+
.forEach((button) => {
|
|
39
|
+
const submenuId = button.getAttribute('aria-controls');
|
|
40
|
+
const submenu = rootElement.querySelector(`#${submenuId}`);
|
|
41
|
+
if (submenu) {
|
|
42
|
+
new Submenu(button, submenu);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
rootElement.querySelectorAll('.reaction_btn').forEach((button) => {
|
|
47
|
+
const reactionTypeId = button.getAttribute('data-reaction-id');
|
|
48
|
+
const reactionableGlobalId = button.getAttribute('data-reactionable-id');
|
|
49
|
+
const url = button.getAttribute('data-reaction-url');
|
|
50
|
+
if (reactionTypeId && url) {
|
|
51
|
+
button.addEventListener('click', function (event) {
|
|
52
|
+
let reaction = button.getAttribute('data-reaction');
|
|
53
|
+
event.preventDefault();
|
|
54
|
+
fetch(url, {
|
|
55
|
+
method: 'POST',
|
|
56
|
+
headers: {
|
|
57
|
+
'Content-Type': 'application/json',
|
|
58
|
+
'X-CSRF-Token': document.querySelector('meta[name="csrf-token"]')
|
|
59
|
+
.content,
|
|
60
|
+
Accept: 'text/html',
|
|
61
|
+
},
|
|
62
|
+
body: JSON.stringify({
|
|
63
|
+
reaction_type_id: reactionTypeId,
|
|
64
|
+
resource_id: reactionableGlobalId,
|
|
65
|
+
}),
|
|
66
|
+
})
|
|
67
|
+
.then((response) => {
|
|
68
|
+
if (!response.ok) {
|
|
69
|
+
throw new Error('Network response was not ok');
|
|
70
|
+
}
|
|
71
|
+
return response.text();
|
|
72
|
+
})
|
|
73
|
+
.then((response) => {
|
|
74
|
+
var resourceId = reactionableGlobalId.split('/').pop();
|
|
75
|
+
var reactionsBlock = document.getElementById(
|
|
76
|
+
`feeds_post-${resourceId}_reactions`
|
|
77
|
+
);
|
|
78
|
+
var submenuId = `post_${resourceId}_posts__post_reactions_submenu`;
|
|
79
|
+
var submenu = document.querySelector(`#${submenuId}`);
|
|
80
|
+
var submenuButtonId = `post_${resourceId}_posts__post_reactions_submenuButton`;
|
|
81
|
+
var submenuButton = document.querySelector(
|
|
82
|
+
`#${submenuButtonId}`
|
|
83
|
+
);
|
|
84
|
+
if (submenuButton.getAttribute('data-reaction') === reaction) {
|
|
85
|
+
reaction = '';
|
|
86
|
+
}
|
|
87
|
+
submenuButton.setAttribute('data-reaction', reaction);
|
|
88
|
+
// replace the reactions block with the new one
|
|
89
|
+
reactionsBlock.innerHTML = response;
|
|
90
|
+
submenuButton.setAttribute('aria-expanded', false);
|
|
91
|
+
submenu.classList.toggle('hidden', true);
|
|
92
|
+
})
|
|
93
|
+
.catch((error) => {
|
|
94
|
+
console.error(
|
|
95
|
+
'There was a problem while updating the reactions:',
|
|
96
|
+
error
|
|
97
|
+
);
|
|
98
|
+
});
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
// Select all comments__header h2 elements
|
|
104
|
+
const commentsHeaders = rootElement.querySelectorAll(
|
|
105
|
+
'.comments__header h2'
|
|
106
|
+
);
|
|
107
|
+
commentsHeaders.forEach((commentsHeader) => {
|
|
108
|
+
const parentContainer = commentsHeader.closest('[data-decidim-posts-comments]');
|
|
109
|
+
const parentId = parentContainer.getAttribute('id');
|
|
110
|
+
commentsHeader.setAttribute('aria-controls', `${parentId}-threads`);
|
|
111
|
+
commentsHeader.setAttribute('aria-expanded', 'false');
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
const newCommentBtns = rootElement.querySelectorAll('.newCommentBtn');
|
|
115
|
+
const showCommentsBtns = rootElement.querySelectorAll(
|
|
116
|
+
'.comments__header h2'
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
newCommentBtns.forEach((newCommentBtn) => {
|
|
120
|
+
addActionToNewCommentBtn(newCommentBtn);
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
showCommentsBtns.forEach((showCommentsBtn) => {
|
|
124
|
+
addActionToShowCommentsBtn(showCommentsBtn);
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
const spinner = "<span class='loading-spinner'></span>";
|
|
129
|
+
|
|
130
|
+
// Implement infinite scroll
|
|
131
|
+
const observer = new IntersectionObserver((entries) => {
|
|
132
|
+
if (entries[0].isIntersecting) {
|
|
133
|
+
loadMore(entries[0].target);
|
|
134
|
+
}
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
function loadMoreButtonClicked(event) {
|
|
138
|
+
event.preventDefault();
|
|
139
|
+
|
|
140
|
+
loadMore(event.target);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function loadMore(button) {
|
|
144
|
+
// remove event listener to prevent multiple clicks
|
|
145
|
+
button.removeEventListener('click', loadMoreButtonClicked);
|
|
146
|
+
const oldBtn = button.innerHTML;
|
|
147
|
+
button.innerHTML = spinner;
|
|
148
|
+
|
|
149
|
+
// get url from data-url attribute
|
|
150
|
+
const url = button.getAttribute('data-url');
|
|
151
|
+
|
|
152
|
+
// get html from url and add page as query parameter
|
|
153
|
+
fetch(url)
|
|
154
|
+
.then((response) => {
|
|
155
|
+
if (!response.ok) {
|
|
156
|
+
// enable the button again
|
|
157
|
+
button.addEventListener('click', loadMoreButtonClicked);
|
|
158
|
+
// reset the button text
|
|
159
|
+
button.innerHTML = oldBtn;
|
|
160
|
+
throw new Error('Network response was not ok');
|
|
161
|
+
}
|
|
162
|
+
return response.text();
|
|
163
|
+
})
|
|
164
|
+
.then((html) => {
|
|
165
|
+
// activate all buttons in the new html
|
|
166
|
+
const tempContainer = document.createElement('div');
|
|
167
|
+
tempContainer.innerHTML = html;
|
|
168
|
+
const fragment = document.createDocumentFragment();
|
|
169
|
+
addEventListeners(tempContainer);
|
|
170
|
+
Array.from(tempContainer.children).forEach((element) => {
|
|
171
|
+
fragment.appendChild(element);
|
|
172
|
+
});
|
|
173
|
+
|
|
174
|
+
// replace the button with the new html
|
|
175
|
+
button.parentNode.replaceChild(fragment, button);
|
|
176
|
+
// alternative:
|
|
177
|
+
// button.parentNode.insertAfter(fragment, button);
|
|
178
|
+
// button.remove();
|
|
179
|
+
|
|
180
|
+
// add event listener to new button
|
|
181
|
+
const newButton = document.getElementById('loadMoreBtn');
|
|
182
|
+
if (newButton) {
|
|
183
|
+
newButton.addEventListener('click', loadMoreButtonClicked);
|
|
184
|
+
observer.observe(newButton);
|
|
185
|
+
}
|
|
186
|
+
})
|
|
187
|
+
.catch((error) => {
|
|
188
|
+
// enable the button again
|
|
189
|
+
button.addEventListener('click', loadMoreButtonClicked);
|
|
190
|
+
// reset the button text
|
|
191
|
+
button.innerHTML = oldBtn;
|
|
192
|
+
console.error('Error:', error);
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// add event listeners to all the buttons found in the document
|
|
197
|
+
addEventListeners(document);
|
|
198
|
+
|
|
199
|
+
function addActionToNewCommentBtn(newCommentBtn) {
|
|
200
|
+
newCommentBtn.addEventListener('click', function () {
|
|
201
|
+
const postId = newCommentBtn.getAttribute('data-post-id');
|
|
202
|
+
const modelType = newCommentBtn.getAttribute('data-model-type');
|
|
203
|
+
const showCommentBtnId = `comments-for-${modelType}-${postId}`;
|
|
204
|
+
const controlledDivId = `new_comment_for_${modelType}_${postId}`;
|
|
205
|
+
const commentsDivId = `comments-for-${modelType}-${postId}-threads`;
|
|
206
|
+
const showCommentBtn = document.getElementById(showCommentBtnId);
|
|
207
|
+
|
|
208
|
+
const wasExpanded =
|
|
209
|
+
newCommentBtn.getAttribute('aria-expanded') === 'true';
|
|
210
|
+
const showCommentsWasExpanded =
|
|
211
|
+
showCommentBtn.getAttribute('aria-expanded') === 'true';
|
|
212
|
+
const controlledDivIds = newCommentBtn
|
|
213
|
+
.getAttribute('aria-controls')
|
|
214
|
+
.split(' ');
|
|
215
|
+
|
|
216
|
+
const controlledDiv = document.getElementById(controlledDivId);
|
|
217
|
+
newCommentBtn.setAttribute('aria-expanded', !wasExpanded);
|
|
218
|
+
showCommentBtn.setAttribute('aria-expanded', !showCommentsWasExpanded);
|
|
219
|
+
|
|
220
|
+
toggleCommentsVisibility(controlledDivId);
|
|
221
|
+
|
|
222
|
+
if (!wasExpanded) {
|
|
223
|
+
showDiv(commentsDivId);
|
|
224
|
+
controlledDiv.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
225
|
+
} else {
|
|
226
|
+
hideDiv(commentsDivId);
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function addActionToShowCommentsBtn(showCommentsBtn) {
|
|
232
|
+
showCommentsBtn.addEventListener('click', function () {
|
|
233
|
+
const controlledDivIds = showCommentsBtn
|
|
234
|
+
.getAttribute('aria-controls')
|
|
235
|
+
.split(' ');
|
|
236
|
+
controlledDivIds.forEach((controlledDivId) => {
|
|
237
|
+
const isExpanded =
|
|
238
|
+
showCommentsBtn.getAttribute('aria-expanded') === 'true';
|
|
239
|
+
showCommentsBtn.setAttribute('aria-expanded', !isExpanded);
|
|
240
|
+
toggleCommentsVisibility(controlledDivId);
|
|
241
|
+
});
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function toggleCommentsVisibility(controlledDivId) {
|
|
246
|
+
const controlledDiv = document.getElementById(controlledDivId);
|
|
247
|
+
|
|
248
|
+
if (controlledDiv.style.visibility === 'visible') {
|
|
249
|
+
hideDiv(controlledDivId);
|
|
250
|
+
} else {
|
|
251
|
+
showDiv(controlledDivId);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function showDiv(id) {
|
|
256
|
+
const div = document.getElementById(id);
|
|
257
|
+
div.style.height = 'auto';
|
|
258
|
+
div.style.visibility = 'visible';
|
|
259
|
+
div.style.marginTop = '8px';
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
function hideDiv(id) {
|
|
263
|
+
const div = document.getElementById(id);
|
|
264
|
+
div.style.height = '0';
|
|
265
|
+
div.style.visibility = 'hidden';
|
|
266
|
+
div.style.marginTop = '0';
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
initSurvey();
|
|
270
|
+
carousel.init();
|
|
271
|
+
host_status();
|
|
272
|
+
});
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
class Submenu {
|
|
2
|
+
constructor(button, submenu) {
|
|
3
|
+
this.button = button;
|
|
4
|
+
this.submenu = submenu;
|
|
5
|
+
this.init();
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
init() {
|
|
9
|
+
this.button.addEventListener('click', () => this.toggleSubmenu());
|
|
10
|
+
document.addEventListener('click', (event) =>
|
|
11
|
+
this.handleClickOutside(event)
|
|
12
|
+
);
|
|
13
|
+
this.submenu.addEventListener('keydown', (event) =>
|
|
14
|
+
this.handleKeydown(event)
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
toggleSubmenu() {
|
|
19
|
+
const isExpanded = this.button.getAttribute('aria-expanded') === 'true';
|
|
20
|
+
this.button.setAttribute('aria-expanded', !isExpanded);
|
|
21
|
+
this.submenu.classList.toggle('hidden', isExpanded);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
handleClickOutside(event) {
|
|
25
|
+
if (
|
|
26
|
+
!this.button.contains(event.target) &&
|
|
27
|
+
!this.submenu.contains(event.target)
|
|
28
|
+
) {
|
|
29
|
+
this.closeSubmenu();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
handleKeydown(event) {
|
|
34
|
+
if (event.key === 'Escape') {
|
|
35
|
+
this.closeSubmenu();
|
|
36
|
+
this.button.focus();
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
closeSubmenu() {
|
|
41
|
+
this.button.setAttribute('aria-expanded', 'false');
|
|
42
|
+
this.submenu.classList.add('hidden');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export default Submenu;
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
export function initSurvey() {
|
|
2
|
+
// Add event listener to the new survey button
|
|
3
|
+
const liveRegion = document.getElementById(
|
|
4
|
+
'posts__post_newSurvey_liveRegion'
|
|
5
|
+
);
|
|
6
|
+
const newSurveyButton = document.querySelector('.posts__post_newSurvey-btn');
|
|
7
|
+
if (newSurveyButton)
|
|
8
|
+
newSurveyButton.addEventListener('click', () => {
|
|
9
|
+
const questionContainer = document.getElementById(
|
|
10
|
+
'posts__post_newSurvey_questionsContainer'
|
|
11
|
+
);
|
|
12
|
+
|
|
13
|
+
// copy content from question_template to questionContainer
|
|
14
|
+
const template = document.getElementById('question_template');
|
|
15
|
+
var content = template.innerHTML.replace(
|
|
16
|
+
/NEW_RECORD/g,
|
|
17
|
+
new Date().getTime()
|
|
18
|
+
);
|
|
19
|
+
questionContainer.insertAdjacentHTML('beforeend', content);
|
|
20
|
+
liveRegion.textContent =
|
|
21
|
+
window.translations.newSurvey.newQuestionResponse;
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
// TODO: this does not work as the button does not exist yet and there will be multiple buttons
|
|
25
|
+
document.addEventListener('click', (event) => {
|
|
26
|
+
if (event.target.classList.contains('posts__post_newAnswer-btn')) {
|
|
27
|
+
const questionId = event.target.dataset.questionId;
|
|
28
|
+
// get div with class posts__post_newSurvey_answersContainer inside the same container as the clicked button
|
|
29
|
+
const answerContainer = document.getElementById(
|
|
30
|
+
`posts__post_newSurvey_answersContainer-${questionId}`
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
const questionAnswers = answerContainer.children.length + 1;
|
|
34
|
+
// answerContainer.dataset.questionAnswers = questionAnswers;
|
|
35
|
+
|
|
36
|
+
// copy content from question_template to questionContainer
|
|
37
|
+
const template = document.getElementById('answer_template');
|
|
38
|
+
var content = template.innerHTML.replace(
|
|
39
|
+
/NEW_RECORD/g,
|
|
40
|
+
new Date().getTime()
|
|
41
|
+
);
|
|
42
|
+
content = content.replace(/QUESTION_RECORD/g, questionId);
|
|
43
|
+
content = content.replace(/ANSWER_NR/g, questionAnswers);
|
|
44
|
+
|
|
45
|
+
answerContainer.insertAdjacentHTML('beforeend', content);
|
|
46
|
+
liveRegion.textContent = window.translations.newSurvey.newAnswerResponse;
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
document.querySelectorAll('.survey-answer-checkbox').forEach((checkbox) => {
|
|
51
|
+
checkbox.addEventListener('change', (event) => {
|
|
52
|
+
const questionId = event.target.dataset.questionId;
|
|
53
|
+
const answerId = event.target.dataset.answerId;
|
|
54
|
+
const checked = event.target.checked;
|
|
55
|
+
console.log(questionId, answerId, checked);
|
|
56
|
+
Rails.ajax({
|
|
57
|
+
url: 'user_answers/',
|
|
58
|
+
type: 'GET',
|
|
59
|
+
data: new URLSearchParams({
|
|
60
|
+
question_id: questionId,
|
|
61
|
+
answer_id: answerId,
|
|
62
|
+
checked: checked,
|
|
63
|
+
}),
|
|
64
|
+
success: function (response) {
|
|
65
|
+
console.log(response);
|
|
66
|
+
for (const [answerId, counter] of Object.entries(
|
|
67
|
+
response.user_answers
|
|
68
|
+
)) {
|
|
69
|
+
// for each user_answer, change the width of the progress bar
|
|
70
|
+
const progressBar = document.getElementById(
|
|
71
|
+
`answer-${answerId}-progressbar`
|
|
72
|
+
);
|
|
73
|
+
const percentage =
|
|
74
|
+
response.survey_responses_count > 0
|
|
75
|
+
? (counter / response.survey_responses_count) * 100
|
|
76
|
+
: 0;
|
|
77
|
+
progressBar.style.width = `${percentage}%`;
|
|
78
|
+
const counterSpan = document.getElementById(
|
|
79
|
+
`answer-${answerId}-counter`
|
|
80
|
+
);
|
|
81
|
+
counterSpan.textContent = counter;
|
|
82
|
+
const totalSpan = document.getElementById(
|
|
83
|
+
`answer-${answerId}-total`
|
|
84
|
+
);
|
|
85
|
+
totalSpan.textContent = `${response.survey_responses_count}`;
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
error: function (xhr, status, error) {
|
|
89
|
+
console.log(xhr, status, error);
|
|
90
|
+
},
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--dg-color-white: 255 255 255;
|
|
3
|
+
--dg-color-black: 60 57 52;
|
|
4
|
+
--dg-color-post: 229 57 144;
|
|
5
|
+
--dg-color-help: 1 114 187;
|
|
6
|
+
--dg-color-sharecare: 36 166 32;
|
|
7
|
+
--dg-color-host: 219 15 16;
|
|
8
|
+
--dg-color-survey: 50 49 143;
|
|
9
|
+
--dg-color-calendar: 253 182 32;
|
|
10
|
+
}
|