decidim 0.0.4 → 0.0.5
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of decidim might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.eslintrc.json +2 -5
- data/.mention-bot +2 -1
- data/.yardopts +8 -0
- data/Gemfile.lock +64 -62
- data/README.md +11 -9
- data/decidim-admin/app/assets/javascripts/decidim/admin/sort_steps.js.es6 +3 -3
- data/decidim-admin/app/assets/stylesheets/decidim/admin/_email_preview.scss +5 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/application.scss +1 -0
- data/decidim-admin/app/commands/decidim/admin/create_newsletter.rb +30 -0
- data/decidim-admin/app/commands/decidim/admin/deliver_newsletter.rb +29 -0
- data/decidim-admin/app/commands/decidim/admin/destroy_participatory_process_step.rb +9 -0
- data/decidim-admin/app/commands/decidim/admin/update_newsletter.rb +33 -0
- data/decidim-admin/app/constraints/decidim/admin/organization_dashboard_constraint.rb +1 -1
- data/decidim-admin/app/controllers/decidim/admin/features_controller.rb +2 -2
- data/decidim-admin/app/controllers/decidim/admin/newsletters_controller.rb +115 -0
- data/decidim-admin/app/controllers/decidim/admin/participatory_processes_controller.rb +4 -4
- data/decidim-admin/app/forms/decidim/admin/newsletter_form.rb +15 -0
- data/decidim-admin/app/jobs/decidim/admin/newsletter_delivery_job.rb +18 -0
- data/decidim-admin/app/jobs/decidim/admin/newsletter_job.rb +32 -0
- data/decidim-admin/app/models/decidim/admin/abilities/admin_user.rb +4 -0
- data/decidim-admin/app/models/decidim/admin/abilities/base.rb +4 -0
- data/decidim-admin/app/models/decidim/admin/abilities/collaborator_user.rb +19 -0
- data/decidim-admin/app/models/decidim/admin/abilities/participatory_process_admin.rb +1 -1
- data/decidim-admin/app/queries/decidim/admin/manageable_participatory_processes_for_user.rb +1 -1
- data/decidim-admin/app/views/decidim/admin/newsletters/_form.html.erb +5 -0
- data/decidim-admin/app/views/decidim/admin/newsletters/edit.html.erb +11 -0
- data/decidim-admin/app/views/decidim/admin/newsletters/index.html.erb +47 -0
- data/decidim-admin/app/views/decidim/admin/newsletters/new.html.erb +11 -0
- data/decidim-admin/app/views/decidim/admin/newsletters/show.html.erb +14 -0
- data/decidim-admin/app/views/decidim/admin/participatory_process_steps/_form.html.erb +1 -1
- data/decidim-admin/app/views/decidim/admin/participatory_processes/_form.html.erb +1 -1
- data/decidim-admin/app/views/decidim/admin/static_pages/_form.html.erb +1 -1
- data/decidim-admin/app/views/layouts/decidim/admin/_sidebar.html.erb +1 -0
- data/decidim-admin/config/locales/ca.yml +40 -0
- data/decidim-admin/config/locales/en.yml +40 -0
- data/decidim-admin/config/locales/es.yml +40 -0
- data/decidim-admin/config/routes.rb +7 -0
- data/decidim-admin/decidim-admin.gemspec +0 -1
- data/decidim-admin/lib/decidim/admin/engine.rb +1 -0
- data/decidim-admin/lib/decidim/admin/features/base_controller.rb +5 -1
- data/decidim-admin/spec/commands/create_newsletter_spec.rb +62 -0
- data/decidim-admin/spec/commands/deliver_newsletter_spec.rb +45 -0
- data/decidim-admin/spec/commands/destroy_participatory_process_step_spec.rb +12 -0
- data/decidim-admin/spec/commands/update_newsletter_spec.rb +64 -0
- data/decidim-admin/spec/features/admin_manages_newsletters_spec.rb +147 -0
- data/decidim-admin/spec/features/admin_manages_participatory_processes_spec.rb +1 -5
- data/decidim-admin/spec/features/static_pages_spec.rb +16 -0
- data/decidim-admin/spec/forms/newsletter_form_spec.rb +47 -0
- data/decidim-admin/spec/jobs/newsletter_delivery_job_spec.rb +25 -0
- data/decidim-admin/spec/jobs/newsletter_job_spec.rb +29 -0
- data/decidim-admin/spec/models/abilities/collaborator_user_spec.rb +66 -0
- data/decidim-admin/spec/organization_dashboard_constraint_spec.rb +55 -0
- data/decidim-admin/spec/queries/manageable_participatory_processes_for_user_spec.rb +8 -0
- data/decidim-admin/spec/shared/manage_processes_examples.rb +1 -5
- data/decidim-api/lib/decidim/api.rb +2 -7
- data/decidim-api/lib/decidim/api/{types/mutation.rb → mutation_type.rb} +0 -0
- data/decidim-api/lib/decidim/api/{types/query.rb → query_type.rb} +0 -0
- data/decidim-budgets/app/assets/javascripts/decidim/budgets/projects.js.es6 +4 -4
- data/decidim-budgets/app/commands/decidim/budgets/add_line_item.rb +4 -2
- data/decidim-budgets/app/commands/decidim/budgets/checkout.rb +7 -3
- data/decidim-budgets/app/models/decidim/budgets/order.rb +16 -1
- data/decidim-budgets/app/models/decidim/budgets/project.rb +16 -0
- data/decidim-budgets/app/views/decidim/budgets/line_items/update_budget.js.erb +7 -7
- data/decidim-budgets/app/views/decidim/budgets/projects/_budget_confirm.html.erb +27 -25
- data/decidim-budgets/app/views/decidim/budgets/projects/_budget_summary.html.erb +4 -13
- data/decidim-budgets/app/views/decidim/budgets/projects/_order_progress.html.erb +23 -21
- data/decidim-budgets/app/views/decidim/budgets/projects/_order_selected_projects.html.erb +25 -23
- data/decidim-budgets/app/views/decidim/budgets/projects/_order_total_budget.html.erb +3 -1
- data/decidim-budgets/app/views/decidim/budgets/projects/_project.html.erb +32 -30
- data/decidim-budgets/app/views/decidim/budgets/projects/_projects.html.erb +1 -3
- data/decidim-budgets/app/views/decidim/budgets/projects/index.html.erb +0 -4
- data/decidim-budgets/app/views/decidim/budgets/projects/show.html.erb +5 -6
- data/decidim-budgets/config/i18n-tasks.yml +1 -0
- data/decidim-budgets/config/locales/ca.yml +7 -2
- data/decidim-budgets/config/locales/en.yml +17 -6
- data/decidim-budgets/config/locales/es.yml +7 -2
- data/decidim-budgets/lib/decidim/budgets/feature.rb +2 -2
- data/decidim-budgets/spec/commands/add_line_item_spec.rb +16 -3
- data/decidim-budgets/spec/commands/cancel_order_spec.rb +7 -1
- data/decidim-budgets/spec/commands/checkout_spec.rb +9 -2
- data/decidim-budgets/spec/commands/remove_line_item_spec.rb +16 -5
- data/decidim-budgets/spec/features/orders_spec.rb +8 -2
- data/decidim-budgets/spec/models/order_spec.rb +31 -2
- data/decidim-budgets/spec/shared/admin_shared_context.rb +1 -1
- data/decidim-comments/README.md +1 -1
- data/decidim-comments/app/assets/javascripts/decidim/comments/bundle.js +0 -0
- data/decidim-comments/app/frontend/comments/add_comment_form.component.jsx +156 -93
- data/decidim-comments/app/frontend/comments/add_comment_form.component.test.jsx +36 -23
- data/decidim-comments/app/frontend/comments/add_comment_form.mutation.graphql +5 -3
- data/decidim-comments/app/frontend/comments/add_comment_form_commentable.fragment.graphql +4 -0
- data/decidim-comments/app/frontend/comments/add_comment_form_session.fragment.graphql +6 -0
- data/decidim-comments/app/frontend/comments/comment.component.jsx +11 -13
- data/decidim-comments/app/frontend/comments/comment.component.test.jsx +22 -21
- data/decidim-comments/app/frontend/comments/comment.fragment.graphql +4 -4
- data/decidim-comments/app/frontend/comments/comment_data.fragment.graphql +4 -3
- data/decidim-comments/app/frontend/comments/comment_order_selector.component.jsx +1 -1
- data/decidim-comments/app/frontend/comments/comment_thread.component.jsx +3 -3
- data/decidim-comments/app/frontend/comments/comment_thread.component.test.jsx +3 -3
- data/decidim-comments/app/frontend/comments/comment_thread.fragment.graphql +1 -1
- data/decidim-comments/app/frontend/comments/comments.component.jsx +47 -39
- data/decidim-comments/app/frontend/comments/comments.component.test.jsx +51 -38
- data/decidim-comments/app/frontend/comments/comments.query.graphql +10 -4
- data/decidim-comments/app/frontend/comments/down_vote_button.component.jsx +6 -3
- data/decidim-comments/app/frontend/comments/up_vote_button.component.jsx +7 -4
- data/decidim-comments/app/frontend/support/generate_comments_data.js +4 -4
- data/decidim-comments/app/models/decidim/comments/comment.rb +7 -9
- data/decidim-comments/app/queries/decidim/comments/{comments_with_replies.rb → sorted_comments.rb} +3 -8
- data/decidim-comments/app/types/decidim/comments/commentable_interface.rb +44 -0
- data/decidim-comments/app/types/decidim/comments/commentable_mutation_type.rb +29 -0
- data/decidim-comments/app/types/decidim/comments/commentable_type.rb +14 -0
- data/decidim-comments/config/locales/ca.yml +3 -1
- data/decidim-comments/config/locales/en.yml +5 -2
- data/decidim-comments/config/locales/es.yml +3 -1
- data/decidim-comments/lib/decidim/comments.rb +4 -0
- data/decidim-comments/{app/types/decidim/comments → lib/decidim/comments/api}/add_comment_type.rb +0 -0
- data/decidim-comments/{app/types/decidim/comments → lib/decidim/comments/api}/comment_mutation_type.rb +0 -0
- data/decidim-comments/{app/types/decidim/comments → lib/decidim/comments/api}/comment_type.rb +11 -17
- data/decidim-comments/lib/decidim/comments/commentable.rb +45 -0
- data/decidim-comments/lib/decidim/comments/comments_helper.rb +15 -10
- data/decidim-comments/lib/decidim/comments/mutation_extensions.rb +8 -16
- data/decidim-comments/lib/decidim/comments/query_extensions.rb +5 -8
- data/decidim-comments/lib/decidim/comments/test/factories.rb +3 -3
- data/decidim-comments/spec/commands/vote_comment_spec.rb +3 -1
- data/decidim-comments/spec/features/comments_spec.rb +28 -14
- data/decidim-comments/spec/features/notifications_spec.rb +1 -1
- data/decidim-comments/spec/helpers/comments_helper_spec.rb +4 -27
- data/decidim-comments/spec/models/comment_spec.rb +7 -11
- data/decidim-comments/spec/models/comment_vote_spec.rb +3 -1
- data/decidim-comments/spec/models/seed_spec.rb +3 -4
- data/decidim-comments/spec/queries/{comments_with_replies_spec.rb → sorted_comments_spec.rb} +12 -29
- data/decidim-comments/spec/types/comment_type_spec.rb +23 -17
- data/decidim-comments/spec/types/commentable_mutation_type_spec.rb +34 -0
- data/decidim-comments/spec/types/commentable_type_spec.rb +48 -0
- data/decidim-comments/spec/types/mutation_type_spec.rb +5 -22
- data/decidim-comments/spec/types/query_type_spec.rb +0 -24
- data/decidim-dev/config/i18n-tasks.yml +4 -0
- data/decidim-dev/decidim-dev.gemspec +1 -1
- data/decidim-dev/lib/decidim/dev/test/rspec_support/action_mailer.rb +10 -4
- data/decidim-dev/lib/decidim/dev/test/rspec_support/feature.rb +6 -5
- data/decidim-dev/lib/decidim/dev/test/rspec_support/i18n.rb +0 -1
- data/decidim-meetings/app/assets/javascripts/decidim/meetings/map.js.es6.erb +8 -3
- data/decidim-meetings/app/assets/stylesheets/decidim/meetings/map.css +3 -1
- data/decidim-meetings/app/controllers/decidim/meetings/meetings_controller.rb +2 -2
- data/decidim-meetings/app/forms/decidim/meetings/admin/close_meeting_form.rb +2 -1
- data/decidim-meetings/app/helpers/decidim/meetings/map_helper.rb +1 -0
- data/decidim-meetings/app/services/decidim/meetings/meeting_search.rb +7 -3
- data/decidim-meetings/app/views/decidim/meetings/meetings/_datetime.html.erb +1 -1
- data/decidim-meetings/app/views/decidim/meetings/meetings/_filters.html.erb +5 -5
- data/decidim-meetings/app/views/decidim/meetings/meetings/_linked_meetings.html.erb +1 -1
- data/decidim-meetings/app/views/decidim/meetings/meetings/index.html.erb +1 -5
- data/decidim-meetings/app/views/decidim/meetings/meetings/show.html.erb +16 -9
- data/decidim-meetings/config/locales/ca.yml +2 -3
- data/decidim-meetings/config/locales/en.yml +2 -3
- data/decidim-meetings/config/locales/es.yml +2 -3
- data/decidim-meetings/spec/features/explore_meetings_spec.rb +75 -24
- data/decidim-meetings/spec/forms/close_meeting_form_spec.rb +1 -1
- data/decidim-meetings/spec/services/meeting_search_spec.rb +15 -12
- data/decidim-meetings/vendor/assets/javascripts/leaflet.markercluster.js +7 -0
- data/decidim-meetings/vendor/assets/stylesheets/MarkerCluster.Default.css +60 -0
- data/decidim-meetings/vendor/assets/stylesheets/MarkerCluster.css +14 -0
- data/decidim-pages/app/models/decidim/pages/page.rb +22 -0
- data/decidim-pages/app/views/decidim/pages/application/show.html.erb +2 -6
- data/decidim-pages/config/locales/ca.yml +2 -2
- data/decidim-pages/config/locales/en.yml +2 -2
- data/decidim-pages/config/locales/es.yml +2 -2
- data/decidim-pages/lib/decidim/pages/feature.rb +2 -2
- data/decidim-pages/spec/features/page_show_spec.rb +0 -33
- data/decidim-proposals/app/controllers/decidim/proposals/admin/proposal_answers_controller.rb +2 -0
- data/decidim-proposals/app/controllers/decidim/proposals/admin/proposals_controller.rb +2 -0
- data/decidim-proposals/app/models/decidim/proposals/abilities/admin_user.rb +45 -0
- data/decidim-proposals/app/models/decidim/proposals/abilities/process_admin_user.rb +57 -0
- data/decidim-proposals/app/models/decidim/proposals/proposal.rb +21 -0
- data/decidim-proposals/app/views/decidim/proposals/admin/proposals/_form.html.erb +1 -1
- data/decidim-proposals/app/views/decidim/proposals/admin/proposals/index.html.erb +16 -10
- data/decidim-proposals/app/views/decidim/proposals/proposal_votes/update_buttons_and_counters.js.erb +4 -4
- data/decidim-proposals/app/views/decidim/proposals/proposals/_filters.html.erb +7 -3
- data/decidim-proposals/app/views/decidim/proposals/proposals/_proposal.html.erb +2 -6
- data/decidim-proposals/app/views/decidim/proposals/proposals/_remaining_votes_count.html.erb +3 -1
- data/decidim-proposals/app/views/decidim/proposals/proposals/_tags.html.erb +1 -1
- data/decidim-proposals/app/views/decidim/proposals/proposals/_vote_button.html.erb +23 -21
- data/decidim-proposals/app/views/decidim/proposals/proposals/_votes_count.html.erb +9 -6
- data/decidim-proposals/app/views/decidim/proposals/proposals/_votes_limit.html.erb +1 -3
- data/decidim-proposals/app/views/decidim/proposals/proposals/index.html.erb +0 -4
- data/decidim-proposals/app/views/decidim/proposals/proposals/new.html.erb +1 -1
- data/decidim-proposals/app/views/decidim/proposals/proposals/show.html.erb +2 -6
- data/decidim-proposals/config/locales/ca.yml +8 -1
- data/decidim-proposals/config/locales/en.yml +8 -1
- data/decidim-proposals/config/locales/es.yml +8 -1
- data/decidim-proposals/lib/decidim/proposals/admin_engine.rb +7 -0
- data/decidim-proposals/lib/decidim/proposals/feature.rb +6 -2
- data/decidim-proposals/spec/features/proposals_spec.rb +226 -40
- data/decidim-proposals/spec/models/decidim/proposals/abilities/admin_user_spec.rb +62 -0
- data/decidim-proposals/spec/models/decidim/proposals/abilities/process_admin_user_spec.rb +63 -0
- data/decidim-proposals/spec/shared/manage_proposals_examples.rb +161 -50
- data/decidim-results/app/models/decidim/results/result.rb +21 -0
- data/decidim-results/app/views/decidim/results/results/index.html.erb +0 -4
- data/decidim-results/app/views/decidim/results/results/show.html.erb +2 -8
- data/decidim-results/config/i18n-tasks.yml +1 -0
- data/decidim-results/config/locales/ca.yml +5 -2
- data/decidim-results/config/locales/en.yml +5 -2
- data/decidim-results/config/locales/es.yml +5 -2
- data/decidim-results/lib/decidim/results/feature.rb +2 -2
- data/decidim-results/spec/services/result_stats_calculator_spec.rb +2 -2
- data/decidim-results/spec/shared/admin_shared_context.rb +1 -1
- data/decidim-system/config/i18n-tasks.yml +1 -1
- data/package.json +50 -51
- data/yarn.lock +198 -151
- metadata +69 -36
- data/decidim-admin/spec/features/admin_access_control.rb +0 -52
- data/decidim-api/lib/decidim/api/types/author_interface.rb +0 -13
- data/decidim-api/lib/decidim/api/types/localized_string.rb +0 -13
- data/decidim-api/lib/decidim/api/types/translated_field.rb +0 -44
- data/decidim-api/spec/types/localized_string_type_spec.rb +0 -31
- data/decidim-api/spec/types/translated_field_type_spec.rb +0 -69
- data/decidim-comments/app/frontend/comments/add_comment_form.fragment.graphql +0 -6
@@ -21,7 +21,7 @@ import commentsQuery from './comments.query.graphql';
|
|
21
21
|
*/
|
22
22
|
export class Comments extends Component {
|
23
23
|
render() {
|
24
|
-
const { comments, reorderComments, orderBy, loading } = this.props;
|
24
|
+
const { commentable: { comments }, reorderComments, orderBy, loading } = this.props;
|
25
25
|
let commentClasses = "comments";
|
26
26
|
let commentHeader = I18n.t("components.comments.title", { count: comments.length });
|
27
27
|
|
@@ -42,6 +42,7 @@ export class Comments extends Component {
|
|
42
42
|
defaultOrderBy={orderBy}
|
43
43
|
/>
|
44
44
|
</div>
|
45
|
+
{this._renderBlockedCommentsWarning()}
|
45
46
|
{this._renderCommentThreads()}
|
46
47
|
{this._renderAddCommentForm()}
|
47
48
|
</section>
|
@@ -49,20 +50,39 @@ export class Comments extends Component {
|
|
49
50
|
);
|
50
51
|
}
|
51
52
|
|
53
|
+
/**
|
54
|
+
* Renders a warning message if the commentable doesn't accept new comments.
|
55
|
+
* @private
|
56
|
+
* @returns {Void|DOMElement} - A warning message or nothing.
|
57
|
+
*/
|
58
|
+
_renderBlockedCommentsWarning() {
|
59
|
+
const { commentable: { acceptsNewComments } } = this.props;
|
60
|
+
|
61
|
+
if (!acceptsNewComments) {
|
62
|
+
return (
|
63
|
+
<div className="callout warning">
|
64
|
+
<p>{ I18n.t("components.comments.blocked_comments_warning") }</p>
|
65
|
+
</div>
|
66
|
+
);
|
67
|
+
}
|
68
|
+
|
69
|
+
return null;
|
70
|
+
}
|
71
|
+
|
52
72
|
/**
|
53
73
|
* Iterates the comment's collection and render a CommentThread for each one
|
54
74
|
* @private
|
55
75
|
* @returns {ReactComponent[]} - A collection of CommentThread components
|
56
76
|
*/
|
57
77
|
_renderCommentThreads() {
|
58
|
-
const {
|
78
|
+
const { session, commentable: { comments, commentsHaveVotes } } = this.props;
|
59
79
|
|
60
80
|
return comments.map((comment) => (
|
61
81
|
<CommentThread
|
62
82
|
key={comment.id}
|
63
83
|
comment={filter(CommentThread.fragments.comment, comment)}
|
64
84
|
session={session}
|
65
|
-
votable={
|
85
|
+
votable={commentsHaveVotes}
|
66
86
|
/>
|
67
87
|
))
|
68
88
|
}
|
@@ -73,15 +93,15 @@ export class Comments extends Component {
|
|
73
93
|
* @returns {Void|ReactComponent} - A AddCommentForm component or nothing
|
74
94
|
*/
|
75
95
|
_renderAddCommentForm() {
|
76
|
-
const { session,
|
96
|
+
const { session, commentable } = this.props;
|
97
|
+
const { acceptsNewComments, commentsHaveAlignment } = commentable;
|
77
98
|
|
78
|
-
if (
|
99
|
+
if (acceptsNewComments) {
|
79
100
|
return (
|
80
101
|
<AddCommentForm
|
81
102
|
session={session}
|
82
|
-
|
83
|
-
|
84
|
-
arguable={arguable}
|
103
|
+
commentable={commentable}
|
104
|
+
arguable={commentsHaveAlignment}
|
85
105
|
/>
|
86
106
|
);
|
87
107
|
}
|
@@ -92,26 +112,27 @@ export class Comments extends Component {
|
|
92
112
|
|
93
113
|
Comments.propTypes = {
|
94
114
|
loading: PropTypes.bool,
|
95
|
-
comments: PropTypes.arrayOf(PropTypes.shape({
|
96
|
-
id: PropTypes.string.isRequired
|
97
|
-
})),
|
98
115
|
session: PropTypes.shape({
|
99
116
|
user: PropTypes.any.isRequired
|
100
117
|
}),
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
118
|
+
commentable: PropTypes.shape({
|
119
|
+
acceptsNewComments: PropTypes.bool,
|
120
|
+
commentsHaveAlignment: PropTypes.bool,
|
121
|
+
commentsHaveVotes: PropTypes.bool,
|
122
|
+
comments: PropTypes.arrayOf(PropTypes.shape({
|
123
|
+
id: PropTypes.string.isRequired
|
124
|
+
}))
|
125
|
+
}),
|
106
126
|
orderBy: PropTypes.string.isRequired,
|
107
127
|
reorderComments: PropTypes.func.isRequired
|
108
128
|
};
|
109
129
|
|
110
130
|
Comments.defaultProps = {
|
111
131
|
loading: false,
|
112
|
-
comments: null,
|
113
132
|
session: null,
|
114
|
-
|
133
|
+
commentable: {
|
134
|
+
comments: []
|
135
|
+
}
|
115
136
|
};
|
116
137
|
|
117
138
|
/**
|
@@ -123,20 +144,18 @@ window.Comments = Comments;
|
|
123
144
|
|
124
145
|
const CommentsWithData = graphql(gql`
|
125
146
|
${commentsQuery}
|
126
|
-
${AddCommentForm.fragments.
|
147
|
+
${AddCommentForm.fragments.session}
|
148
|
+
${AddCommentForm.fragments.commentable}
|
127
149
|
${CommentThread.fragments.comment}
|
128
150
|
`, {
|
129
151
|
options: {
|
130
152
|
pollInterval: 15000
|
131
153
|
},
|
132
|
-
props: ({ ownProps, data: { loading, session,
|
133
|
-
loading
|
134
|
-
comments: comments || [],
|
154
|
+
props: ({ ownProps, data: { loading, session, commentable, refetch }}) => ({
|
155
|
+
loading,
|
135
156
|
session,
|
136
|
-
|
137
|
-
commentableType: ownProps.commentableType,
|
157
|
+
commentable,
|
138
158
|
orderBy: ownProps.orderBy,
|
139
|
-
options: ownProps.options,
|
140
159
|
reorderComments: (orderBy) => {
|
141
160
|
return refetch({
|
142
161
|
orderBy
|
@@ -150,12 +169,11 @@ const CommentsWithData = graphql(gql`
|
|
150
169
|
* connect it with Apollo client and store.
|
151
170
|
* @returns {ReactComponent} - A component wrapped within an Application component
|
152
171
|
*/
|
153
|
-
const CommentsApplication = ({ locale, commentableId, commentableType
|
172
|
+
const CommentsApplication = ({ locale, commentableId, commentableType }) => (
|
154
173
|
<Application locale={locale}>
|
155
174
|
<CommentsWithData
|
156
175
|
commentableId={commentableId}
|
157
176
|
commentableType={commentableType}
|
158
|
-
options={options}
|
159
177
|
orderBy="older"
|
160
178
|
/>
|
161
179
|
</Application>
|
@@ -163,18 +181,8 @@ const CommentsApplication = ({ locale, commentableId, commentableType, options }
|
|
163
181
|
|
164
182
|
CommentsApplication.propTypes = {
|
165
183
|
locale: PropTypes.string.isRequired,
|
166
|
-
commentableId:
|
167
|
-
|
168
|
-
PropTypes.number
|
169
|
-
]),
|
170
|
-
commentableType: PropTypes.string.isRequired,
|
171
|
-
options: PropTypes.shape({
|
172
|
-
arguable: PropTypes.bool
|
173
|
-
}).isRequired
|
174
|
-
};
|
175
|
-
|
176
|
-
CommentsApplication.defaultProps = {
|
177
|
-
commentableId: null
|
184
|
+
commentableId: PropTypes.string.isRequired,
|
185
|
+
commentableType: PropTypes.string.isRequired
|
178
186
|
};
|
179
187
|
|
180
188
|
export default CommentsApplication;
|
@@ -15,10 +15,10 @@ import generateUserData from '../support/generate_user_data';
|
|
15
15
|
import resolveGraphQLQuery from '../support/resolve_graphql_query';
|
16
16
|
|
17
17
|
describe('<Comments />', () => {
|
18
|
-
let
|
18
|
+
let commentable = {};
|
19
19
|
let session = null;
|
20
20
|
const commentableId = "1";
|
21
|
-
const commentableType = "Decidim::
|
21
|
+
const commentableType = "Decidim::DummyResource";
|
22
22
|
const orderBy = "older";
|
23
23
|
const reorderComments = () => {};
|
24
24
|
|
@@ -28,14 +28,20 @@ describe('<Comments />', () => {
|
|
28
28
|
}
|
29
29
|
`;
|
30
30
|
|
31
|
-
const
|
32
|
-
fragment
|
31
|
+
const addCommentFormSessionFragment = gql`
|
32
|
+
fragment AddCommentFormSession on Session {
|
33
33
|
verifiedUserGroups {
|
34
34
|
id
|
35
35
|
}
|
36
36
|
}
|
37
37
|
`;
|
38
38
|
|
39
|
+
const addCommentFormCommentableFragment = gql`
|
40
|
+
fragment AddCommentFormCommentable on Commentable {
|
41
|
+
id
|
42
|
+
}
|
43
|
+
`;
|
44
|
+
|
39
45
|
stubComponent(CommentOrderSelector)
|
40
46
|
|
41
47
|
stubComponent(CommentThread, {
|
@@ -46,7 +52,8 @@ describe('<Comments />', () => {
|
|
46
52
|
|
47
53
|
stubComponent(AddCommentForm, {
|
48
54
|
fragments: {
|
49
|
-
|
55
|
+
session: addCommentFormSessionFragment,
|
56
|
+
commentable: addCommentFormCommentableFragment
|
50
57
|
}
|
51
58
|
});
|
52
59
|
|
@@ -57,7 +64,8 @@ describe('<Comments />', () => {
|
|
57
64
|
const query = gql`
|
58
65
|
${commentsQuery}
|
59
66
|
${commentThreadFragment}
|
60
|
-
${
|
67
|
+
${addCommentFormSessionFragment}
|
68
|
+
${addCommentFormCommentableFragment}
|
61
69
|
`;
|
62
70
|
|
63
71
|
const result = resolveGraphQLQuery(query, {
|
@@ -66,7 +74,12 @@ describe('<Comments />', () => {
|
|
66
74
|
session: {
|
67
75
|
user: userData
|
68
76
|
},
|
69
|
-
|
77
|
+
commentable: {
|
78
|
+
acceptsNewComments: true,
|
79
|
+
commentsHaveAlignment: true,
|
80
|
+
commentsHaveVotes: true,
|
81
|
+
comments: commentsData
|
82
|
+
}
|
70
83
|
},
|
71
84
|
variables: {
|
72
85
|
orderBy,
|
@@ -76,82 +89,82 @@ describe('<Comments />', () => {
|
|
76
89
|
});
|
77
90
|
|
78
91
|
session = result.session;
|
79
|
-
|
92
|
+
commentable = result.commentable;
|
80
93
|
});
|
81
94
|
|
82
|
-
it("
|
83
|
-
const wrapper = shallow(<Comments
|
95
|
+
it("renders loading-comments class and the respective loading text", () => {
|
96
|
+
const wrapper = shallow(<Comments commentable={commentable} session={session} reorderComments={reorderComments} orderBy={orderBy} loading />);
|
84
97
|
expect(wrapper.find('.loading-comments')).to.be.present();
|
85
98
|
expect(wrapper.find('h2')).to.have.text("Loading comments ...");
|
86
99
|
});
|
87
100
|
|
88
|
-
it("
|
89
|
-
const wrapper = shallow(<Comments
|
101
|
+
it("renders a div of id comments", () => {
|
102
|
+
const wrapper = shallow(<Comments commentable={commentable} session={session} reorderComments={reorderComments} orderBy={orderBy} />);
|
90
103
|
expect(wrapper.find('#comments')).to.be.present();
|
91
104
|
});
|
92
105
|
|
93
|
-
describe("
|
106
|
+
describe("renders a CommentThread component for each comment", () => {
|
94
107
|
it("and pass filter comment data as a prop to it", () => {
|
95
|
-
const wrapper = shallow(<Comments
|
96
|
-
expect(wrapper).to.have.exactly(comments.length).descendants(CommentThread);
|
108
|
+
const wrapper = shallow(<Comments commentable={commentable} session={session} reorderComments={reorderComments} orderBy={orderBy} />);
|
109
|
+
expect(wrapper).to.have.exactly(commentable.comments.length).descendants(CommentThread);
|
97
110
|
wrapper.find(CommentThread).forEach((node, idx) => {
|
98
|
-
expect(node).to.have.prop("comment").deep.equal(filter(commentThreadFragment, comments[idx]));
|
111
|
+
expect(node).to.have.prop("comment").deep.equal(filter(commentThreadFragment, commentable.comments[idx]));
|
99
112
|
});
|
100
113
|
});
|
101
114
|
|
102
115
|
it("and pass the session as a prop to it", () => {
|
103
|
-
const wrapper = shallow(<Comments
|
104
|
-
expect(wrapper).to.have.exactly(comments.length).descendants(CommentThread);
|
116
|
+
const wrapper = shallow(<Comments commentable={commentable} session={session} reorderComments={reorderComments} orderBy={orderBy} />);
|
117
|
+
expect(wrapper).to.have.exactly(commentable.comments.length).descendants(CommentThread);
|
105
118
|
wrapper.find(CommentThread).forEach((node) => {
|
106
119
|
expect(node).to.have.prop("session").deep.equal(session);
|
107
120
|
});
|
108
121
|
});
|
109
122
|
|
110
|
-
it("and pass the
|
111
|
-
const wrapper = shallow(<Comments
|
112
|
-
expect(wrapper).to.have.exactly(comments.length).descendants(CommentThread);
|
123
|
+
it("and pass the commentable 'commentsHaveVotes' property as a prop to it", () => {
|
124
|
+
const wrapper = shallow(<Comments commentable={commentable} session={session} reorderComments={reorderComments} orderBy={orderBy} />);
|
125
|
+
expect(wrapper).to.have.exactly(commentable.comments.length).descendants(CommentThread);
|
113
126
|
wrapper.find(CommentThread).forEach((node) => {
|
114
127
|
expect(node).to.have.prop("votable").equal(true);
|
115
128
|
});
|
116
129
|
});
|
117
130
|
});
|
118
131
|
|
119
|
-
it("
|
120
|
-
const wrapper = shallow(<Comments
|
121
|
-
const rex = new RegExp(`${comments.length} comments`);
|
132
|
+
it("renders comments count", () => {
|
133
|
+
const wrapper = shallow(<Comments commentable={commentable} session={session} reorderComments={reorderComments} orderBy={orderBy} />);
|
134
|
+
const rex = new RegExp(`${commentable.comments.length} comments`);
|
122
135
|
expect(wrapper.find('h2.section-heading')).to.have.text().match(rex);
|
123
136
|
});
|
124
137
|
|
125
|
-
it("
|
126
|
-
const wrapper = shallow(<Comments
|
138
|
+
it("renders a AddCommentForm component and pass the commentable 'commentsHaveAlignment' as a prop", () => {
|
139
|
+
const wrapper = shallow(<Comments commentable={commentable} session={session} reorderComments={reorderComments} orderBy={orderBy} />);
|
127
140
|
expect(wrapper).to.have.exactly(1).descendants(AddCommentForm);
|
128
141
|
expect(wrapper.find(AddCommentForm)).to.have.prop('arguable').equal(true);
|
129
142
|
});
|
130
143
|
|
131
|
-
describe("
|
144
|
+
describe("when the commentable cannot accept new comments", () => {
|
132
145
|
beforeEach(() => {
|
133
|
-
|
146
|
+
commentable.acceptsNewComments = false;
|
134
147
|
});
|
135
148
|
|
136
|
-
it("
|
137
|
-
const wrapper = shallow(<Comments
|
149
|
+
it("doesn't render an AddCommentForm component", () => {
|
150
|
+
const wrapper = shallow(<Comments commentable={commentable} session={session} reorderComments={reorderComments} orderBy={orderBy} />);
|
138
151
|
expect(wrapper.find(AddCommentForm)).not.to.be.present();
|
139
152
|
});
|
140
|
-
});
|
141
153
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
154
|
+
it("renders a callout message to inform the user that comments are blocked", () => {
|
155
|
+
const wrapper = shallow(<Comments commentable={commentable} session={session} reorderComments={reorderComments} orderBy={orderBy} />);
|
156
|
+
expect(wrapper.find('.callout.warning')).to.include.text("disabled");
|
157
|
+
});
|
158
|
+
});
|
147
159
|
|
160
|
+
describe("renders a CommentOrderSelector component", () => {
|
148
161
|
it("and pass the reorderComments as a prop to it", () => {
|
149
|
-
const wrapper = shallow(<Comments
|
162
|
+
const wrapper = shallow(<Comments commentable={commentable} session={session} reorderComments={reorderComments} orderBy={orderBy} />);
|
150
163
|
expect(wrapper.find(CommentOrderSelector)).to.have.prop('reorderComments').deep.equal(reorderComments);
|
151
164
|
});
|
152
165
|
|
153
166
|
it("and pass the orderBy as a prop to it", () => {
|
154
|
-
const wrapper = shallow(<Comments
|
167
|
+
const wrapper = shallow(<Comments commentable={commentable} session={session} reorderComments={reorderComments} orderBy={orderBy} />);
|
155
168
|
expect(wrapper.find(CommentOrderSelector)).to.have.prop('defaultOrderBy').equal('older');
|
156
169
|
});
|
157
170
|
});
|
@@ -4,10 +4,16 @@ query GetComments($commentableId: String!, $commentableType: String!, $orderBy:
|
|
4
4
|
name
|
5
5
|
avatarUrl
|
6
6
|
}
|
7
|
-
...
|
7
|
+
...AddCommentFormSession
|
8
8
|
}
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
commentable(id: $commentableId, type: $commentableType) {
|
10
|
+
acceptsNewComments
|
11
|
+
commentsHaveAlignment
|
12
|
+
commentsHaveVotes
|
13
|
+
comments(orderBy: $orderBy) {
|
14
|
+
id
|
15
|
+
...CommentThread
|
16
|
+
}
|
17
|
+
...AddCommentFormCommentable
|
12
18
|
}
|
13
19
|
}
|
@@ -71,20 +71,23 @@ const DownVoteButtonWithMutation = graphql(gql`
|
|
71
71
|
updateQueries: {
|
72
72
|
GetComments: (prev, { mutationResult: { data } }) => {
|
73
73
|
const commentReducer = (comment) => {
|
74
|
-
const replies = comment.
|
74
|
+
const replies = comment.comments || [];
|
75
75
|
|
76
76
|
if (comment.id === ownProps.comment.id) {
|
77
77
|
return data.comment.downVote;
|
78
78
|
}
|
79
79
|
return {
|
80
80
|
...comment,
|
81
|
-
|
81
|
+
comments: replies.map(commentReducer)
|
82
82
|
};
|
83
83
|
};
|
84
84
|
|
85
85
|
return {
|
86
86
|
...prev,
|
87
|
-
|
87
|
+
commentable: {
|
88
|
+
...prev.commentable,
|
89
|
+
comments: prev.commentable.comments.map(commentReducer)
|
90
|
+
}
|
88
91
|
}
|
89
92
|
}
|
90
93
|
}
|
@@ -46,7 +46,7 @@ UpVoteButton.propTypes = {
|
|
46
46
|
|
47
47
|
const UpVoteButtonWithMutation = graphql(gql`
|
48
48
|
${upVoteMutation}
|
49
|
-
${commentFragment}
|
49
|
+
${commentFragment}
|
50
50
|
${commentDataFragment}
|
51
51
|
${upVoteFragment}
|
52
52
|
${downVoteFragment}
|
@@ -71,20 +71,23 @@ const UpVoteButtonWithMutation = graphql(gql`
|
|
71
71
|
updateQueries: {
|
72
72
|
GetComments: (prev, { mutationResult: { data } }) => {
|
73
73
|
const commentReducer = (comment) => {
|
74
|
-
const replies = comment.
|
74
|
+
const replies = comment.comments || [];
|
75
75
|
|
76
76
|
if (comment.id === ownProps.comment.id) {
|
77
77
|
return data.comment.upVote;
|
78
78
|
}
|
79
79
|
return {
|
80
80
|
...comment,
|
81
|
-
|
81
|
+
comments: replies.map(commentReducer)
|
82
82
|
};
|
83
83
|
};
|
84
84
|
|
85
85
|
return {
|
86
86
|
...prev,
|
87
|
-
|
87
|
+
commentable: {
|
88
|
+
...prev.commentable,
|
89
|
+
comments: prev.commentable.comments.map(commentReducer)
|
90
|
+
}
|
88
91
|
}
|
89
92
|
}
|
90
93
|
}
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import { random, name, date, image } from 'faker/locale/en';
|
2
2
|
|
3
|
-
/**
|
3
|
+
/**
|
4
4
|
* Generate random comment data to emulate a database real content
|
5
5
|
* @param {number} num - The number of comments to generate random data
|
6
6
|
* @returns {Object[]} - An array of objects representing comments data
|
@@ -17,9 +17,9 @@ const generateCommentsData = (num = 1) => {
|
|
17
17
|
name: name.findName(),
|
18
18
|
avatarUrl: image.imageUrl()
|
19
19
|
},
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
hasComments: false,
|
21
|
+
comments: [],
|
22
|
+
acceptsNewComments: true,
|
23
23
|
alignment: 0,
|
24
24
|
upVotes: random.number(),
|
25
25
|
upVoted: false,
|