decidim-posts 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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>