REFACTOR: rewrite UI using an Ember component

REFACTORE: rewrite UI using an Ember component

diff --git a/assets/javascripts/discourse/components/post-policy.js.es6 b/assets/javascripts/discourse/components/post-policy.js.es6
new file mode 100644
index 0000000..7591e8b
--- /dev/null
+++ b/assets/javascripts/discourse/components/post-policy.js.es6
@@ -0,0 +1,151 @@
+import { bind } from "discourse-common/utils/decorators";
+import showModal from "discourse/lib/show-modal";
+import getURL from "discourse-common/lib/get-url";
+import { ajax } from "discourse/lib/ajax";
+import { popupAjaxError } from "discourse/lib/ajax-error";
+import Component from "@ember/component";
+import { computed, action } from "@ember/object";
+import layout from "javascripts/components/post-policy";
+
+export default Component.extend({
+  layout,
+  tagName: "",
+  post: null,
+  options: null,
+  showNotAccepted: false,
+  isLoading: false,
+  form: null,
+
+  init() {
+    this._super(...arguments);
+
+    this.post.set("policy_accepted_by", this.post.policy_accepted_by || []);
+    this.post.set(
+      "policy_not_accepted_by",
+      this.post.policy_not_accepted_by || []
+    );
+  },
+
+  didInsertElement() {
+    this._super(...arguments);
+
+    this.appEvents.on("policy:changed", this, "policyChanged");
+  },
+
+  willDestroyElement() {
+    this._super(...arguments);
+
+    this.appEvents.off("policy:changed", this, "policyChanged");
+  },
+
+  acceptedUsers: computed("post.policy_accepted_by.[]", function () {
+    return this.post.policy_accepted_by || [];
+  }),
+
+  notAcceptedUsers: computed("post.policy_not_accepted_by.[]", function () {
+    return this.post.policy_not_accepted_by || [];
+  }),
+
+  canManagePolicy: computed(
+    "currentUser.{id,staff}",
+    "post.user_id",
+    function () {
+      return (
+        this.get("currentUser.staff") ||
+        this.get("currentUser.id") === this.post.user_id
+      );
+    }
+  ),
+
+  currentlyAcceptedUser: computed(
+    "currentUser.id",
+    "acceptedUsers.[]",
+    function () {
+      return (
+        this.currentUser && this.acceptedUsers.findBy("id", this.currentUser.id)
+      );
+    }
+  ),
+
+  notCurrentlyAcceptedUser: computed(
+    "currentUser.id",
+    "notAcceptedUsers.[]",
+    function () {
+      return (
+        this.currentUser &&
+        this.notAcceptedUsers.findBy("id", this.currentUser.id)
+      );
+    }
+  ),
+
+  @action
+  revokePolicy(post) {
+    this.post.policy_not_accepted_by.pushObject(this.currentlyAcceptedUser);
+    this.post.set(
+      "policy_accepted_by",
+      this.post.policy_accepted_by.rejectBy("id", this.currentlyAcceptedUser.id)
+    );
+
+    this._updatePolicy("unaccept", post.id);
+
+    return false;
+  },
+
+  @action
+  editPolicy(post) {
+    showModal("policy-builder").setProperties({
+      insertMode: false,
+      post,
+      form: this.form,
+    });
+  },
+
+  @action
+  acceptPolicy(post) {
+    this.post.policy_accepted_by.pushObject(this.notCurrentlyAcceptedUser);
+    this.post.set(
+      "policy_not_accepted_by",
+      this.post.policy_not_accepted_by.rejectBy(
+        "id",
+        this.notCurrentlyAcceptedUser.id
+      )
+    );
+
+    this._updatePolicy("accept", post.id);
+
+    return false;
+  },
+
+  @action
+  toggleShowUsers() {
+    this.toggleProperty("showNotAccepted");
+  },
+
+  @bind
+  policyChanged(data) {
+    const stream = data.controller.get("model.postStream");
+    const post = stream.findLoadedPost(data.message.id);
+
+    if (post) {
+      const endpoint = getURL(`/posts/${post.id}.json`);
+      ajax(endpoint).then((result) => {
+        this.post.set("policy_accepted_by", result.policy_accepted_by || []);
+        this.post.set(
+          "policy_not_accepted_by",
+          result.policy_not_accepted_by || []
+        );
+      });
+    }
+  },
+
+  _updatePolicy(policyAction, id) {
+    this.set("isLoading", true);
+
+    return ajax(getURL(`/policy/${policyAction}`), {
+      type: "put",
+      data: { post_id: id },
+    })
+      .catch(popupAjaxError)
+      .finally(() => this.set("isLoading", false));
+  },
+});
diff --git a/assets/javascripts/discourse/templates/components/post-policy.hbs b/assets/javascripts/discourse/templates/components/post-policy.hbs
new file mode 100644
index 0000000..7cba41b
--- /dev/null
+++ b/assets/javascripts/discourse/templates/components/post-policy.hbs
@@ -0,0 +1,63 @@
+<div class="policy-footer">
+  {{#if currentlyAcceptedUser}}
+    {{d-button
+      isLoading=isLoading
+      action=(action "revokePolicy" post)
+      class="btn-danger revoke btn-revoke-policy"
+      translatedLabel=options.revokeText
+    }}
+  {{/if}}
+
+  {{#if notCurrentlyAcceptedUser}}
+    {{d-button
+      isLoading=isLoading
+      action=(action "acceptPolicy" post)
+      class="btn-primary accept btn-accept-policy"
+      translatedLabel=options.acceptText
+    }}
+  {{/if}}
+
+  <div class="user-lists">
+    <a href {{action "toggleShowUsers"}} class="toggle toggle-accepted" title={{i18n "discourse_policy.accepted_tooltip"}}>
+      <span class="user-count">
+        {{acceptedUsers.length}}
+      </span>
+      {{d-icon "user-check"}}
+    </a>
+
+    {{#unless showNotAccepted}}
+      <div class="users accepted">
+        {{#each acceptedUsers as |acceptedUser|}}
+          {{avatar acceptedUser imageSize="tiny"}}
+        {{/each}}
+      </div>
+    {{/unless}}
+
+    {{#if notAcceptedUsers.length}}
+      <div class="seperator"></div>
+
+      <a href {{action "toggleShowUsers"}} class="toggle toggle-not-accepted" title={{i18n "discourse_policy.not_accepted_tooltip"}}>
+        <span class="user-count">
+          {{notAcceptedUsers.length}}
+        </span>
+        {{d-icon "user-times"}}
+      </a>
+
+      {{#if showNotAccepted}}
+        <div class="users not-accepted">
+          {{#each notAcceptedUsers as |notAcceptedUser|}}
+            {{avatar notAcceptedUser imageSize="tiny"}}
+          {{/each}}
+        </div>
+      {{/if}}
+    {{/if}}
+  </div>
+
+  {{#if canManagePolicy}}
+    {{d-button
+      class="no-text btn-default edit-policy-settings-btn"
+      icon="cog"
+      action=(action "editPolicy" post)
+    }}
+  {{/if}}
+</div>
diff --git a/assets/javascripts/pre-initializers/define-policy-templates.js.es6 b/assets/javascripts/pre-initializers/define-policy-templates.js.es6
new file mode 100644
index 0000000..0480cfd
--- /dev/null
+++ b/assets/javascripts/pre-initializers/define-policy-templates.js.es6
@@ -0,0 +1,9 @@
+export default {
+  name: "define-policy-templates",
+  after: "inject-discourse-objects",
+
+  initialize() {
+    const template = "javascripts/components/post-policy";
+    define(template, () => Ember.TEMPLATES[template]);
+  },
+};

GitHub sha: 7f847922

mistakenly split in two parts: rewrite extend