- Notifications
You must be signed in to change notification settings - Fork8.7k
DEV: Add page-aware plugin APIs for saving user preferences#36757
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Changes from1 commit
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -2081,12 +2081,113 @@ class _PluginApi { | ||
| addAdvancedSearchOptions(options); | ||
| } | ||
| /** | ||
| * Registers a user field that can be saved via the user preferences API. | ||
| * User fields are admin-defined profile fields stored in the user_fields table. | ||
| * | ||
| * @param {string} fieldName - The name of the user field to save | ||
| * @param {Object} [options] - Optional configuration | ||
| * @param {string} [options.page] - The preferences page where this field should be saved. | ||
| * Valid pages: "account", "emails", "interface", "navigation-menu", "notifications", | ||
| * "profile", "tags", "tracking", "users" | ||
| * | ||
| * @example | ||
| * // Register a user field that will be saved on the emails preferences page | ||
| * api.addSaveableUserField("newsletter_subscribe", { page: "emails" }); | ||
| */ | ||
| addSaveableUserField(fieldName, options = {}) { | ||
| addSaveableUserField(fieldName); | ||
| if (options.page) { | ||
| this.registerValueTransformer( | ||
| "preferences-save-attributes", | ||
| ({ value: attrs, context }) => { | ||
| if (context.page === options.page) { | ||
| attrs.push(fieldName); | ||
| } | ||
| return attrs; | ||
| } | ||
| ); | ||
| } | ||
| } | ||
| /** | ||
| * Registers a user option that can be saved via the user preferences API. | ||
| * User options are preference settings stored in the user_options table. | ||
| * | ||
| * @param {string} fieldName - The name of the user option to save | ||
| * @param {Object} [options] - Optional configuration | ||
| * @param {string} [options.page] - The preferences page where this option should be saved. | ||
| * Valid pages: "account", "emails", "interface", "navigation-menu", "notifications", | ||
| * "profile", "tags", "tracking", "users" | ||
| * | ||
| * @example | ||
| * // Register a user option that will be saved on the emails preferences page | ||
| * api.addSaveableUserOption("chat_email_frequency", { page: "emails" }); | ||
| * | ||
| * @example | ||
| * // Register a user option without specifying a page (for use with custom preference pages) | ||
| * api.addSaveableUserOption("my_custom_setting"); | ||
| */ | ||
| addSaveableUserOption(fieldName, options = {}) { | ||
| addSaveableUserOptionField(fieldName); | ||
| if (options.page) { | ||
| this.registerValueTransformer( | ||
| "preferences-save-attributes", | ||
| ({ value: attrs, context }) => { | ||
| if (context.page === options.page) { | ||
| attrs.push(fieldName); | ||
| } | ||
| return attrs; | ||
| } | ||
| ); | ||
| } | ||
| } | ||
| /** | ||
| * @deprecated Use `addSaveableUserOption` instead | ||
| */ | ||
| addSaveableUserOptionField(fieldName, options = {}) { | ||
| this.addSaveableUserOption(fieldName, options); | ||
| } | ||
| /** | ||
| * Ensures custom_fields are saved on a specific preferences page. | ||
| * Custom fields are stored in the user_custom_fields table. | ||
| * | ||
| * Unlike `addSaveableUserOption` and `addSaveableUserField` which track | ||
| * individual field names, this method ensures the entire `custom_fields` | ||
| * object is included in the save payload. Multiple plugins can safely | ||
| * call this for the same page - `custom_fields` will only be added once. | ||
| * | ||
| * @param {Object} options - Configuration options | ||
| * @param {string} options.page - The preferences page where custom_fields should be saved. | ||
| * Valid pages: "account", "emails", "interface", "navigation-menu", "notifications", | ||
| * "profile", "tags", "tracking", "users" | ||
| * | ||
| * @example | ||
| * // Ensure custom_fields are saved on the notifications preferences page | ||
| * api.addSaveableCustomFields({ page: "notifications" }); | ||
| */ | ||
| addSaveableCustomFields(options = {}) { | ||
ZogStriP marked this conversation as resolved. OutdatedShow resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| if (!options.page) { | ||
| // eslint-disable-next-line no-console | ||
| console.warn( | ||
ZogStriP marked this conversation as resolved. OutdatedShow resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| "addSaveableCustomFields requires a `page` option to specify which preferences page should save custom_fields" | ||
| ); | ||
| return; | ||
| } | ||
| this.registerValueTransformer( | ||
| "preferences-save-attributes", | ||
| ({ value: attrs, context }) => { | ||
| if (context.page === options.page && !attrs.includes("custom_fields")) { | ||
| attrs.push("custom_fields"); | ||
| } | ||
| return attrs; | ||
| } | ||
| ); | ||
| } | ||
| /** | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,35 +1,26 @@ | ||
| import{withPluginApi}from"discourse/lib/plugin-api"; | ||
| exportdefault{ | ||
| name:"chat-user-options", | ||
| initialize(container){ | ||
| withPluginApi((api)=>{ | ||
| const{ chat_enabled}=container.lookup("service:site-settings"); | ||
| if(chat_enabled){ | ||
| // Chat settings | ||
| api.addSaveableUserOption("chat_enabled"); | ||
pmusaraj marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| api.addSaveableUserOption("chat_header_indicator_preference"); | ||
| api.addSaveableUserOption("chat_quick_reaction_type"); | ||
| api.addSaveableUserOption("chat_quick_reactions_custom"); | ||
| api.addSaveableUserOption("chat_send_shortcut"); | ||
| api.addSaveableUserOption("chat_separate_sidebar_mode"); | ||
| api.addSaveableUserOption("chat_sound"); | ||
| api.addSaveableUserOption("ignore_channel_wide_mention"); | ||
| api.addSaveableUserOption("only_chat_push_notifications"); | ||
| api.addSaveableUserOption("show_thread_title_prompts"); | ||
| // Email settings | ||
| api.addSaveableUserOption("chat_email_frequency",{page:"emails"}); | ||
| } | ||
| }); | ||
| }, | ||
This file was deleted.
Uh oh!
There was an error while loading.Please reload this page.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| import { click, visit } from "@ember/test-helpers"; | ||
| import { test } from "qunit"; | ||
| import { | ||
| acceptance, | ||
| updateCurrentUser, | ||
| } from "discourse/tests/helpers/qunit-helpers"; | ||
| import selectKit from "discourse/tests/helpers/select-kit-helper"; | ||
| acceptance("Chat | Email Preferences", function (needs) { | ||
| needs.user(); | ||
| needs.settings({ | ||
| chat_enabled: true, | ||
| }); | ||
| let savedData; | ||
| needs.pretender((server, helper) => { | ||
| server.put("/u/eviltrout.json", (request) => { | ||
| savedData = helper.parsePostData(request.requestBody); | ||
| return helper.response({ user: {} }); | ||
| }); | ||
| }); | ||
| test("saves chat_email_frequency when saving email preferences", async function (assert) { | ||
| updateCurrentUser({ | ||
| user_option: { | ||
| chat_email_frequency: "when_away", | ||
| }, | ||
| }); | ||
| await visit("/u/eviltrout/preferences/emails"); | ||
| const dropdown = selectKit("#user_chat_email_frequency"); | ||
| await dropdown.expand(); | ||
| await dropdown.selectRowByValue("never"); | ||
| await click(".save-changes"); | ||
| assert.strictEqual( | ||
| savedData.chat_email_frequency, | ||
| "never", | ||
| "chat_email_frequency is included in saved data" | ||
| ); | ||
| }); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,24 +1,17 @@ | ||
| import { withPluginApi } from "discourse/lib/plugin-api"; | ||
| export default { | ||
| name: "policy-user-options", | ||
| initialize(container) { | ||
| withPluginApi((api) => { | ||
| const { policy_enabled } = container.lookup("service:site-settings"); | ||
| if (policy_enabled){ | ||
| api.addSaveableUserOption("policy_email_frequency", { | ||
| page: "emails", | ||
| }); | ||
| } | ||
| }); | ||
| }, | ||
| }; |
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.