UX: move data export to preferences page for new user nav (#20141)

This commit is contained in:
Kris 2023-02-03 11:19:08 -05:00 committed by GitHub
parent 2bff6dbe26
commit e5f557b971
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 64 additions and 43 deletions

View File

@ -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 { propertyNotEqual, setting } from "discourse/lib/computed";
import CanCheckEmails from "discourse/mixins/can-check-emails"; 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 EmberObject, { action } from "@ember/object";
import I18n from "I18n"; import I18n from "I18n";
import discourseComputed from "discourse-common/utils/decorators"; import discourseComputed from "discourse-common/utils/decorators";
@ -12,9 +12,13 @@ import { popupAjaxError } from "discourse/lib/ajax-error";
import { inject as service } from "@ember/service"; import { inject as service } from "@ember/service";
import { next } from "@ember/runloop"; import { next } from "@ember/runloop";
import showModal from "discourse/lib/show-modal"; import showModal from "discourse/lib/show-modal";
import { exportUserArchive } from "discourse/lib/export-csv";
export default Controller.extend(CanCheckEmails, { export default Controller.extend(CanCheckEmails, {
dialog: service(), dialog: service(),
user: controller(),
canDownloadPosts: alias("user.viewingSelf"),
init() { init() {
this._super(...arguments); this._super(...arguments);
@ -244,5 +248,12 @@ export default Controller.extend(CanCheckEmails, {
connectAccount(method) { connectAccount(method) {
method.doLogin({ reconnect: true }); method.doLogin({ reconnect: true });
}, },
exportUserArchive() {
this.dialog.yesNoConfirm({
message: I18n.t("user.download_archive.confirm"),
didConfirm: () => exportUserArchive(),
});
},
}, },
}); });

View File

@ -15,6 +15,7 @@
<nav <nav
title={{i18n "topic.progress.title"}} title={{i18n "topic.progress.title"}}
aria-label={{i18n "topic.progress.title"}}
class={{if this.hideProgress "hidden"}} class={{if this.hideProgress "hidden"}}
id="topic-progress" id="topic-progress"
style={{html-safe this.progressStyle}} style={{html-safe this.progressStyle}}

View File

@ -263,6 +263,23 @@
</div> </div>
{{/if}} {{/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> <span>
<PluginOutlet <PluginOutlet
@name="user-preferences-account" @name="user-preferences-account"

View File

@ -1,6 +1,6 @@
import { acceptance, query } from "../helpers/qunit-helpers"; import { acceptance, query } from "../helpers/qunit-helpers";
import { test } from "qunit"; import { test } from "qunit";
import { click, visit } from "@ember/test-helpers"; import { visit } from "@ember/test-helpers";
import I18n from "I18n"; import I18n from "I18n";
acceptance("User Activity / Replies - empty state", function (needs) { acceptance("User Activity / Replies - empty state", function (needs) {
@ -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"
);
});
});

View File

@ -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");
});
});

View File

@ -1047,10 +1047,12 @@ en:
mute: "Mute" mute: "Mute"
edit: "Edit Preferences" edit: "Edit Preferences"
download_archive: download_archive:
button_text: "Download All" title: "Export your data"
confirm: "Are you sure you want to download your posts?" description: "Download an archive of your account activity and preferences."
success: "Download initiated, you will be notified via message when the process is complete." button_text: "Request archive"
rate_limit_error: "Posts can be downloaded once per day, please try again tomorrow." 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" new_private_message: "New Message"
private_message: "Message" private_message: "Message"
private_messages: "Messages" private_messages: "Messages"