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.
Files changed (117) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE-AGPLv3.txt +661 -0
  3. data/README.md +40 -0
  4. data/Rakefile +9 -0
  5. data/app/cells/decidim/posts/comments/add_comment.erb +15 -0
  6. data/app/cells/decidim/posts/comments/comments_loading.erb +1 -0
  7. data/app/cells/decidim/posts/comments/order_control.erb +13 -0
  8. data/app/cells/decidim/posts/comments/show.erb +31 -0
  9. data/app/cells/decidim/posts/comments_cell.rb +158 -0
  10. data/app/cells/decidim/posts/content_blocks/posts/show.erb +3 -0
  11. data/app/cells/decidim/posts/content_blocks/posts_cell.rb +50 -0
  12. data/app/cells/decidim/posts/content_blocks/posts_settings_form/show.erb +3 -0
  13. data/app/cells/decidim/posts/content_blocks/posts_settings_form_cell.rb +23 -0
  14. data/app/cells/decidim/posts/feed_dropdown_metadata_cell.rb +19 -0
  15. data/app/cells/decidim/posts/meeting/show.erb +65 -0
  16. data/app/cells/decidim/posts/meeting_cell.rb +44 -0
  17. data/app/cells/decidim/posts/post/show.erb +30 -0
  18. data/app/cells/decidim/posts/post/survey.erb +68 -0
  19. data/app/cells/decidim/posts/post_attachments/show.erb +40 -0
  20. data/app/cells/decidim/posts/post_attachments_cell.rb +17 -0
  21. data/app/cells/decidim/posts/post_cell.rb +44 -0
  22. data/app/cells/decidim/posts/post_comment/show.erb +17 -0
  23. data/app/cells/decidim/posts/post_comment_cell.rb +49 -0
  24. data/app/cells/decidim/posts/post_header/show.erb +53 -0
  25. data/app/cells/decidim/posts/post_header_cell.rb +79 -0
  26. data/app/cells/decidim/posts/post_host/show.erb +74 -0
  27. data/app/cells/decidim/posts/post_host_cell.rb +73 -0
  28. data/app/cells/decidim/posts/post_metadata/show.erb +9 -0
  29. data/app/cells/decidim/posts/post_metadata_cell.rb +67 -0
  30. data/app/cells/decidim/posts/reaction_menu/show.erb +18 -0
  31. data/app/cells/decidim/posts/reaction_menu/styles.erb +7 -0
  32. data/app/cells/decidim/posts/reaction_menu_cell.rb +26 -0
  33. data/app/cells/decidim/posts/reactions/show.erb +8 -0
  34. data/app/cells/decidim/posts/reactions_cell.rb +22 -0
  35. data/app/commands/decidim/posts/add_reaction_to_resource.rb +90 -0
  36. data/app/commands/decidim/posts/create_post.rb +112 -0
  37. data/app/commands/decidim/posts/destroy_post.rb +20 -0
  38. data/app/commands/decidim/posts/remove_reaction_from_resource.rb +41 -0
  39. data/app/commands/decidim/posts/update_post.rb +72 -0
  40. data/app/controllers/concerns/decidim/posts/admin/filterable.rb +46 -0
  41. data/app/controllers/concerns/decidim/posts/reactionable.rb +31 -0
  42. data/app/controllers/decidim/posts/admin/application_controller.rb +26 -0
  43. data/app/controllers/decidim/posts/admin/posts_controller.rb +93 -0
  44. data/app/controllers/decidim/posts/application_controller.rb +18 -0
  45. data/app/controllers/decidim/posts/meetings_controller.rb +176 -0
  46. data/app/controllers/decidim/posts/posts_controller.rb +202 -0
  47. data/app/controllers/decidim/posts/reactions_controller.rb +54 -0
  48. data/app/controllers/decidim/posts/user_answers_controller.rb +36 -0
  49. data/app/events/decidim/posts/resource_reacted_event.rb +38 -0
  50. data/app/forms/decidim/posts/answer_form.rb +13 -0
  51. data/app/forms/decidim/posts/post_form.rb +121 -0
  52. data/app/forms/decidim/posts/question_form.rb +20 -0
  53. data/app/helpers/decidim/posts/admin/posts_helper.rb +8 -0
  54. data/app/helpers/decidim/posts/application_helper.rb +20 -0
  55. data/app/helpers/decidim/posts/post_cells_helper.rb +35 -0
  56. data/app/helpers/decidim/posts/posts_helper.rb +34 -0
  57. data/app/helpers/decidim/posts/reaction_helper.rb +22 -0
  58. data/app/models/decidim/posts/answer.rb +13 -0
  59. data/app/models/decidim/posts/application_record.rb +10 -0
  60. data/app/models/decidim/posts/post.rb +116 -0
  61. data/app/models/decidim/posts/question.rb +17 -0
  62. data/app/models/decidim/posts/reaction.rb +22 -0
  63. data/app/models/decidim/posts/reaction_type.rb +13 -0
  64. data/app/models/decidim/posts/user_answer.rb +11 -0
  65. data/app/packs/entrypoints/decidim_posts.js +5 -0
  66. data/app/packs/entrypoints/decidim_posts.scss +1 -0
  67. data/app/packs/images/decidim/posts/icon.svg +1 -0
  68. data/app/packs/src/decidim/posts/carousel.js +112 -0
  69. data/app/packs/src/decidim/posts/host_status.js +75 -0
  70. data/app/packs/src/decidim/posts/newFeeds.js +98 -0
  71. data/app/packs/src/decidim/posts/posts.js +272 -0
  72. data/app/packs/src/decidim/posts/submenu.js +46 -0
  73. data/app/packs/src/decidim/posts/survey.js +94 -0
  74. data/app/packs/stylesheets/decidim/posts/_variables.scss +10 -0
  75. data/app/packs/stylesheets/decidim/posts/posts.scss +415 -0
  76. data/app/permissions/decidim/posts/admin/permissions.rb +23 -0
  77. data/app/permissions/decidim/posts/permissions.rb +101 -0
  78. data/app/presenters/decidim/posts/post_presenter.rb +45 -0
  79. data/app/views/decidim/posts/admin/posts/_post-tr.html.erb +45 -0
  80. data/app/views/decidim/posts/admin/posts/index.html.erb +54 -0
  81. data/app/views/decidim/posts/meetings/edit.html.erb +24 -0
  82. data/app/views/decidim/posts/posts/_admin_options.html.erb +30 -0
  83. data/app/views/decidim/posts/posts/_attachment.html.erb +24 -0
  84. data/app/views/decidim/posts/posts/_edit_form.html.erb +16 -0
  85. data/app/views/decidim/posts/posts/_feed.html.erb +8 -0
  86. data/app/views/decidim/posts/posts/_form.html.erb +104 -0
  87. data/app/views/decidim/posts/posts/_index.html.erb +49 -0
  88. data/app/views/decidim/posts/posts/_meeting_form.erb +18 -0
  89. data/app/views/decidim/posts/posts/_new.html.erb +33 -0
  90. data/app/views/decidim/posts/posts/_new_survey.html.erb +20 -0
  91. data/app/views/decidim/posts/posts/_new_survey_answer.html.erb +11 -0
  92. data/app/views/decidim/posts/posts/_new_survey_question.html.erb +17 -0
  93. data/app/views/decidim/posts/posts/_post.html.erb +11 -0
  94. data/app/views/decidim/posts/posts/_post_form.html.erb +5 -0
  95. data/app/views/decidim/posts/posts/_sidebar.html.erb +36 -0
  96. data/app/views/decidim/posts/posts/edit.html.erb +34 -0
  97. data/app/views/decidim/posts/posts/index.html.erb +1 -0
  98. data/app/views/decidim/posts/posts/show.html.erb +12 -0
  99. data/app/views/decidim/posts/reactions/_update_buttons_and_counters.html.erb +1 -0
  100. data/config/assets.rb +9 -0
  101. data/config/i18n-tasks.yml +10 -0
  102. data/config/locales/bs.yml +215 -0
  103. data/config/locales/de.yml +217 -0
  104. data/config/locales/en.yml +216 -0
  105. data/config/locales/hr.yml +219 -0
  106. data/config/locales/it.yml +215 -0
  107. data/config/locales/sr.yml +220 -0
  108. data/config/locales/tr.yml +219 -0
  109. data/lib/decidim/posts/admin.rb +10 -0
  110. data/lib/decidim/posts/admin_engine.rb +25 -0
  111. data/lib/decidim/posts/component.rb +59 -0
  112. data/lib/decidim/posts/content_blocks/content_blocks_homepage.rb +19 -0
  113. data/lib/decidim/posts/engine.rb +84 -0
  114. data/lib/decidim/posts/test/factories.rb +14 -0
  115. data/lib/decidim/posts/version.rb +9 -0
  116. data/lib/decidim/posts.rb +13 -0
  117. metadata +183 -0
@@ -0,0 +1,415 @@
1
+ /* css for decidim_feeds */
2
+
3
+ @import '_variables.scss';
4
+
5
+ #posts__post_newElement {
6
+ @apply fixed left-0 top-0 right-0 bottom-0 w-full h-full bg-white bg-opacity-60 z-50 justify-center items-start pt-[72px] hidden;
7
+ &.open {
8
+ --tw-ring-color: theme('colors.feeds.sidebar');
9
+ @apply flex;
10
+ .circle {
11
+ svg {
12
+ @apply rotate-0 motion-safe:transition-transform;
13
+ }
14
+ }
15
+ }
16
+ .circle {
17
+ @apply w-[52px] h-[52px] p-2 bg-white rounded-[52px] shadow-feedMenu justify-center items-center inline-flex text-black;
18
+ svg {
19
+ @apply w-[36px] h-[36px] fill-feeds-sidebar rotate-45 motion-safe:transition-transform;
20
+ }
21
+ }
22
+ .posts__post_newElement_modal_frame {
23
+ --tw-ring-color: theme('colors.white');
24
+ @apply p-4 gap-2 w-full shadow-feedBox rounded lg:max-w-screen-md bg-white w-[calc(100%-2rem)] max-h-[80vh] overflow-auto motion-safe:transition-all;
25
+ }
26
+ .posts__post_newElement_modal_content {
27
+ @apply flex flex-col gap-2;
28
+ }
29
+ .category-selection {
30
+ @apply flex gap-2 flex-wrap justify-center;
31
+ button {
32
+ @apply border-2 hover:bg-white hover:text-black;
33
+ &:hover {
34
+ background: white;
35
+ }
36
+ &[data-category='post'] {
37
+ @apply border-feeds-post focus:outline-feeds-post;
38
+ &:hover,
39
+ &.active {
40
+ @apply outline outline-offset-2 outline-feeds-post;
41
+ }
42
+ }
43
+ &[data-category='host'] {
44
+ @apply border-feeds-host focus:outline-feeds-host;
45
+ &:hover,
46
+ &.active {
47
+ @apply outline outline-offset-2 outline-feeds-host;
48
+ }
49
+ }
50
+ &[data-category='sharecare'] {
51
+ @apply border-feeds-sharecare focus:outline-feeds-sharecare;
52
+ &:hover,
53
+ &.active {
54
+ @apply outline outline-offset-2 outline-feeds-sharecare;
55
+ }
56
+ }
57
+ &[data-category='survey'] {
58
+ @apply border-feeds-survey focus:outline-feeds-survey;
59
+ &:hover,
60
+ &.active {
61
+ @apply outline outline-offset-2 outline-feeds-survey;
62
+ }
63
+ }
64
+ &[data-category='calendar'] {
65
+ @apply border-feeds-calendar focus:outline-feeds-calendar;
66
+ &:hover,
67
+ &.active {
68
+ @apply outline outline-offset-2 outline-feeds-calendar;
69
+ }
70
+ }
71
+ }
72
+ }
73
+ form {
74
+ @apply hidden opacity-0 scale-0 motion-safe:transition-transform motion-safe:transition-opacity;
75
+ &.open {
76
+ @apply flex flex-col gap-4 opacity-100 scale-100 motion-safe:transition-transform motion-safe:transition-opacity;
77
+ }
78
+ label {
79
+ font-size: 1rem;
80
+ }
81
+ input,
82
+ textarea {
83
+ margin-block-start: 0;
84
+ }
85
+ .posts__post_newElement_Body {
86
+ @apply border-0 bg-feeds-formBody;
87
+ }
88
+ .postType {
89
+ @apply flex gap-2 flex-wrap justify-center;
90
+
91
+ input[type='radio']:checked + label {
92
+ @apply bg-primary text-white focus:outline-primary;
93
+ }
94
+ }
95
+ .posts__post_newElement_Xtra {
96
+ @apply relative hidden opacity-0 scale-0 motion-safe:transition-transform motion-safe:transition-opacity;
97
+ &.open {
98
+ @apply block opacity-100 scale-100 motion-safe:transition-transform motion-safe:transition-opacity;
99
+ }
100
+ &.posts__post_newSurvey {
101
+ .posts__post_newSurvey-btn {
102
+ @apply flex justify-center items-center gap-2 text-black font-medium p-4 bg-feeds-bg w-full rounded;
103
+ }
104
+ #newQuestion {
105
+ --tw-ring-color: theme('colors.feeds.sidebar');
106
+ @apply top-0 left-0 w-full h-full bg-white p-4 ring-1 rounded;
107
+ }
108
+ }
109
+ }
110
+ .posts__post_newElement_Media {
111
+ @apply px-2 pb-2 pt-0;
112
+ svg {
113
+ @apply w-[24px] h-auto;
114
+ }
115
+ .active-uploads {
116
+ @apply mt-0 pb-2;
117
+ }
118
+ button {
119
+ @apply mt-0;
120
+ }
121
+ }
122
+ .sndBtn {
123
+ @apply self-end;
124
+ }
125
+ }
126
+ }
127
+
128
+ .feeds__container {
129
+ @apply pr-[91px] md:pr-[101px] lg:pr-0 order-1 grow min-h-[calc(100vh-72px)];
130
+ .feeds__body {
131
+ @apply flex-grow flex flex-wrap gap-4 items-start;
132
+ .posts__post {
133
+ @apply gap-4 ring-1 hover:cursor-default md:col-start-1 md:col-end-4 lg:col-start-2 lg:col-end-8 xl:col-start-2 xl:col-end-10;
134
+ .card__grid-text {
135
+ @apply py-2 text-pretty;
136
+ p {
137
+ @apply text-black;
138
+ }
139
+ a {
140
+ @apply break-words break-all underline motion-safe:transition-colors hover:text-feeds-notification hover:no-underline;
141
+ }
142
+ }
143
+ &[data-content] {
144
+ @apply shadow-feedBox;
145
+ }
146
+ &[data-content='post'] {
147
+ --tw-ring-color: theme('colors.feeds.post');
148
+ }
149
+ &[data-content='sharecare'] {
150
+ --tw-ring-color: theme('colors.feeds.sharecare');
151
+ }
152
+ &[data-content='host'] {
153
+ --tw-ring-color: theme('colors.feeds.host');
154
+ &.host-highlight {
155
+ @apply bg-feeds-host font-medium;
156
+ .content-block__description {
157
+ @apply text-white;
158
+ button {
159
+ @apply text-white;
160
+ }
161
+ }
162
+ .card__grid-metadata {
163
+ .posts__post_actions_submenu {
164
+ button.openButton,
165
+ button.openButton span {
166
+ @apply text-white;
167
+ }
168
+ &:has(ul:empty) {
169
+ @apply hidden;
170
+ }
171
+ }
172
+ }
173
+ }
174
+ &.posts__post_host-handling {
175
+ @apply border-t-8 border-warning;
176
+ }
177
+ &.posts__post_host-complete {
178
+ @apply border-t-8 border-success;
179
+ }
180
+ .host-icon {
181
+ @apply absolute -right-2 -top-2 bg-white fill-feeds-host;
182
+ }
183
+ }
184
+ &[data-content='survey'] {
185
+ --tw-ring-color: theme('colors.feeds.survey');
186
+ .posts__post_survey {
187
+ @apply flex flex-col gap-2 text-sm font-bold px-2;
188
+ .posts__post_survey-question {
189
+ @apply flex flex-col p-2 gap-2 rounded bg-feeds-bg;
190
+ .posts__post_survey-question-answer {
191
+ @apply font-medium flex flex-col px-2;
192
+ .posts__post_survey-question-answerInput {
193
+ @apply flex py-1 gap-2;
194
+ span {
195
+ @apply text-sm shrink-0;
196
+ }
197
+ }
198
+ }
199
+ }
200
+ }
201
+ }
202
+ &[data-content='calendar'] {
203
+ --tw-ring-color: theme('colors.feeds.calendar');
204
+ }
205
+ .card__grid-metadata {
206
+ @apply gap-2 items-center flex-nowrap text-black px-2 pt-2;
207
+ .author {
208
+ @apply mr-auto shrink;
209
+ }
210
+ .posts__post_actions {
211
+ @apply flex gap-4;
212
+ span {
213
+ @apply flex items-center gap-1;
214
+ }
215
+ .endorsers-list__trigger {
216
+ @apply hidden;
217
+ }
218
+ #endorsement-button {
219
+ @apply border-0 p-0 font-normal;
220
+ &:hover {
221
+ background: none;
222
+ color: inherit;
223
+ }
224
+ svg {
225
+ @apply fill-black;
226
+ }
227
+ }
228
+ .posts__post_actions_submenu {
229
+ button.openButton {
230
+ span {
231
+ @apply leading-[0] text-3xl text-feeds-sidebar;
232
+ }
233
+ }
234
+ }
235
+ }
236
+ }
237
+ .posts__post_gallery {
238
+ li {
239
+ transition: opacity 0.5s ease;
240
+ opacity: 0;
241
+ display: none;
242
+ &.active {
243
+ opacity: 1;
244
+ display: block;
245
+ }
246
+ @supports not (aspect-ratio: 4 / 3) {
247
+ &::before {
248
+ float: left;
249
+ padding-top: 75%;
250
+ content: '';
251
+ }
252
+
253
+ &::after {
254
+ display: block;
255
+ content: '';
256
+ clear: both;
257
+ }
258
+ }
259
+ }
260
+ }
261
+ .posts__post_comments {
262
+ @apply px-2;
263
+ #comments {
264
+ .comments__header {
265
+ @apply flex-row justify-end h-8 items-center mb-0;
266
+ h2 {
267
+ @apply flex text-sm font-medium gap-1 cursor-pointer;
268
+ svg {
269
+ @apply w-[14px] h-auto fill-black;
270
+ }
271
+ }
272
+ }
273
+ .comment-order-by {
274
+ @apply hidden;
275
+ }
276
+ .comment-threads,
277
+ .add-comment:not(.comment__additionalreply) form.new_comment {
278
+ @apply h-0 invisible motion-safe:transition-transform;
279
+ }
280
+ .comment-threads {
281
+ .comment-thread {
282
+ .comment__header {
283
+ @apply -ml-8;
284
+ }
285
+ .author__avatar-container {
286
+ @apply w-6 h-6;
287
+ }
288
+ }
289
+ }
290
+ .add-comment {
291
+ @apply mt-4;
292
+ label {
293
+ @apply block text-md font-medium;
294
+ }
295
+ textarea {
296
+ @apply block w-full sm:text-sm sm:leading-6;
297
+ }
298
+ }
299
+ .add-comment:not(.comment__additionalreply) {
300
+ @apply mt-0;
301
+ }
302
+ }
303
+ }
304
+ &.posts__post_newElement {
305
+ --tw-ring-color: theme('colors.white');
306
+ @apply gap-4;
307
+ .circle {
308
+ @apply w-[52px] h-[52px] p-2 bg-white rounded-[52px] shadow-feedMenu justify-center items-center inline-flex text-black;
309
+ svg {
310
+ @apply w-[36px] h-[36px] fill-feeds-sidebar rotate-45 motion-safe:transition-transform;
311
+ }
312
+ }
313
+ }
314
+ }
315
+ }
316
+ }
317
+
318
+ .posts__aside {
319
+ @apply shrink-0 max-lg:right-[16px] max-lg:top-[88px] max-lg:bottom-[80px] max-lg:fixed max-w-[72px] order-2 flex flex-col justify-between lg:justify-start;
320
+ ul {
321
+ @apply flex flex-col space-y-4;
322
+ a {
323
+ @apply flex flex-col items-center font-medium text-sm md:text-md text-feeds-sidebar text-center;
324
+ svg {
325
+ @apply w-[24px] h-auto fill-feeds-sidebar;
326
+ }
327
+ &.active {
328
+ span {
329
+ @apply font-bold;
330
+ }
331
+ &[data-filter='post'] {
332
+ svg {
333
+ @apply fill-feeds-post;
334
+ }
335
+ }
336
+ &[data-filter='sharecare'] {
337
+ svg {
338
+ @apply fill-feeds-sharecare;
339
+ }
340
+ }
341
+ &[data-filter='host'] {
342
+ svg {
343
+ @apply fill-feeds-host;
344
+ }
345
+ }
346
+ &[data-filter='survey'] {
347
+ svg {
348
+ @apply fill-feeds-survey;
349
+ }
350
+ }
351
+ &[data-filter='calendar'] {
352
+ svg {
353
+ @apply fill-feeds-calendar;
354
+ }
355
+ }
356
+ }
357
+ &[data-filter='host'] {
358
+ @apply mt-8;
359
+ }
360
+ }
361
+ }
362
+ }
363
+
364
+ // tooltip
365
+ .author__tooltip {
366
+ &[role='tooltip'] {
367
+ @apply bg-white text-black rounded-2xl shadow-feedMenu;
368
+ .author__name {
369
+ @apply text-black;
370
+ &:hover {
371
+ @apply no-underline;
372
+ }
373
+ }
374
+ &::before {
375
+ @apply bg-white;
376
+ }
377
+ .button {
378
+ @apply border-black bg-white text-black;
379
+ }
380
+ }
381
+ }
382
+
383
+ // fix bottom menu overlapping content on desktops
384
+ #content {
385
+ @apply lg:mb-28;
386
+ }
387
+
388
+ // color hacks
389
+ .content-block__description {
390
+ @apply text-black;
391
+ }
392
+
393
+ // long text cut off
394
+ .content-block__description[data-component='accordion']
395
+ [id*='panel'][aria-hidden='true']::after,
396
+ .content-block__description[data-component='accordion']
397
+ [id*='panel'][aria-hidden='true']::before {
398
+ content: none;
399
+ }
400
+
401
+ .content-block__description[data-component='accordion'] button {
402
+ margin-block-start: 1rem;
403
+ }
404
+
405
+ // reactions icons
406
+
407
+ .posts__post_reactions_submenu {
408
+ button {
409
+ &[data-reaction]:not([data-reaction='']) {
410
+ .reaction_icon {
411
+ @apply hidden;
412
+ }
413
+ }
414
+ }
415
+ }
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Posts
5
+ module Admin
6
+ class Permissions < Decidim::DefaultPermissions
7
+ def permissions
8
+ return permission_action if permission_action.scope != :admin
9
+ return permission_action unless user&.admin?
10
+
11
+ allow! if can_access?
12
+
13
+ permission_action
14
+ end
15
+
16
+ def can_access?
17
+ permission_action.subject == :feeds &&
18
+ permission_action.action == :read
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,101 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Posts
5
+ class Permissions < Decidim::DefaultPermissions
6
+ def permissions
7
+ return permission_action unless user
8
+
9
+ case permission_action.subject
10
+ when :post
11
+ case permission_action.action
12
+ when :create
13
+ allow! if can_create_posts?
14
+ when :edit
15
+ allow! if can_update_post?
16
+ when :delete
17
+ allow! if can_delete_post?
18
+ when :read
19
+ allow! if can_access?
20
+ when :change_post_status
21
+ allow! if change_post_status?
22
+ end
23
+ when :meeting
24
+ case permission_action.action
25
+ when :create
26
+ allow! if can_create_posts?
27
+ when :update
28
+ allow! if can_update_meeting?
29
+ when :withdraw
30
+ allow! if can_withdraw_meeting?
31
+ end
32
+ when :reaction
33
+ case permission_action.action
34
+ when :create
35
+ allow! if can_access?
36
+ when :withdraw
37
+ allow! if can_access?
38
+ end
39
+ end
40
+
41
+ permission_action
42
+ end
43
+
44
+ private
45
+
46
+ def post
47
+ @post ||= context.fetch(:post, nil) || context.fetch(:resource, nil)
48
+ end
49
+
50
+ def meeting
51
+ @meeting ||= context.fetch(:meeting, nil) || context.fetch(:resource, nil)
52
+ end
53
+
54
+ def can_access?
55
+ user.present?
56
+ end
57
+
58
+ def can_create_posts?
59
+ return false unless user
60
+ # component_settings&.creation_enabled_for_participants? && public_space_or_member?
61
+ public_space_or_member?
62
+ end
63
+
64
+ def can_update_post?
65
+ post.authored_by?(user)
66
+ end
67
+
68
+ def can_delete_post?
69
+ post.authored_by?(user) || user.admin?
70
+ end
71
+
72
+ def change_post_status?
73
+ participatory_space.admins.exists?(id: user.id)
74
+ end
75
+
76
+ def public_space_or_member?
77
+ participatory_space = context[:current_component].participatory_space
78
+
79
+ participatory_space.private_space? ? space_member?(participatory_space, user) : true
80
+ end
81
+
82
+ # Neither platform admins, nor space admins should be able to create meetings from the public side.
83
+ def space_member?(participatory_space, user)
84
+ return false unless user
85
+
86
+ participatory_space.participatory_space_private_users.exists?(decidim_user_id: user.id)
87
+ end
88
+
89
+ def can_update_meeting?
90
+ meeting.authored_by?(user) &&
91
+ !meeting.closed?
92
+ end
93
+
94
+ def can_withdraw_meeting?
95
+ meeting.authored_by?(user) &&
96
+ !meeting.withdrawn? &&
97
+ !meeting.past?
98
+ end
99
+ end
100
+ end
101
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Posts
5
+ #
6
+ # Decorator for Posts
7
+ #
8
+ class PostPresenter < Decidim::ResourcePresenter
9
+ include Rails.application.routes.mounted_helpers
10
+ include ActionView::Helpers::UrlHelper
11
+ include Decidim::SanitizeHelper
12
+
13
+ def post
14
+ __getobj__
15
+ end
16
+
17
+ def post_path
18
+ Decidim::ResourceLocatorPresenter.new(post).path
19
+ end
20
+
21
+ def title(links: false, extras: true, html_escape: false, all_locales: false)
22
+ return unless post
23
+
24
+ super post.title, links, html_escape, all_locales, extras:
25
+ end
26
+
27
+ def body(links: true, extras: true, strip_tags: false, all_locales: false)
28
+ return unless post
29
+
30
+ content_handle_locale(post.body, all_locales, extras, links, strip_tags)
31
+ end
32
+
33
+ def editor_body(all_locales: false, extras: true)
34
+ editor_locales(post.body, all_locales, extras:)
35
+ end
36
+
37
+ # def resource_manifest
38
+ # post.class.resource_manifest
39
+ # end
40
+
41
+ # private
42
+
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,45 @@
1
+ <tr data-id="<%= post.id %>">
2
+ <td>
3
+ <%= check_box_tag "post_ids_s[]", post.id, false, class: "js-check-all-post js-post-list-check js-post-id-#{post.id}" %><br>
4
+ </td>
5
+ <td class="!text-left">
6
+ <% if allowed_to? :edit, :post, post: post %>
7
+ <%= link_to present(post).title(html_escape: true), post_path(post) %><br>
8
+ <% else %>
9
+ <%= present(post).title(html_escape: true) %><br>
10
+ <% end %>
11
+ <div class="flex items-center gap-x-1 mt-2">
12
+ <%= icon "price-tag-3-line", class: "fill-gray w-4 h-4" %>
13
+ <%= post.category %>
14
+ </div>
15
+ </td>
16
+ <td class="table-list__date">
17
+ <%= l post.created_at, format: :decidim_short %>
18
+ </td>
19
+
20
+ <td>
21
+ <%= post.reactions_count %>
22
+ </td>
23
+
24
+ <td>
25
+ <%= post.comments_count %>
26
+ </td>
27
+
28
+ <td>
29
+ <%= post.status %>
30
+ </td>
31
+
32
+ <td class="table-list__actions">
33
+ <% if allowed_to? :edit, :post, post: post %>
34
+ <%= icon_link_to "pencil-line", edit_post_path(post), t("actions.edit_post", scope: "decidim.posts"), class: "action-icon--edit-post" %>
35
+ <% else %>
36
+ <span class="action-space icon"></span>
37
+ <% end %>
38
+
39
+ <%#= icon_with_link_to_post(post) %>
40
+
41
+ <%= icon_link_to "eye-line", resource_locator(post).path, t("actions.preview", scope: "decidim.posts.admin"), class: "action-icon--preview", target: :blank, data: { "external-link": false } %>
42
+
43
+ <%= resource_permissions_link(post) %>
44
+ </td>
45
+ </tr>
@@ -0,0 +1,54 @@
1
+ <% add_decidim_page_title(t(".title")) %>
2
+ <div class="card">
3
+ <div class="item_show__header">
4
+ <h1 class="item_show__header-title">
5
+ <div>
6
+ <%= t(".title") %>
7
+ <span id="js-selected-posts-count" class="component-counter component-counter--inline" title="<%= t("decidim.posts.admin.posts.index.selected") %>"></span>
8
+ </div>
9
+ <%#= render partial: "bulk-actions" %>
10
+ <%#= render partial: "decidim/admin/components/resource_action" %>
11
+ </h1>
12
+ </div>
13
+ <%#= admin_filter_selector(:posts) %>
14
+ <div class="table-scroll mt-16">
15
+ <table class="table-list">
16
+ <thead>
17
+ <tr>
18
+ <th>
19
+ <%#= check_box_tag "posts_bulk", "all", false, class: "js-check-all" %>
20
+ </th>
21
+ <th class="!text-left">
22
+ <%= t("models.post.fields.title", scope: "decidim.posts") %>
23
+ </th>
24
+ <th>
25
+ <%= t("models.post.fields.created_at", scope: "decidim.posts") %>
26
+ </th>
27
+
28
+ <th>
29
+ <%= t("models.post.fields.endorsements", scope: "decidim.posts") %>
30
+ </th>
31
+
32
+ <th>
33
+ <%= t("models.post.fields.comments", scope: "decidim.posts") %>
34
+ </th>
35
+
36
+ <th>
37
+ <%= t("models.post.fields.status", scope: "decidim.posts") %>
38
+ </th>
39
+
40
+ <th class="actions"><%= t("actions.title", scope: "decidim.posts") %></th>
41
+ </tr>
42
+ </thead>
43
+ <tbody>
44
+ <% posts.each do |post| %>
45
+ <%= render partial: "post-tr", locals: { post: } %>
46
+ <% end %>
47
+ </tbody>
48
+ </table>
49
+ </div>
50
+ </div>
51
+
52
+ <%#= decidim_paginate posts %>
53
+
54
+ <%#= append_javascript_pack_tag "decidim_posts_admin" %>
@@ -0,0 +1,24 @@
1
+ <main class="feeds__main home">
2
+ <!-- This is the sidebar that appears on the right side of the page -->
3
+ <%= render partial: "decidim/posts/posts/sidebar" %>
4
+ <div class="feeds__container">
5
+ <div class="feeds__body">
6
+ <div class="card__grid-home w-full lg:grid-cols-8 xl:grid-cols-12 gap-6">
7
+ <div class="card__grid posts__post p-2" data-content="calendar">
8
+ <%= decidim_form_for(@form, url: Decidim::EngineRouter.main_proxy(posts_component_for_meeting(@meeting)).meeting_path(@meeting), html: { class: "meetings_form new_meeting" }) do |form| %>
9
+ <div class="form__wrapper p-0 gap-4">
10
+ <%= render partial: "decidim/posts/posts/meeting_form", locals: { form: form } %>
11
+ </div>
12
+ <div class="form__wrapper-block flex-col-reverse md:flex-row justify-between">
13
+ <%= link_to t("decidim.components.posts.newFeed.cancel"), '/', class: "button button__sm button__transparent-secondary" %>
14
+ <%= form.submit "#{t("decidim.components.posts.newFeed.action")} #{icon('send-plane-line')}".html_safe, class: "sndBtn button button__sm button__transparent-primary", data: { disable: true } %>
15
+ </div>
16
+ <% end %>
17
+ </div>
18
+ </div>
19
+ <!-- In case the Module Decidim FeedsUi is present, the form will be installed in the footer of the application -->
20
+ <% unless defined?(Decidim::FeedsUi) %>
21
+ <%= append_javascript_pack_tag "decidim_feeds" %>
22
+ <% end %>
23
+ </div>
24
+ </main>