FEATURE: allows to remove invitees from the modal listing them

FEATURE: allows to remove invitees from the modal listing them

diff --git a/app/controllers/discourse_post_event/invitees_controller.rb b/app/controllers/discourse_post_event/invitees_controller.rb
index d4c66ce..cec0e81 100644
--- a/app/controllers/discourse_post_event/invitees_controller.rb
+++ b/app/controllers/discourse_post_event/invitees_controller.rb
@@ -3,7 +3,7 @@
 module DiscoursePostEvent
   class InviteesController < DiscoursePostEventController
     def index
-      event = Event.find(params['event-id'])
+      event = Event.find(params[:post_id])
 
       event_invitees = event.invitees
 
@@ -22,28 +22,37 @@ module DiscoursePostEvent
     end
 
     def update
-      invitee = Invitee.find(params[:id])
+      invitee = Invitee.find_by(id: params[:id], post_id: params[:post_id])
       guardian.ensure_can_act_on_invitee!(invitee)
       invitee.update_attendance!(invitee_params[:status])
       render json: InviteeSerializer.new(invitee)
     end
 
     def create
-      event = Event.find(invitee_params[:post_id])
+      event = Event.find(params[:post_id])
       guardian.ensure_can_see!(event.post)
 
       invitee = Invitee.create_attendance!(
         current_user.id,
-        invitee_params[:post_id],
+        params[:post_id],
         invitee_params[:status]
       )
       render json: InviteeSerializer.new(invitee)
     end
 
+    def destroy
+      event = Event.find_by(id: params[:post_id])
+      invitee = event.invitees.find_by(id: params[:id])
+      guardian.ensure_can_act_on_discourse_post_event!(event)
+      invitee.destroy!
+      event.publish_update!
+      render json: success_json
+    end
+
     private
 
     def invitee_params
-      params.require(:invitee).permit(:status, :post_id)
+      params.require(:invitee).permit(:status)
     end
   end
 end
diff --git a/app/serializers/discourse_post_event/invitee_serializer.rb b/app/serializers/discourse_post_event/invitee_serializer.rb
index b7c6884..7361193 100644
--- a/app/serializers/discourse_post_event/invitee_serializer.rb
+++ b/app/serializers/discourse_post_event/invitee_serializer.rb
@@ -2,7 +2,7 @@
 
 module DiscoursePostEvent
   class InviteeSerializer < ApplicationSerializer
-    attributes :id, :status, :user
+    attributes :id, :status, :user, :post_id
 
     def status
       object.status ? Invitee.statuses[object.status] : nil
diff --git a/assets/javascripts/discourse/adapters/discourse-post-event-invitee.js.es6 b/assets/javascripts/discourse/adapters/discourse-post-event-invitee.js.es6
index dafe382..c925805 100644
--- a/assets/javascripts/discourse/adapters/discourse-post-event-invitee.js.es6
+++ b/assets/javascripts/discourse/adapters/discourse-post-event-invitee.js.es6
@@ -1,11 +1,65 @@
+import { Result } from "discourse/adapters/rest";
+import { ajax } from "discourse/lib/ajax";
 import DiscoursePostEventAdapter from "./discourse-post-event-adapter";
 import { underscore } from "@ember/string";
 
 export default DiscoursePostEventAdapter.extend({
+  // TODO: destroy/update/create should be improved in core to allow for nested models
+  destroyRecord(store, type, record) {
+    return ajax(
+      this.pathFor(store, type, {
+        post_id: record.post_id,
+        invitee_id: record.id
+      }),
+      {
+        type: "DELETE"
+      }
+    );
+  },
+
+  update(store, type, id, attrs) {
+    const data = {};
+    const typeField = underscore(this.apiNameFor(type));
+    data[typeField] = attrs;
+
+    return ajax(
+      this.pathFor(store, type, { invitee_id: id, post_id: attrs.post_id }),
+      this.getPayload("PUT", data)
+    ).then(function(json) {
+      return new Result(json[typeField], json);
+    });
+  },
+
+  createRecord(store, type, attrs) {
+    const data = {};
+    const typeField = underscore(this.apiNameFor(type));
+    data[typeField] = attrs;
+    return ajax(
+      this.pathFor(store, type, attrs),
+      this.getPayload("POST", data)
+    ).then(function(json) {
+      return new Result(json[typeField], json);
+    });
+  },
+
   pathFor(store, type, findArgs) {
+    const post_id = findArgs["post_id"];
+    delete findArgs["post_id"];
+
+    const invitee_id = findArgs["invitee_id"];
+    delete findArgs["invitee_id"];
+
     let path =
-      this.basePath(store, type, findArgs) +
-      underscore(store.pluralize(this.apiNameFor(type)));
+      this.basePath(store, type, {}) +
+      "events/" +
+      post_id +
+      "/" +
+      underscore(store.pluralize(this.apiNameFor()));
+
+    if (invitee_id) {
+      path += `/${invitee_id}`;
+    }
+
     return this.appendQueryParams(path, findArgs);
   },
 
diff --git a/assets/javascripts/discourse/controllers/discourse-post-event-invitees.js.es6 b/assets/javascripts/discourse/controllers/discourse-post-event-invitees.js.es6
index c9a0efa..a046870 100644
--- a/assets/javascripts/discourse/controllers/discourse-post-event-invitees.js.es6
+++ b/assets/javascripts/discourse/controllers/discourse-post-event-invitees.js.es6
@@ -17,13 +17,20 @@ export default Controller.extend(ModalFunctionality, {
     debounce(this, this._fetchInvitees, filter, 250);
   },
 
+  @action
+  removeInvitee(invitee) {
+    invitee
+      .destroyRecord({ parent: this.model })
+      .then(() => this._fetchInvitees());
+  },
+
   _fetchInvitees(filter) {
     this.set("isLoading", true);
 
     this.store
       .findAll("discourse-post-event-invitee", {
-        "event-id": this.model.id,
-        filter
+        filter,
+        post_id: this.model.id
       })
       .then(invitees => this.set("invitees", invitees))
       .finally(() => this.set("isLoading", false));
diff --git a/assets/javascripts/discourse/templates/modal/discourse-post-event-invitees.hbs b/assets/javascripts/discourse/templates/modal/discourse-post-event-invitees.hbs
index dfaee1a..5cb7f15 100644
--- a/assets/javascripts/discourse/templates/modal/discourse-post-event-invitees.hbs
+++ b/assets/javascripts/discourse/templates/modal/discourse-post-event-invitees.hbs
@@ -11,6 +11,7 @@
     {{#each invitees as |invitee|}}
       <li class="invitee">
         {{render-invitee invitee}}
+
         {{#if invitee.status}}
           <span class="status {{invitee.status}}">
             {{i18n (concat "discourse_post_event.models.invitee.status." invitee.status)}}
@@ -20,6 +21,14 @@
             -
           </span>
         {{/if}}
+
+        {{#if model.can_act_on_discourse_post_event}}
+          {{d-button
+            class="btn-danger"
+            icon="times"
+            action=(action "removeInvitee" invitee)
+          }}
+        {{/if}}
       </li>
     {{/each}}
   </ul>
diff --git a/assets/javascripts/discourse/widgets/discourse-post-event-invitees.js.es6 b/assets/javascripts/discourse/widgets/discourse-post-event-invitees.js.es6
index 8e8b209..f88b692 100644
--- a/assets/javascripts/discourse/widgets/discourse-post-event-invitees.js.es6
+++ b/assets/javascripts/discourse/widgets/discourse-post-event-invitees.js.es6
@@ -6,8 +6,7 @@ export default createWidget("discourse-post-event-invitees", {
 
   transform(attrs) {
     return {
-      isPrivateEvent: attrs.eventModel.status === "private",
-      showAll: attrs.eventModel.stats.invited > 10
+      isPrivateEvent: attrs.eventModel.status === "private"
     };
   },
 
@@ -22,17 +21,15 @@ export default createWidget("discourse-post-event-invitees", {
         {{/if}}
       </div>
 
-      {{#if transformed.showAll}}
-        {{attach
-          widget="button"
-          attrs=(hash
-            className="show-all btn-small"
-            label="discourse_post_event.event_ui.show_all"
-            action="showAllInvitees"
-            actionParam=(hash postId=attrs.eventModel.id)
-          )
-        }}
-      {{/if}}
+      {{attach
+        widget="button"
+        attrs=(hash
+          className="show-all btn-small"
+          label="discourse_post_event.event_ui.show_all"
+          action="showAllInvitees"
+          actionParam=(hash postId=attrs.eventModel.id)
+        )
+      }}
     </div>

[... diff too long, it was truncated ...]

GitHub sha: 5c5ffdaa