Skip to content

Commit

Permalink
UX: move data export to preferences page for new user nav (#20141)
Browse files Browse the repository at this point in the history
  • Loading branch information
awesomerobot committed Feb 3, 2023
1 parent 2bff6db commit e5f557b
Show file tree
Hide file tree
Showing 6 changed files with 64 additions and 43 deletions.
@@ -1,7 +1,7 @@
import { gt, not, or } from "@ember/object/computed";
import { alias, gt, not, or } from "@ember/object/computed";
import { propertyNotEqual, setting } from "discourse/lib/computed";
import CanCheckEmails from "discourse/mixins/can-check-emails";
import Controller from "@ember/controller";
import Controller, { inject as controller } from "@ember/controller";
import EmberObject, { action } from "@ember/object";
import I18n from "I18n";
import discourseComputed from "discourse-common/utils/decorators";
Expand All @@ -12,9 +12,13 @@ import { popupAjaxError } from "discourse/lib/ajax-error";
import { inject as service } from "@ember/service";
import { next } from "@ember/runloop";
import showModal from "discourse/lib/show-modal";
import { exportUserArchive } from "discourse/lib/export-csv";

export default Controller.extend(CanCheckEmails, {
dialog: service(),
user: controller(),
canDownloadPosts: alias("user.viewingSelf"),

init() {
this._super(...arguments);

Expand Down Expand Up @@ -244,5 +248,12 @@ export default Controller.extend(CanCheckEmails, {
connectAccount(method) {
method.doLogin({ reconnect: true });
},

exportUserArchive() {
this.dialog.yesNoConfirm({
message: I18n.t("user.download_archive.confirm"),
didConfirm: () => exportUserArchive(),
});
},
},
});
Expand Up @@ -15,6 +15,7 @@

<nav
title={{i18n "topic.progress.title"}}
aria-label={{i18n "topic.progress.title"}}
class={{if this.hideProgress "hidden"}}
id="topic-progress"
style={{html-safe this.progressStyle}}
Expand Down
Expand Up @@ -263,6 +263,23 @@
</div>
{{/if}}

{{#if this.canDownloadPosts}}
<div class="control-group pref-data-export">
<label class="control-label">{{i18n "user.download_archive.title"}}</label>
<div class="controls">
<DButton
@action={{action "exportUserArchive"}}
@class="btn-default btn-request-archive"
@label="user.download_archive.button_text"
@icon="download"
/>
</div>
<div class="instructions">
{{i18n "user.download_archive.description"}}
</div>
</div>
{{/if}}

<span>
<PluginOutlet
@name="user-preferences-account"
Expand Down
@@ -1,6 +1,6 @@
import { acceptance, query } from "../helpers/qunit-helpers";
import { test } from "qunit";
import { click, visit } from "@ember/test-helpers";
import { visit } from "@ember/test-helpers";
import I18n from "I18n";

acceptance("User Activity / Replies - empty state", function (needs) {
Expand Down Expand Up @@ -33,39 +33,3 @@ acceptance("User Activity / Replies - empty state", function (needs) {
);
});
});

acceptance("User Activity / Replies - Download All", function (needs) {
const currentUser = "eviltrout";
const anotherUser = "charlie";
needs.user();
needs.pretender((server, helper) => {
server.post("/export_csv/export_entity.json", () => {
return helper.response({});
});
});

test("Can see and trigger download for own data replies", async function (assert) {
await visit(`/u/${currentUser}/activity`);

assert.ok(query(".user-additional-controls .btn"), "button exists");

await click(".user-additional-controls .btn");
await click("#dialog-holder .btn-primary");

assert.equal(
query(".dialog-body").innerText.trim(),
I18n.t("user.download_archive.success")
);

await click("#dialog-holder .btn-primary");
});

test("Cannot see 'Download All' button for another user", async function (assert) {
await visit(`/u/${anotherUser}/activity`);

assert.notOk(
query(".user-additional-controls .btn"),
"download button is not present"
);
});
});
Expand Up @@ -307,3 +307,29 @@ acceptance("User Preferences - Account", function (needs) {
);
});
});

acceptance("User Preferences — Account - Download Archive", function (needs) {
const currentUser = "eviltrout";
needs.user();
needs.pretender((server, helper) => {
server.post("/export_csv/export_entity.json", () => {
return helper.response({});
});
});

test("Can see and trigger download for account data", async function (assert) {
await visit(`/u/${currentUser}/preferences/account`);

assert.ok(query(".btn-request-archive"), "button exists");

await click(".btn-request-archive");
await click("#dialog-holder .btn-primary");

assert.equal(
query(".dialog-body").innerText.trim(),
I18n.t("user.download_archive.success")
);

await click("#dialog-holder .btn-primary");
});
});
10 changes: 6 additions & 4 deletions config/locales/client.en.yml
Expand Up @@ -1047,10 +1047,12 @@ en:
mute: "Mute"
edit: "Edit Preferences"
download_archive:
button_text: "Download All"
confirm: "Are you sure you want to download your posts?"
success: "Download initiated, you will be notified via message when the process is complete."
rate_limit_error: "Posts can be downloaded once per day, please try again tomorrow."
title: "Export your data"
description: "Download an archive of your account activity and preferences."
button_text: "Request archive"
confirm: "Do you really want to download an archive of your account activity and preferences?"
success: "We've started collecting your archive, you will receive a message when the process is complete."
rate_limit_error: "Account archives can be downloaded once per day, please try again tomorrow."
new_private_message: "New Message"
private_message: "Message"
private_messages: "Messages"
Expand Down

1 comment on commit e5f557b

@discoursebot
Copy link

Choose a reason for hiding this comment

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

This commit has been mentioned on Discourse Meta. There might be relevant details there:

https://meta.discourse.org/t/modifyclass-does-not-override-action/297051/2

Please sign in to comment.