FEATURE: Allow recovery of deleted small action posts (#14643)

FEATURE: Allow recovery of deleted small action posts (#14643)

Previously when clicking the Delete button for small action posts there was no way to recover this post if the action was accidental. Now if canRecover is true on the post, which it is just after it is deleted and the post is fetched from the server again, we show an undo button which calls the recover endpoint for the post.

We also now disallow the editing of the post if it is deleted, and show the proper deleted red CSS on the small action post when deleted.

diff --git a/app/assets/javascripts/discourse/app/widgets/post-small-action.js b/app/assets/javascripts/discourse/app/widgets/post-small-action.js
index 7331ce4..76f1b95 100644
--- a/app/assets/javascripts/discourse/app/widgets/post-small-action.js
+++ b/app/assets/javascripts/discourse/app/widgets/post-small-action.js
@@ -87,6 +87,17 @@ export default createWidget("post-small-action", {
   html(attrs) {
     const contents = [];
 
+    if (attrs.canRecover) {
+      contents.push(
+        this.attach("button", {
+          className: "small-action-recover",
+          icon: "undo",
+          action: "recoverPost",
+          title: "post.controls.undelete",
+        })
+      );
+    }
+
     if (attrs.canDelete) {
       contents.push(
         this.attach("button", {
@@ -98,7 +109,7 @@ export default createWidget("post-small-action", {
       );
     }
 
-    if (attrs.canEdit) {
+    if (attrs.canEdit && !attrs.canRecover) {
       contents.push(
         this.attach("button", {
           className: "small-action-edit",
diff --git a/app/assets/javascripts/discourse/tests/integration/widgets/post-small-action-test.js b/app/assets/javascripts/discourse/tests/integration/widgets/post-small-action-test.js
new file mode 100644
index 0000000..087835a
--- /dev/null
+++ b/app/assets/javascripts/discourse/tests/integration/widgets/post-small-action-test.js
@@ -0,0 +1,80 @@
+import componentTest, {
+  setupRenderingTest,
+} from "discourse/tests/helpers/component-test";
+import { discourseModule, exists } from "discourse/tests/helpers/qunit-helpers";
+import hbs from "htmlbars-inline-precompile";
+
+discourseModule(
+  "Integration | Component | Widget | post-small-action",
+  function (hooks) {
+    setupRenderingTest(hooks);
+
+    componentTest("does not have delete/edit/recover buttons by default", {
+      template: hbs`{{mount-widget widget="post-small-action" args=args}}`,
+      beforeEach() {
+        this.set("args", { id: 123 });
+      },
+      async test(assert) {
+        assert.ok(!exists(".small-action-desc > .small-action-delete"));
+        assert.ok(!exists(".small-action-desc > .small-action-recover"));
+        assert.ok(!exists(".small-action-desc > .small-action-edit"));
+      },
+    });
+
+    componentTest("shows edit button if canEdit", {
+      template: hbs`{{mount-widget widget="post-small-action" args=args}}`,
+      beforeEach() {
+        this.set("args", { id: 123, canEdit: true });
+      },
+      async test(assert) {
+        assert.ok(
+          exists(".small-action-desc > .small-action-edit"),
+          "it adds the edit small action button"
+        );
+      },
+    });
+
+    componentTest("does not show edit button if canRecover even if canEdit", {
+      template: hbs`{{mount-widget widget="post-small-action" args=args}}`,
+      beforeEach() {
+        this.set("args", { id: 123, canEdit: true, canRecover: true });
+      },
+      async test(assert) {
+        assert.ok(
+          !exists(".small-action-desc > .small-action-edit"),
+          "it does not add the edit small action button"
+        );
+        assert.ok(
+          exists(".small-action-desc > .small-action-recover"),
+          "it adds the recover small action button"
+        );
+      },
+    });
+
+    componentTest("shows delete button if canDelete", {
+      template: hbs`{{mount-widget widget="post-small-action" args=args}}`,
+      beforeEach() {
+        this.set("args", { id: 123, canDelete: true });
+      },
+      async test(assert) {
+        assert.ok(
+          exists(".small-action-desc > .small-action-delete"),
+          "it adds the delete small action button"
+        );
+      },
+    });
+
+    componentTest("shows undo button if canRecover", {
+      template: hbs`{{mount-widget widget="post-small-action" args=args}}`,
+      beforeEach() {
+        this.set("args", { id: 123, canRecover: true });
+      },
+      async test(assert) {
+        assert.ok(
+          exists(".small-action-desc > .small-action-recover"),
+          "it adds the recover small action button"
+        );
+      },
+    });
+  }
+);
diff --git a/app/assets/stylesheets/common/base/topic-post.scss b/app/assets/stylesheets/common/base/topic-post.scss
index 65fb9b1..cbaee44 100644
--- a/app/assets/stylesheets/common/base/topic-post.scss
+++ b/app/assets/stylesheets/common/base/topic-post.scss
@@ -929,7 +929,7 @@ blockquote > *:last-child {
     }
   }
 
-  .small-action.deleted {
+  &.deleted {
     background-color: var(--danger-low-mid);
   }
 

GitHub sha: ecee9d000ba1be6c0384fcb470ee17bf717652db

This commit appears in #14643 which was approved by techAPJ. It was merged by martin.