Skip to content

Improve meeting invitations#3632

Merged
mrcasals merged 14 commits intomasterfrom
feature/improve_meeting_invitations
Jul 9, 2018
Merged

Improve meeting invitations#3632
mrcasals merged 14 commits intomasterfrom
feature/improve_meeting_invitations

Conversation

@rbngzlv
Copy link
Copy Markdown
Contributor

@rbngzlv rbngzlv commented Jun 11, 2018

🎩 What? Why?

Allow users to accept or reject invitations to meetings, and allow admins to see their status.

📌 Related Issues

📋 Subtasks

  • Add CHANGELOG entry
  • Add tests
  • Add feature to admin panel
  • Accept/Reject invite

📷 Screenshots

screencapture-decidim-localhost-admin-assemblies-enim-autem-components-20-manage-meetings-6-registrations-invites-2018-06-11-11_15_16

@rbngzlv rbngzlv self-assigned this Jun 11, 2018
@rbngzlv
Copy link
Copy Markdown
Contributor Author

rbngzlv commented Jun 11, 2018

Hi, I have doubts about the implementation of the part related to rejecting an invitation. Let's me explain the two possible cases:

1. An administrator invites an already registered user.

In this case we will always have the current_user, so no problem at all.

2. An administrator invites a non existing user.

In this case, the user is invited to sign up to the platform before accept the meeting invitation. So:

  • If the user accepts and completes the sign up form, it is redirected to the "accept invitation" URL (as it is doing now).

  • If the user wants to refuse the invitation, we need to "reject the invitation" but don't touch the invitation to sign up, because maybe the user has also been invited to another meeting or by a friend, right? And also, we will need a token to identify the meeting invitation that is being refused, because we will not have the current_user.

/cc @decidim/product @decidim/lot-core

@josepjaume
Copy link
Copy Markdown
Contributor

Hi @rbngzlv - @mrcasals has recently been working on invitations so maybe he can provide some feedback.

@mrcasals
Copy link
Copy Markdown
Contributor

I don't have much insight, I delegates the logic to the InviteUser command, which handled my use cases.

If the user wants to refuse the invitation, we need to "reject the invitation" but don't touch the invitation to sign up, because maybe the user has also been invited to another meeting or by a friend, right? And also, we will need a token to identify the meeting invitation that is being refused, because we will not have the current_user.

We could make a list of invitations, so after a sign up we redirect the user to this list (if there's any invitations, of course). From there, the user can accept or reject those invitations (one button for each action). This would work for already existing users too. This way we don't need to send tokens through the invitation email.

Does this sound good to you @rbngzlv? Would this fix your problem? If this works for you please ensure @decidim/product is OK with this 😄

@rbngzlv
Copy link
Copy Markdown
Contributor Author

rbngzlv commented Jun 11, 2018

@mrcasals the idea of a central place to manage the invitations sounds good to me, but I think that it is out of the scope of this PR and also doesn't solve the "problem" with the unregistered users refusing invitations, because, an unregistered user will not be able to access that page.

@mrcasals
Copy link
Copy Markdown
Contributor

@rbngzlv when we invite a user to the platform we create the User in the DB, but we differentiate those users that have accepted the invitation from those that haven't. We could create MeetingInvitation model related to a user and a meeting. If the user never accepts the invitation to the platform, we'll have to leave the meeting invitation row around. We can make it expire though, for example:

  • if you haven't accepted a meeting invitation in 1 month, then it is deleted
  • if the meeting starts, all invitations to that meeting are deleted

the idea of a central place to manage the invitations sounds good to me, but I think that it is out of the scope of this PR

I don't think that's out of the scope of the PR, but I'll leave that to @decidim/product. A list of meeting invitations is the best I can come up with, if you have another layout/workflow in mind then go ahead 😄

@rbngzlv rbngzlv force-pushed the feature/improve_meeting_invitations branch from 146888f to 8cebc8d Compare June 14, 2018 15:34
@rbngzlv rbngzlv force-pushed the feature/improve_meeting_invitations branch from 8cebc8d to 0a693d9 Compare June 14, 2018 21:22
@ghost ghost added the status: WIP label Jun 22, 2018
@isaacmg410
Copy link
Copy Markdown
Contributor

@rbngzlv @decidim/lot-core ready to check, no?

@ghost ghost added the status: WIP label Jul 1, 2018
@mrcasals
Copy link
Copy Markdown
Contributor

mrcasals commented Jul 3, 2018

@isaacmg410 you'll need to rebase/update your branch with master so that tests can run!

@isaacmg410
Copy link
Copy Markdown
Contributor

@rbngzlv check @mrcasals comment

@rbngzlv
Copy link
Copy Markdown
Contributor Author

rbngzlv commented Jul 3, 2018

@mrcasals master merged.

@ghost ghost added the status: WIP label Jul 5, 2018
@rbngzlv
Copy link
Copy Markdown
Contributor Author

rbngzlv commented Jul 5, 2018

Hi @decidim/lot-core, it is the fifth time that we merge master to resolve conflicts, can you review this PR please?

/cc @decidim/lot-mods

@arnaumonty
Copy link
Copy Markdown
Member

@decidim/lot-core @mrcasals can you review this, please?

mrcasals
mrcasals previously approved these changes Jul 9, 2018
<%= t("decidim.meetings.admin.invite_join_meeting_mailer.invite.invited_you_to_join_a_meeting", invited_by: @resource.invited_by.name, application: @resource.organization.name) %>
</p>

<p><%= link_to t("devise.mailer.invitation_instructions.decline"), accept_invitation_url(@resource, invitation_token: @token, invite_redirect: Decidim::EngineRouter.main_proxy(@opts[:meeting].component).decline_invitation_meeting_registration_path(meeting_id: @opts[:meeting], participatory_space_id: @opts[:meeting].component.participatory_space), host: @resource.organization.host) %></p>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does Decidim::EngineRouter.main_proxy(@opts[:meeting].component) do? Have you tried with decidim_meetings.decline_invitation_meeting_registration_path?

Copy link
Copy Markdown
Contributor Author

@rbngzlv rbngzlv Jul 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that we can't access to decicim_meetings because this mailer is executed inside devise.

<%= t("decidim.meetings.admin.invite_join_meeting_mailer.invite.invited_you_to_join_a_meeting", invited_by: @resource.invited_by.name, application: @resource.organization.name) %>

<%= t("devise.mailer.invitation_instructions.decline") %>:
<% accept_invitation_url(@resource, invitation_token: @token, invite_redirect: Decidim::EngineRouter.main_proxy(@opts[:meeting].component).decline_invitation_meeting_registration_path(meeting_id: @opts[:meeting], participatory_space_id: @opts[:meeting].component.participatory_space), host: @resource.organization.host) %>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same

Copy link
Copy Markdown
Contributor Author

@rbngzlv rbngzlv Jul 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that we can't access to decicim_mettings because this mailer is executed inside devise.


it "has an association with one agenda" do
subject.agenda = build(:agenda)
subject.agenda = build_stubbed(:agenda)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I didn't know about this build_stubbed method! 👏

@ghost ghost assigned mrcasals Jul 9, 2018
@ghost ghost added the status: WIP label Jul 9, 2018
@mrcasals mrcasals merged commit eca456a into master Jul 9, 2018
@mrcasals mrcasals deleted the feature/improve_meeting_invitations branch July 9, 2018 09:56
@ghost ghost removed the status: WIP label Jul 9, 2018
@mrcasals
Copy link
Copy Markdown
Contributor

mrcasals commented Jul 9, 2018

Code looks good, build was green. Conflicts were only on the CHANGELOG file.

@rbngzlv sorry for the delay reviewing this! Please, if this happens again, ping me privately on Gitter and I'll check it ASAP. GitHub notifications are far from great and it's not the first time some important things slip my filters 😞

Also, even though the PR is merged, can you check this comment? #3632

Thanks!

end

def can_decline_invitation?
meeting.registrations_enabled? && invitation.present?
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What happens if the registrations are disabled after I get the invite? Does it appear as pending?

Copy link
Copy Markdown
Contributor Author

@rbngzlv rbngzlv Jul 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it appears as pending. If the user don't respond the invitation before the registrations are closed, he can't either accept it or reject it, her time to interact is over. I think that for admin is important to know that the user doesn't respond in time.

#
class InvitesController < Admin::ApplicationController
def index
enforce_permission_to :read_invites, :meeting, meeting: meeting
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How come we have a single meeting if we are at the index?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This action is listing the invites for a single meeting. Is a screen in the admin panel.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, it's listing invites, not meetings. Sorry, my bad 🤦‍♂️

Decidim::Meetings::AdminLog::InvitePresenter
end

def self.user_collection(user)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is this used?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is needed for the data portability export.

<% end %>
</tbody>
</table>
<%= paginate @invites, theme: "decidim" %>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you use decidim_paginate?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can't localize an admin view using decidim_paginate, I need to include the Decidim::PaginateHelper in Decidim::Admin::ApplicationHelper, is this helper new? Do you want this?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I thought we were using it everywhere, don't worry then.

def filter_by_search(invites)
return invites if @query.blank?
invites.joins(:user).where(
User.arel_table[:name].lower.matches("%#{@query}%").or(User.arel_table[:email].lower.matches("%#{@query}%"))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should check that the users are from the same organization

Copy link
Copy Markdown
Contributor Author

@rbngzlv rbngzlv Jul 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about this, the query is loading only the users related to the invites being filtered, right?

SELECT  "decidim_meetings_invites".*
FROM "decidim_meetings_invites"
INNER JOIN "decidim_users" ON "decidim_users"."id" = "decidim_meetings_invites"."decidim_user_id"
WHERE "decidim_meetings_invites"."decidim_meeting_id" = $1
AND (LOWER("decidim_users"."name") ILIKE '%ab%' OR LOWER("decidim_users"."email") ILIKE '%ab%')
LIMIT $2 OFFSET $3

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, you're right, no need for that!

@oriolgual
Copy link
Copy Markdown
Contributor

It was merged while I was reviewing 😞

@rbngzlv please create a new PR with the fixes.

@mrcasals
Copy link
Copy Markdown
Contributor

mrcasals commented Jul 9, 2018

Whoops, sorry :(

@rbngzlv
Copy link
Copy Markdown
Contributor Author

rbngzlv commented Jul 9, 2018

Thank you both for the review. I'll check all comments, discuss here if needed, and create a new PR, don't worry.

@rbngzlv
Copy link
Copy Markdown
Contributor Author

rbngzlv commented Jul 9, 2018

Hi @oriolgual and @mrcasals can you check my comments, please?

@oriolgual
Copy link
Copy Markdown
Contributor

Done @rbngzlv

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants