FEATURE: allows to invite people to public events

This commit is contained in:
jjaffeux 2020-03-26 16:38:25 +01:00
parent fbd1dbcccd
commit 36d39f085d
10 changed files with 122 additions and 17 deletions

View File

@ -33,6 +33,23 @@ module DiscourseCalendar
scope: guardian).as_json
end
def invite
post_event = PostEvent.find(params[:id])
guardian.ensure_can_act_on_post_event!(post_event)
invites = Array(params.permit(invites: [])['invites'])
users = User.where(
id: GroupUser.where(
group_id: Group.where(name: invites).select(:id)
).select(:user_id)
).or(User.where(username: invites))
users.each do |user|
post_event.create_notification!(user, post_event.post)
end
render json: success_json
end
def show
post_event = DiscourseCalendar::PostEvent.find(params[:id])
guardian.ensure_can_see!(post_event.post)

View File

@ -46,20 +46,24 @@ module DiscourseCalendar
def notify_invitees!
self.invitees.where(notified: false).each do |invitee|
invitee.user.notifications.create!(
notification_type: Notification.types[:custom],
topic_id: self.post.topic_id,
post_number: self.post.post_number,
data: {
topic_title: self.post.topic.title,
display_username: self.post.user.username,
message: 'discourse_calendar.invite_user_notification'
}.to_json
)
create_notification!(invitee.user, self.post)
invitee.update!(notified: true)
end
end
def create_notification!(user, post)
user.notifications.create!(
notification_type: Notification.types[:custom],
topic_id: post.topic_id,
post_number: post.post_number,
data: {
topic_title: post.topic.title,
display_username: post.user.username,
message: 'discourse_calendar.invite_user_notification'
}.to_json
)
end
def self.statuses
@statuses ||= Enum.new(standalone: 0, public: 1, private: 2)
end

View File

@ -0,0 +1,27 @@
import ModalFunctionality from "discourse/mixins/modal-functionality";
import Controller from "@ember/controller";
import { action } from "@ember/object";
import { extractError } from "discourse/lib/ajax-error";
import { ajax } from "discourse/lib/ajax";
export default Controller.extend(ModalFunctionality, {
invitedNames: null,
@action
setInvitedNames(_, invitedNames) {
this.set("invitedNames", invitedNames);
},
@action
invite() {
return ajax(
`/discourse-calendar/post-events/${this.model.id}/invite.json`,
{
data: { invites: this.invitedNames || [] },
type: "POST"
}
)
.then(() => this.send("closeModal"))
.catch(e => this.flash(extractError(e), "error"));
}
});

View File

@ -1,7 +1,4 @@
import RestModel from "discourse/models/rest";
// import { ajax } from "discourse/lib/ajax";
// const BASE_URL = "/discourse-calendar/post-events";
const ATTRIBUTES = {
id: {},

View File

@ -1,8 +1,10 @@
{{#if enabled}}
<div class="event-field {{class}}">
<div class="event-field-label">
<span class="label">{{i18n label}}</span>
</div>
{{#if label}}
<div class="event-field-label">
<span class="label">{{i18n label}}</span>
</div>
{{/if}}
<div class="event-field-control">
{{yield}}
</div>

View File

@ -17,6 +17,7 @@
to=endsAt
onChange=(action "onChangeDates")
}}
{{#event-field label="event.ui_builder.status.label"}}
<label class="radio-label">
{{radio-button

View File

@ -0,0 +1,29 @@
{{#d-modal-body
title="event.invite_user_or_group.title"
class="invite-user-or-group"
}}
{{#event-field}}
{{user-selector
single=false
onChangeCallback=(action "setInvitedNames")
fullWidthWrap=true
allowAny=false
includeMessageableGroups=true
placeholderKey="composer.users_placeholder"
tabindex="1"
usernames=invitedNames
hasGroups=true
autocomplete="discourse"
excludeCurrentUser=true
}}
{{/event-field}}
{{/d-modal-body}}
<div class="modal-footer">
{{d-button
type="button"
class="btn-primary"
label="event.invite_user_or_group.invite"
action=(action "invite")
}}
</div>

View File

@ -21,6 +21,14 @@ export default createWidget("post-event", {
}
},
inviteUserOrGroup(postId) {
this.store.find("post-event", postId).then(postEvent => {
showModal("invite-user-or-group", {
model: postEvent
});
});
},
showAllInvitees(postId) {
this.store.find("post-event", postId).then(postEvent => {
showModal("post-event-invitees", {
@ -98,7 +106,8 @@ export default createWidget("post-event", {
startsAtDay: moment(postEvent.starts_at).format("D"),
postEventName: postEvent.name || postEvent.post.topic.title,
statusClass: `status ${postEvent.status}`,
statusIcon: iconNode(statusIcon)
statusIcon: iconNode(statusIcon),
isPublicEvent: postEvent.status === "public"
};
},
@ -178,6 +187,20 @@ export default createWidget("post-event", {
action="sendPMToCreator"
)
}}
{{#if state.postEvent.can_act_on_post_event}}
{{#if transformed.isPublicEvent}}
{{attach
widget="button"
attrs=(hash
className="btn-small"
icon="user-plus"
label="event.post_ui.invite"
action="inviteUserOrGroup"
actionParam=state.postEvent.id
)
}}
{{/if}}
{{/if}}
</footer>
{{/if}}
`

View File

@ -31,6 +31,7 @@ en:
description: "A private event can only be joined by invited users."
post_ui:
show_all: show all
invite: invite
add_to_calendar: add to calendar
send_pm_to_creator: contact
post-event-invitees-modal:
@ -52,6 +53,9 @@ en:
label: Status
display_invitees:
label: Display invited users
invite_user_or_group:
title: Invite user(s) or group(s)
invite: Invite
upcoming_events:
title: Upcoming events
group_timezones:

View File

@ -246,6 +246,7 @@ after_initialize do
get '/discourse-calendar/post-events' => 'post_events#index'
post '/discourse-calendar/post-events' => 'post_events#create'
put '/discourse-calendar/post-events/:id' => 'post_events#update'
post '/discourse-calendar/post-events/:id/invite' => 'post_events#invite'
put '/discourse-calendar/invitees/:id' => 'invitees#update'
post '/discourse-calendar/invitees' => 'invitees#create'
get '/discourse-calendar/invitees' => 'invitees#index'