UX: reorganize user prefs for experimental user nav (#18764)
Trying out changes to reduce the number of nav items in the experimental horizontal user nav. These changes should only appear with the redesigned_user_page_nav_enabled feature flag. 1. Created a new "Tracking" route. This combines some tracking-related settings from Notifications and Category and Tag tracking (which were separate tabs previously). Don't love the layout yet, but it's something that we can work on. 2. Moved some user-related settings out of Notifications and to the Users tab. These seem more user-related to me, and it's nice that we can associate enabling messages with the setting to limit who can send messages. 3. Moved the App tab (lists app permissions) to be within the Security tab. It's very similar to Recently Used Devices.
This commit is contained in:
parent
60abe99add
commit
a6c787345c
|
@ -4,58 +4,58 @@
|
||||||
<span>{{i18n "user.preferences_nav.account"}}</span>
|
<span>{{i18n "user.preferences_nav.account"}}</span>
|
||||||
</LinkTo>
|
</LinkTo>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="nav-security">
|
<li class="nav-security">
|
||||||
<LinkTo @route="preferences.security">
|
<LinkTo @route="preferences.security">
|
||||||
{{d-icon "lock"}}
|
{{d-icon "lock"}}
|
||||||
<span>{{i18n "user.preferences_nav.security"}}</span>
|
<span>{{i18n "user.preferences_nav.security"}}</span>
|
||||||
</LinkTo>
|
</LinkTo>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="nav-profile">
|
<li class="nav-profile">
|
||||||
<LinkTo @route="preferences.profile">
|
<LinkTo @route="preferences.profile">
|
||||||
{{d-icon "user"}}
|
{{d-icon "user"}}
|
||||||
<span>{{i18n "user.preferences_nav.profile"}}</span>
|
<span>{{i18n "user.preferences_nav.profile"}}</span>
|
||||||
</LinkTo>
|
</LinkTo>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="nav-emails">
|
<li class="nav-emails">
|
||||||
<LinkTo @route="preferences.emails">
|
<LinkTo @route="preferences.emails">
|
||||||
{{d-icon "envelope"}}
|
{{d-icon "envelope"}}
|
||||||
<span>{{i18n "user.preferences_nav.emails"}}</span>
|
<span>{{i18n "user.preferences_nav.emails"}}</span>
|
||||||
</LinkTo>
|
</LinkTo>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="nav-notifications">
|
<li class="nav-notifications">
|
||||||
<LinkTo @route="preferences.notifications">
|
<LinkTo @route="preferences.notifications">
|
||||||
{{d-icon "bell"}}
|
{{d-icon "bell"}}
|
||||||
<span>{{i18n "user.preferences_nav.notifications"}}</span>
|
<span>{{i18n "user.preferences_nav.notifications"}}</span>
|
||||||
</LinkTo>
|
</LinkTo>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
{{#if @model.can_change_tracking_preferences}}
|
{{#if @model.can_change_tracking_preferences}}
|
||||||
<li class="indent nav-categories">
|
<li class="nav-tracking">
|
||||||
<LinkTo @route="preferences.categories">
|
<LinkTo @route="preferences.tracking">
|
||||||
{{d-icon "folder"}}
|
{{d-icon "plus"}}
|
||||||
<span>{{i18n "user.preferences_nav.categories"}}</span>
|
<span>{{i18n "user.preferences_nav.tracking"}}</span>
|
||||||
</LinkTo>
|
</LinkTo>
|
||||||
</li>
|
</li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
<li class="indent nav-users">
|
<li class="indent nav-users">
|
||||||
<LinkTo @route="preferences.users">
|
<LinkTo @route="preferences.users">
|
||||||
{{d-icon "users"}}
|
{{d-icon "users"}}
|
||||||
<span>{{i18n "user.preferences_nav.users"}}</span>
|
<span>{{i18n "user.preferences_nav.users"}}</span>
|
||||||
</LinkTo>
|
</LinkTo>
|
||||||
</li>
|
</li>
|
||||||
{{#if (and @model.can_change_tracking_preferences @siteSettings.tagging_enabled)}}
|
|
||||||
<li class="indent nav-tags">
|
|
||||||
<LinkTo @route="preferences.tags">
|
|
||||||
{{d-icon "tag"}}
|
|
||||||
<span>{{i18n "user.preferences_nav.tags"}}</span>
|
|
||||||
</LinkTo>
|
|
||||||
</li>
|
|
||||||
{{/if}}
|
|
||||||
<li class="nav-interface">
|
<li class="nav-interface">
|
||||||
<LinkTo @route="preferences.interface">
|
<LinkTo @route="preferences.interface">
|
||||||
{{d-icon "desktop"}}
|
{{d-icon "desktop"}}
|
||||||
<span>{{i18n "user.preferences_nav.interface"}}</span>
|
<span>{{i18n "user.preferences_nav.interface"}}</span>
|
||||||
</LinkTo>
|
</LinkTo>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
{{#if @siteSettings.enable_experimental_sidebar_hamburger}}
|
{{#if @siteSettings.enable_experimental_sidebar_hamburger}}
|
||||||
<li class="indent nav-sidebar">
|
<li class="indent nav-sidebar">
|
||||||
<LinkTo @route="preferences.sidebar">
|
<LinkTo @route="preferences.sidebar">
|
||||||
|
@ -64,11 +64,6 @@
|
||||||
</LinkTo>
|
</LinkTo>
|
||||||
</li>
|
</li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
<PluginOutlet @name="user-preferences-nav-under-interface" @connectorTagName="div" @args={{hash model=@model}} />
|
<PluginOutlet @name="user-preferences-nav-under-interface" @connectorTagName="div" @args={{hash model=@model}} />
|
||||||
<li class="nav-apps">
|
|
||||||
<LinkTo @route="preferences.apps">
|
|
||||||
{{d-icon "mobile-alt"}}
|
|
||||||
<span>{{i18n "user.preferences_nav.apps"}}</span>
|
|
||||||
</LinkTo>
|
|
||||||
</li>
|
|
||||||
<PluginOutlet @name="user-preferences-nav" @connectorTagName="li" @args={{hash model=@model}} />
|
<PluginOutlet @name="user-preferences-nav" @connectorTagName="li" @args={{hash model=@model}} />
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
<div class="control-group private-messages">
|
||||||
|
<label class="control-label">{{i18n "user.private_messages"}}</label>
|
||||||
|
<div class="controls">
|
||||||
|
<PreferenceCheckbox @labelKey="user.allow_private_messages" @checked={{@model.user_option.allow_private_messages}} />
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,53 @@
|
||||||
|
<div class="control-group category-notifications">
|
||||||
|
<label class="control-label">{{i18n "user.categories_settings"}}</label>
|
||||||
|
|
||||||
|
<div class="controls tracking-controls tracking-controls--watched-categories">
|
||||||
|
<label>{{d-icon "d-watching"}} {{i18n "user.watched_categories"}}</label>
|
||||||
|
{{#if @canSee}}
|
||||||
|
<a class="show-tracking" href={{@model.watchingTopicsPath}}>{{i18n "user.tracked_topics_link"}}</a>
|
||||||
|
{{/if}}
|
||||||
|
<CategorySelector @categories={{@model.watchedCategories}} @blockedCategories={{@selectedCategories}} @onChange={{action (mut @model.watchedCategories)}} />
|
||||||
|
</div>
|
||||||
|
<div class="instructions">{{i18n "user.watched_categories_instructions"}}</div>
|
||||||
|
|
||||||
|
<div class="controls tracking-controls tracking-controls--tracked-categories">
|
||||||
|
<label>{{d-icon "d-tracking"}} {{i18n "user.tracked_categories"}}</label>
|
||||||
|
{{#if @canSee}}
|
||||||
|
<a class="show-tracking" href={{@model.trackingTopicsPath}}>{{i18n "user.tracked_topics_link"}}</a>
|
||||||
|
{{/if}}
|
||||||
|
<CategorySelector @categories={{@model.trackedCategories}} @blockedCategories={{@selectedCategories}} @onChange={{action (mut @model.trackedCategories)}} />
|
||||||
|
</div>
|
||||||
|
<div class="instructions">{{i18n "user.tracked_categories_instructions"}}</div>
|
||||||
|
|
||||||
|
<div class="controls tracking-controls tracking-controls--watched-first-categories">
|
||||||
|
<label>{{d-icon "d-watching-first"}} {{i18n "user.watched_first_post_categories"}}</label>
|
||||||
|
<CategorySelector @categories={{@model.watchedFirstPostCategories}} @blockedCategories={{@selectedCategories}} @onChange={{action (mut @model.watchedFirstPostCategories)}} />
|
||||||
|
</div>
|
||||||
|
<div class="instructions">{{i18n "user.watched_first_post_categories_instructions"}}</div>
|
||||||
|
|
||||||
|
{{#if @siteSettings.mute_all_categories_by_default}}
|
||||||
|
<div class="controls tracking-controls tracking-controls--regular-categories">
|
||||||
|
<label>{{d-icon "d-regular"}} {{i18n "user.regular_categories"}}</label>
|
||||||
|
<CategorySelector @categories={{@model.regularCategories}} @blockedCategories={{@selectedCategories}} @onChange={{action (mut @model.regularCategories)}} />
|
||||||
|
</div>
|
||||||
|
<div class="instructions">{{i18n "user.regular_categories_instructions"}}</div>
|
||||||
|
{{else}}
|
||||||
|
<div class="controls tracking-controls tracking-controls--muted-categories">
|
||||||
|
<label>{{d-icon "d-muted"}} {{i18n "user.muted_categories"}}</label>
|
||||||
|
|
||||||
|
{{#if @canSee}}
|
||||||
|
<a class="show-tracking" href={{@model.mutedTopicsPath}}>{{i18n "user.tracked_topics_link"}}</a>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<CategorySelector @categories={{@model.mutedCategories}} @blockedCategories={{@selectedCategories}} @onChange={{action (mut @model.mutedCategories)}} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="instructions">{{i18n (if @hideMutedTags "user.muted_categories_instructions" "user.muted_categories_instructions_dont_hide")}}</div>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<PluginOutlet @name="user-preferences-categories" @tagName="span" @connectorTagName="div" @args={{hash model=@model save=@save}} />
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<PluginOutlet @name="user-custom-controls" @tagName="span" @connectorTagName="div" @args={{hash model=@model}} />
|
|
@ -0,0 +1,45 @@
|
||||||
|
{{#if @siteSettings.tagging_enabled}}
|
||||||
|
<div class="control-group tag-notifications">
|
||||||
|
<label class="control-label">{{i18n "user.tag_settings"}}</label>
|
||||||
|
|
||||||
|
<div class="controls tracking-controls">
|
||||||
|
<label>{{d-icon "d-watching" class="icon watching"}} {{i18n "user.watched_tags"}}</label>
|
||||||
|
<TagChooser @tags={{@model.watched_tags}} @blockedTags={{@selectedTags}} @everyTag={{true}} @unlimitedTagCount={{true}} @options={{hash
|
||||||
|
allowAny=false
|
||||||
|
}} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="instructions">{{i18n "user.watched_tags_instructions"}}</div>
|
||||||
|
|
||||||
|
<div class="controls tracking-controls">
|
||||||
|
<label>{{d-icon "d-tracking" class="icon tracking"}} {{i18n "user.tracked_tags"}}</label>
|
||||||
|
<TagChooser @tags={{@model.tracked_tags}} @blockedTags={{@selectedTags}} @everyTag={{true}} @unlimitedTagCount={{true}} @options={{hash
|
||||||
|
allowAny=false
|
||||||
|
}} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="instructions">{{i18n "user.tracked_tags_instructions"}}</div>
|
||||||
|
|
||||||
|
<div class="controls tracking-controls">
|
||||||
|
<label>{{d-icon "d-watching-first" class="icon watching-first-post"}} {{i18n "user.watched_first_post_tags"}}</label>
|
||||||
|
<TagChooser @tags={{@model.watching_first_post_tags}} @blockedTags={{@selectedTags}} @everyTag={{true}} @unlimitedTagCount={{true}} @options={{hash
|
||||||
|
allowAny=false
|
||||||
|
}} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="instructions">
|
||||||
|
{{i18n "user.watched_first_post_tags_instructions"}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="controls tracking-controls">
|
||||||
|
<label>{{d-icon "d-muted" class="icon muted"}} {{i18n "user.muted_tags"}}</label>
|
||||||
|
<TagChooser @tags={{@model.muted_tags}} @blockedTags={{@selectedTags}} @everyTag={{true}} @unlimitedTagCount={{true}} @options={{hash
|
||||||
|
allowAny=false
|
||||||
|
}} />
|
||||||
|
</div>
|
||||||
|
<div class="instructions">{{i18n "user.muted_tags_instructions"}}</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<PluginOutlet @name="user-preferences-tags" @connectorTagName="div" @args={{hash model=@model save=@save}} />
|
||||||
|
<PluginOutlet @name="user-custom-controls" @connectorTagName="div" @args={{hash model=@model}} />
|
||||||
|
{{/if}}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<div class="user-preferences_tracking-topics-controls">
|
||||||
|
<div class="controls controls-dropdown">
|
||||||
|
<label>{{i18n "user.new_topic_duration.label"}}</label>
|
||||||
|
<ComboBox @class="duration" @valueProperty="value" @content={{@considerNewTopicOptions}} @value={{@model.user_option.new_topic_duration_minutes}} @onChange={{action (mut @model.user_option.new_topic_duration_minutes)}} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="controls controls-dropdown">
|
||||||
|
<label>{{i18n "user.auto_track_topics"}}</label>
|
||||||
|
<ComboBox @valueProperty="value" @content={{@autoTrackDurations}} @value={{@model.user_option.auto_track_topics_after_msecs}} @onChange={{action (mut @model.user_option.auto_track_topics_after_msecs)}} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="controls controls-dropdown">
|
||||||
|
<label>{{i18n "user.notification_level_when_replying"}}</label>
|
||||||
|
<ComboBox @valueProperty="value" @content={{@notificationLevelsForReplying}} @value={{@model.user_option.notification_level_when_replying}} @onChange={{action (mut @model.user_option.notification_level_when_replying)}} />
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -0,0 +1,26 @@
|
||||||
|
{{#if @model.userApiKeys}}
|
||||||
|
<div class="control-group apps">
|
||||||
|
<label class="control-label">{{i18n "user.apps"}}</label>
|
||||||
|
<div class="controls">
|
||||||
|
{{#each @model.userApiKeys as |key|}}
|
||||||
|
<div>
|
||||||
|
<span>{{key.application_name}}</span>
|
||||||
|
{{#if key.revoked}}
|
||||||
|
<DButton @action={{route-action "undoRevokeApiKey"}} @actionParam={{key}} @class="btn" @label="user.undo_revoke_access" />
|
||||||
|
{{else}}
|
||||||
|
<DButton @action={{route-action "revokeApiKey"}} @actionParam={{key}} @class="btn" @label="user.revoke_access" />
|
||||||
|
{{/if}}
|
||||||
|
<p>
|
||||||
|
<ul>
|
||||||
|
{{#each key.scopes as |scope|}}
|
||||||
|
<li>{{scope}}</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
</p>
|
||||||
|
<p><span>{{i18n "user.api_approved"}}</span> {{bound-date key.created_at}}</p>
|
||||||
|
<p><span>{{i18n "user.api_last_used_at"}}</span> {{bound-date key.last_used_at}}</p>
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
|
@ -0,0 +1,157 @@
|
||||||
|
import Controller from "@ember/controller";
|
||||||
|
import { NotificationLevels } from "discourse/lib/notification-levels";
|
||||||
|
import I18n from "I18n";
|
||||||
|
import { popupAjaxError } from "discourse/lib/ajax-error";
|
||||||
|
import { action, computed } from "@ember/object";
|
||||||
|
import { inject as service } from "@ember/service";
|
||||||
|
import { tracked } from "@glimmer/tracking";
|
||||||
|
|
||||||
|
export default class extends Controller {
|
||||||
|
@service currentUser;
|
||||||
|
@service siteSettings;
|
||||||
|
@tracked saved = false;
|
||||||
|
|
||||||
|
saveAttrNames = [
|
||||||
|
"new_topic_duration_minutes",
|
||||||
|
"auto_track_topics_after_msecs",
|
||||||
|
"notification_level_when_replying",
|
||||||
|
"muted_category_ids",
|
||||||
|
"regular_category_ids",
|
||||||
|
"watched_category_ids",
|
||||||
|
"tracked_category_ids",
|
||||||
|
"watched_first_post_category_ids",
|
||||||
|
"muted_tags",
|
||||||
|
"tracked_tags",
|
||||||
|
"watched_tags",
|
||||||
|
"watching_first_post_tags",
|
||||||
|
];
|
||||||
|
|
||||||
|
likeNotificationFrequencies = [
|
||||||
|
{ name: I18n.t("user.like_notification_frequency.always"), value: 0 },
|
||||||
|
{
|
||||||
|
name: I18n.t("user.like_notification_frequency.first_time_and_daily"),
|
||||||
|
value: 1,
|
||||||
|
},
|
||||||
|
{ name: I18n.t("user.like_notification_frequency.first_time"), value: 2 },
|
||||||
|
{ name: I18n.t("user.like_notification_frequency.never"), value: 3 },
|
||||||
|
];
|
||||||
|
|
||||||
|
autoTrackDurations = [
|
||||||
|
{ name: I18n.t("user.auto_track_options.never"), value: -1 },
|
||||||
|
{ name: I18n.t("user.auto_track_options.immediately"), value: 0 },
|
||||||
|
{
|
||||||
|
name: I18n.t("user.auto_track_options.after_30_seconds"),
|
||||||
|
value: 30000,
|
||||||
|
},
|
||||||
|
{ name: I18n.t("user.auto_track_options.after_1_minute"), value: 60000 },
|
||||||
|
{
|
||||||
|
name: I18n.t("user.auto_track_options.after_2_minutes"),
|
||||||
|
value: 120000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: I18n.t("user.auto_track_options.after_3_minutes"),
|
||||||
|
value: 180000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: I18n.t("user.auto_track_options.after_4_minutes"),
|
||||||
|
value: 240000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: I18n.t("user.auto_track_options.after_5_minutes"),
|
||||||
|
value: 300000,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: I18n.t("user.auto_track_options.after_10_minutes"),
|
||||||
|
value: 600000,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
notificationLevelsForReplying = [
|
||||||
|
{
|
||||||
|
name: I18n.t("topic.notifications.watching.title"),
|
||||||
|
value: NotificationLevels.WATCHING,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: I18n.t("topic.notifications.tracking.title"),
|
||||||
|
value: NotificationLevels.TRACKING,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: I18n.t("topic.notifications.regular.title"),
|
||||||
|
value: NotificationLevels.REGULAR,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
considerNewTopicOptions = [
|
||||||
|
{ name: I18n.t("user.new_topic_duration.not_viewed"), value: -1 },
|
||||||
|
{ name: I18n.t("user.new_topic_duration.after_1_day"), value: 60 * 24 },
|
||||||
|
{ name: I18n.t("user.new_topic_duration.after_2_days"), value: 60 * 48 },
|
||||||
|
{
|
||||||
|
name: I18n.t("user.new_topic_duration.after_1_week"),
|
||||||
|
value: 7 * 60 * 24,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: I18n.t("user.new_topic_duration.after_2_weeks"),
|
||||||
|
value: 2 * 7 * 60 * 24,
|
||||||
|
},
|
||||||
|
{ name: I18n.t("user.new_topic_duration.last_here"), value: -2 },
|
||||||
|
];
|
||||||
|
|
||||||
|
get canSee() {
|
||||||
|
return this.currentUser.id === this.model.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
@computed(
|
||||||
|
"model.watched_tags.[]",
|
||||||
|
"model.watching_first_post_tags.[]",
|
||||||
|
"model.tracked_tags.[]",
|
||||||
|
"model.muted_tags.[]"
|
||||||
|
)
|
||||||
|
get selectedTags() {
|
||||||
|
return []
|
||||||
|
.concat(
|
||||||
|
this.model.watched_tags,
|
||||||
|
this.model.watching_first_post_tags,
|
||||||
|
this.model.tracked_tags,
|
||||||
|
this.model.muted_tags
|
||||||
|
)
|
||||||
|
.filter((t) => t);
|
||||||
|
}
|
||||||
|
|
||||||
|
@computed(
|
||||||
|
"model.watchedCategories",
|
||||||
|
"model.watchedFirstPostCategories",
|
||||||
|
"model.trackedCategories",
|
||||||
|
"model.mutedCategories"
|
||||||
|
)
|
||||||
|
get selectedCategories() {
|
||||||
|
return []
|
||||||
|
.concat(
|
||||||
|
this.modelwatchedCategories,
|
||||||
|
this.model.watchedFirstPostCategories,
|
||||||
|
this.model.tracakedCategories,
|
||||||
|
this.model.mutedCategories
|
||||||
|
)
|
||||||
|
.filter((t) => t);
|
||||||
|
}
|
||||||
|
|
||||||
|
@computed("siteSettings.remove_muted_tags_from_latest")
|
||||||
|
get hideMutedTags() {
|
||||||
|
return this.siteSettings.remove_muted_tags_from_latest !== "never";
|
||||||
|
}
|
||||||
|
|
||||||
|
get canSave() {
|
||||||
|
return this.canSee || this.currentUser.admin;
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
save() {
|
||||||
|
this.saved = false;
|
||||||
|
|
||||||
|
return this.model
|
||||||
|
.save(this.saveAttrNames)
|
||||||
|
.then(() => {
|
||||||
|
this.saved = true;
|
||||||
|
})
|
||||||
|
.catch(popupAjaxError);
|
||||||
|
}
|
||||||
|
}
|
|
@ -51,6 +51,7 @@ export default Controller.extend({
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
|
|
||||||
this.saveAttrNames = [
|
this.saveAttrNames = [
|
||||||
|
"allow_private_messages",
|
||||||
"muted_usernames",
|
"muted_usernames",
|
||||||
"allowed_pm_usernames",
|
"allowed_pm_usernames",
|
||||||
"enable_allowed_pm_users",
|
"enable_allowed_pm_users",
|
||||||
|
@ -72,11 +73,6 @@ export default Controller.extend({
|
||||||
return !allowPrivateMessages;
|
return !allowPrivateMessages;
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed("currentUser.can_send_private_messages")
|
|
||||||
showMessageSettings() {
|
|
||||||
return this.currentUser?.can_send_private_messages;
|
|
||||||
},
|
|
||||||
|
|
||||||
@action
|
@action
|
||||||
save() {
|
save() {
|
||||||
this.set("saved", false);
|
this.set("saved", false);
|
||||||
|
|
|
@ -161,6 +161,7 @@ export default function () {
|
||||||
this.route("profile");
|
this.route("profile");
|
||||||
this.route("emails");
|
this.route("emails");
|
||||||
this.route("notifications");
|
this.route("notifications");
|
||||||
|
this.route("tracking");
|
||||||
this.route("categories");
|
this.route("categories");
|
||||||
this.route("users");
|
this.route("users");
|
||||||
this.route("tags");
|
this.route("tags");
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
import RestrictedUserRoute from "discourse/routes/restricted-user";
|
||||||
|
|
||||||
|
export default RestrictedUserRoute.extend({
|
||||||
|
showFooter: true,
|
||||||
|
});
|
|
@ -3,8 +3,7 @@
|
||||||
<div class="user-navigation user-navigation-secondary">
|
<div class="user-navigation user-navigation-secondary">
|
||||||
<HorizontalOverflowNav>
|
<HorizontalOverflowNav>
|
||||||
<UserNav::PreferencesNav
|
<UserNav::PreferencesNav
|
||||||
@user={{this.model}}
|
@currentUser={{this.currentUser}}
|
||||||
@viewingSelf={{this.viewingSelf}}
|
|
||||||
@model={{this.model}}
|
@model={{this.model}}
|
||||||
@siteSettings={{this.siteSettings}}/>
|
@siteSettings={{this.siteSettings}}/>
|
||||||
</HorizontalOverflowNav>
|
</HorizontalOverflowNav>
|
||||||
|
@ -79,6 +78,7 @@
|
||||||
</LinkTo>
|
</LinkTo>
|
||||||
</li>
|
</li>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
<PluginOutlet @name="user-preferences-nav" @tagName="span" @connectorTagName="li" @args={{hash model=this.model}} />
|
<PluginOutlet @name="user-preferences-nav" @tagName="span" @connectorTagName="li" @args={{hash model=this.model}} />
|
||||||
</MobileNav>
|
</MobileNav>
|
||||||
</DSection>
|
</DSection>
|
||||||
|
|
|
@ -1,28 +1,3 @@
|
||||||
{{#if this.model.userApiKeys}}
|
<UserPreferences::UserApiKeys @model={{@model}}/>
|
||||||
<div class="control-group apps">
|
|
||||||
<label class="control-label">{{i18n "user.apps"}}</label>
|
|
||||||
<div class="controls">
|
|
||||||
{{#each this.model.userApiKeys as |key|}}
|
|
||||||
<div>
|
|
||||||
<span>{{key.application_name}}</span>
|
|
||||||
{{#if key.revoked}}
|
|
||||||
<DButton @action={{route-action "undoRevokeApiKey"}} @actionParam={{key}} @class="btn" @label="user.undo_revoke_access" />
|
|
||||||
{{else}}
|
|
||||||
<DButton @action={{route-action "revokeApiKey"}} @actionParam={{key}} @class="btn" @label="user.revoke_access" />
|
|
||||||
{{/if}}
|
|
||||||
<p>
|
|
||||||
<ul>
|
|
||||||
{{#each key.scopes as |scope|}}
|
|
||||||
<li>{{scope}}</li>
|
|
||||||
{{/each}}
|
|
||||||
</ul>
|
|
||||||
</p>
|
|
||||||
<p><span>{{i18n "user.api_approved"}}</span> {{bound-date key.created_at}}</p>
|
|
||||||
<p><span>{{i18n "user.api_last_used_at"}}</span> {{bound-date key.last_used_at}}</p>
|
|
||||||
</div>
|
|
||||||
{{/each}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
<PluginOutlet @name="user-preferences-apps" @tagName="span" @connectorTagName="div" @args={{hash model=this.model}} />
|
<PluginOutlet @name="user-preferences-apps" @tagName="span" @connectorTagName="div" @args={{hash model=this.model}} />
|
||||||
|
|
|
@ -1,53 +1,10 @@
|
||||||
<div class="control-group category-notifications">
|
<UserPreferences::Categories
|
||||||
<label class="control-label">{{i18n "user.categories_settings"}}</label>
|
@canSee={{this.canSee}}
|
||||||
|
@model={{this.model}}
|
||||||
<div class="controls tracking-controls tracking-controls--watched-categories">
|
@selectedCategories={{this.selectedCategories}}
|
||||||
<label>{{d-icon "d-watching"}} {{i18n "user.watched_categories"}}</label>
|
@hideMutedTags={{this.hideMutedTags}}
|
||||||
{{#if this.canSee}}
|
@save={{action "save"}}
|
||||||
<a class="show-tracking" href={{this.model.watchingTopicsPath}}>{{i18n "user.tracked_topics_link"}}</a>
|
@siteSettings={{this.siteSettings}}/>
|
||||||
{{/if}}
|
|
||||||
<CategorySelector @categories={{this.model.watchedCategories}} @blockedCategories={{this.selectedCategories}} @onChange={{action (mut this.model.watchedCategories)}} />
|
|
||||||
</div>
|
|
||||||
<div class="instructions">{{i18n "user.watched_categories_instructions"}}</div>
|
|
||||||
|
|
||||||
<div class="controls tracking-controls tracking-controls--tracked-categories">
|
|
||||||
<label>{{d-icon "d-tracking"}} {{i18n "user.tracked_categories"}}</label>
|
|
||||||
{{#if this.canSee}}
|
|
||||||
<a class="show-tracking" href={{this.model.trackingTopicsPath}}>{{i18n "user.tracked_topics_link"}}</a>
|
|
||||||
{{/if}}
|
|
||||||
<CategorySelector @categories={{this.model.trackedCategories}} @blockedCategories={{this.selectedCategories}} @onChange={{action (mut this.model.trackedCategories)}} />
|
|
||||||
</div>
|
|
||||||
<div class="instructions">{{i18n "user.tracked_categories_instructions"}}</div>
|
|
||||||
|
|
||||||
<div class="controls tracking-controls tracking-controls--watched-first-categories">
|
|
||||||
<label>{{d-icon "d-watching-first"}} {{i18n "user.watched_first_post_categories"}}</label>
|
|
||||||
<CategorySelector @categories={{this.model.watchedFirstPostCategories}} @blockedCategories={{this.selectedCategories}} @onChange={{action (mut this.model.watchedFirstPostCategories)}} />
|
|
||||||
</div>
|
|
||||||
<div class="instructions">{{i18n "user.watched_first_post_categories_instructions"}}</div>
|
|
||||||
|
|
||||||
{{#if this.siteSettings.mute_all_categories_by_default}}
|
|
||||||
<div class="controls tracking-controls tracking-controls--regular-categories">
|
|
||||||
<label>{{d-icon "d-regular"}} {{i18n "user.regular_categories"}}</label>
|
|
||||||
<CategorySelector @categories={{this.model.regularCategories}} @blockedCategories={{this.selectedCategories}} @onChange={{action (mut this.model.regularCategories)}} />
|
|
||||||
</div>
|
|
||||||
<div class="instructions">{{i18n "user.regular_categories_instructions"}}</div>
|
|
||||||
{{else}}
|
|
||||||
<div class="controls tracking-controls tracking-controls--muted-categories">
|
|
||||||
<label>{{d-icon "d-muted"}} {{i18n "user.muted_categories"}}</label>
|
|
||||||
{{#if this.canSee}}
|
|
||||||
<a class="show-tracking" href={{this.model.mutedTopicsPath}}>{{i18n "user.tracked_topics_link"}}</a>
|
|
||||||
{{/if}}
|
|
||||||
<CategorySelector @categories={{this.model.mutedCategories}} @blockedCategories={{this.selectedCategories}} @onChange={{action (mut this.model.mutedCategories)}} />
|
|
||||||
</div>
|
|
||||||
<div class="instructions">{{i18n (if this.hideMutedTags "user.muted_categories_instructions" "user.muted_categories_instructions_dont_hide")}}</div>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<PluginOutlet @name="user-preferences-categories" @tagName="span" @connectorTagName="div" @args={{hash model=this.model save=(action "save")}} />
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<PluginOutlet @name="user-custom-controls" @tagName="span" @connectorTagName="div" @args={{hash model=this.model}} />
|
|
||||||
|
|
||||||
{{#if this.canSave}}
|
{{#if this.canSave}}
|
||||||
<SaveControls @model={{this.model}} @action={{action "save"}} @saved={{this.saved}} />
|
<SaveControls @model={{this.model}} @action={{action "save"}} @saved={{this.saved}} />
|
||||||
|
|
|
@ -1,20 +1,13 @@
|
||||||
<div class="control-group notifications">
|
<div class="control-group notifications">
|
||||||
<label class="control-label">{{i18n "user.notifications"}}</label>
|
<label class="control-label">{{i18n "user.notifications"}}</label>
|
||||||
|
|
||||||
<div class="controls controls-dropdown">
|
{{#unless this.currentUser.redesigned_user_page_nav_enabled}}
|
||||||
<label>{{i18n "user.new_topic_duration.label"}}</label>
|
<UserPreferences::TopicTracking
|
||||||
<ComboBox @class="duration" @valueProperty="value" @content={{this.considerNewTopicOptions}} @value={{this.model.user_option.new_topic_duration_minutes}} @onChange={{action (mut this.model.user_option.new_topic_duration_minutes)}} />
|
@considerNewTopicOptions={{this.considerNewTopicOptions}}
|
||||||
</div>
|
@model={{this.model}}
|
||||||
|
@autoTrackDurations={{this.autoTrackDurations}}
|
||||||
<div class="controls controls-dropdown">
|
@notificationLevelsForReplying={{this.notificationLevelsForReplying}} />
|
||||||
<label>{{i18n "user.auto_track_topics"}}</label>
|
{{/unless}}
|
||||||
<ComboBox @valueProperty="value" @content={{this.autoTrackDurations}} @value={{this.model.user_option.auto_track_topics_after_msecs}} @onChange={{action (mut this.model.user_option.auto_track_topics_after_msecs)}} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="controls controls-dropdown">
|
|
||||||
<label>{{i18n "user.notification_level_when_replying"}}</label>
|
|
||||||
<ComboBox @valueProperty="value" @content={{this.notificationLevelsForReplying}} @value={{this.model.user_option.notification_level_when_replying}} @onChange={{action (mut this.model.user_option.notification_level_when_replying)}} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="controls controls-dropdown">
|
<div class="controls controls-dropdown">
|
||||||
<label>{{i18n "user.like_notification_frequency.title"}}</label>
|
<label>{{i18n "user.like_notification_frequency.title"}}</label>
|
||||||
|
@ -34,13 +27,9 @@
|
||||||
<UserNotificationSchedule @model={{this.model}} />
|
<UserNotificationSchedule @model={{this.model}} />
|
||||||
|
|
||||||
{{#if this.showMessageSettings}}
|
{{#if this.showMessageSettings}}
|
||||||
<div class="control-group private-messages">
|
{{#unless this.currentUser.redesigned_user_page_nav_enabled}}
|
||||||
<label class="control-label">{{i18n "user.private_messages"}}</label>
|
<UserPreferences::AllowPrivateMessages @model={{this.model}} />
|
||||||
|
{{/unless}}
|
||||||
<div class="controls">
|
|
||||||
<PreferenceCheckbox @labelKey="user.allow_private_messages" @checked={{this.model.user_option.allow_private_messages}} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
<PluginOutlet @name="user-preferences-notifications" @tagName="span" @connectorTagName="div" @args={{hash model=this.model save=(action "save")}} />
|
<PluginOutlet @name="user-preferences-notifications" @tagName="span" @connectorTagName="div" @args={{hash model=this.model save=(action "save")}} />
|
||||||
|
|
|
@ -71,6 +71,10 @@
|
||||||
</div>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if this.currentUser.redesigned_user_page_nav_enabled}}
|
||||||
|
<UserPreferences::UserApiKeys @model={{@model}}/>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
<PluginOutlet @name="user-preferences-security" @tagName="span" @connectorTagName="div" @args={{hash model=this.model save=(action "save")}} />
|
<PluginOutlet @name="user-preferences-security" @tagName="span" @connectorTagName="div" @args={{hash model=this.model save=(action "save")}} />
|
||||||
|
|
||||||
<br>
|
<br>
|
||||||
|
|
|
@ -1,50 +1,7 @@
|
||||||
{{#if this.siteSettings.tagging_enabled}}
|
<UserPreferences::Tags
|
||||||
<div class="control-group tag-notifications">
|
@model={{this.model}}
|
||||||
<label class="control-label">{{i18n "user.tag_settings"}}</label>
|
@selectedTags={{this.selectedTags}}
|
||||||
|
@save={{action "save"}}
|
||||||
<div class="controls tracking-controls">
|
@siteSettings={{this.siteSettings}}/>
|
||||||
<label>{{d-icon "d-watching" class="icon watching"}} {{i18n "user.watched_tags"}}</label>
|
|
||||||
<TagChooser @tags={{this.model.watched_tags}} @blockedTags={{this.selectedTags}} @everyTag={{true}} @unlimitedTagCount={{true}} @options={{hash
|
|
||||||
allowAny=false
|
|
||||||
}} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="instructions">{{i18n "user.watched_tags_instructions"}}</div>
|
|
||||||
|
|
||||||
<div class="controls tracking-controls">
|
|
||||||
<label>{{d-icon "d-tracking" class="icon tracking"}} {{i18n "user.tracked_tags"}}</label>
|
|
||||||
<TagChooser @tags={{this.model.tracked_tags}} @blockedTags={{this.selectedTags}} @everyTag={{true}} @unlimitedTagCount={{true}} @options={{hash
|
|
||||||
allowAny=false
|
|
||||||
}} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="instructions">{{i18n "user.tracked_tags_instructions"}}</div>
|
|
||||||
|
|
||||||
<div class="controls tracking-controls">
|
|
||||||
<label>{{d-icon "d-watching-first" class="icon watching-first-post"}} {{i18n "user.watched_first_post_tags"}}</label>
|
|
||||||
<TagChooser @tags={{this.model.watching_first_post_tags}} @blockedTags={{this.selectedTags}} @everyTag={{true}} @unlimitedTagCount={{true}} @options={{hash
|
|
||||||
allowAny=false
|
|
||||||
}} />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="instructions">
|
|
||||||
{{i18n "user.watched_first_post_tags_instructions"}}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="controls tracking-controls">
|
|
||||||
<label>{{d-icon "d-muted" class="icon muted"}} {{i18n "user.muted_tags"}}</label>
|
|
||||||
<TagChooser @tags={{this.model.muted_tags}} @blockedTags={{this.selectedTags}} @everyTag={{true}} @unlimitedTagCount={{true}} @options={{hash
|
|
||||||
allowAny=false
|
|
||||||
}} />
|
|
||||||
</div>
|
|
||||||
<div class="instructions">{{i18n "user.muted_tags_instructions"}}</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<PluginOutlet @name="user-preferences-tags" @tagName="span" @connectorTagName="div" @args={{hash model=this.model save=(action "save")}} />
|
|
||||||
|
|
||||||
<br>
|
|
||||||
|
|
||||||
<PluginOutlet @name="user-custom-controls" @tagName="span" @connectorTagName="div" @args={{hash model=this.model}} />
|
|
||||||
|
|
||||||
<SaveControls @model={{this.model}} @action={{action "save"}} @saved={{this.saved}} />
|
<SaveControls @model={{this.model}} @action={{action "save"}} @saved={{this.saved}} />
|
||||||
{{/if}}
|
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
<DSection @pageClass="user-preferences-tracking" />
|
||||||
|
|
||||||
|
<div class="user-preferences_tracking-topics-wrapper">
|
||||||
|
<label class="control-label">{{i18n "user.topics_settings"}}</label>
|
||||||
|
<UserPreferences::TopicTracking
|
||||||
|
@considerNewTopicOptions={{this.considerNewTopicOptions}}
|
||||||
|
@model={{this.model}}
|
||||||
|
@autoTrackDurations={{this.autoTrackDurations}}
|
||||||
|
@notificationLevelsForReplying={{this.notificationLevelsForReplying}} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="user-preferences_tracking-categories-tags-wrapper">
|
||||||
|
<UserPreferences::Categories
|
||||||
|
@canSee={{this.canSee}}
|
||||||
|
@model={{this.model}}
|
||||||
|
@selectedCategories={{this.selectedCategories}}
|
||||||
|
@hideMutedTags={{this.hideMutedTags}}
|
||||||
|
@siteSettings={{this.siteSettings}} />
|
||||||
|
|
||||||
|
<UserPreferences::Tags
|
||||||
|
@model={{this.model}}
|
||||||
|
@selectedTags={{this.selectedTags}}
|
||||||
|
@save={{this.save}}
|
||||||
|
@siteSettings={{this.siteSettings}} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{#if this.canSave}}
|
||||||
|
<SaveControls @model={{this.model}} @action={{this.save}} @saved={{this.saved}} />
|
||||||
|
{{/if}}
|
|
@ -21,7 +21,11 @@
|
||||||
<div class="instructions">{{i18n "user.muted_users_instructions"}}</div>
|
<div class="instructions">{{i18n "user.muted_users_instructions"}}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#if this.showMessageSettings}}
|
{{#if this.currentUser.can_send_private_messages}}
|
||||||
|
{{#if this.currentUser.redesigned_user_page_nav_enabled}}
|
||||||
|
<UserPreferences::AllowPrivateMessages @model={{this.model}} />
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
<div class="control-group user-allow-pm">
|
<div class="control-group user-allow-pm">
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<PreferenceCheckbox @labelKey="user.allow_private_messages_from_specific_users" @checked={{this.model.user_option.enable_allowed_pm_users}} @disabled={{this.disableAllowPmUsersSetting}} />
|
<PreferenceCheckbox @labelKey="user.allow_private_messages_from_specific_users" @checked={{this.model.user_option.enable_allowed_pm_users}} @disabled={{this.disableAllowPmUsersSetting}} />
|
||||||
|
|
|
@ -91,6 +91,7 @@ acceptance("User Preferences", function (needs) {
|
||||||
"/u/eviltrout/preferences/account",
|
"/u/eviltrout/preferences/account",
|
||||||
"defaults to account tab"
|
"defaults to account tab"
|
||||||
);
|
);
|
||||||
|
|
||||||
assert.ok(exists(".user-preferences"), "it shows the preferences");
|
assert.ok(exists(".user-preferences"), "it shows the preferences");
|
||||||
|
|
||||||
const savePreferences = async () => {
|
const savePreferences = async () => {
|
||||||
|
@ -112,25 +113,32 @@ acceptance("User Preferences", function (needs) {
|
||||||
await savePreferences();
|
await savePreferences();
|
||||||
|
|
||||||
await click(".preferences-nav .nav-notifications a");
|
await click(".preferences-nav .nav-notifications a");
|
||||||
|
|
||||||
await selectKit(
|
await selectKit(
|
||||||
".control-group.notifications .combo-box.duration"
|
".control-group.notifications .combo-box.duration"
|
||||||
).expand();
|
).expand();
|
||||||
|
|
||||||
await selectKit(
|
await selectKit(
|
||||||
".control-group.notifications .combo-box.duration"
|
".control-group.notifications .combo-box.duration"
|
||||||
).selectRowByValue(1440);
|
).selectRowByValue(1440);
|
||||||
|
|
||||||
await savePreferences();
|
await savePreferences();
|
||||||
|
|
||||||
await click(".preferences-nav .nav-categories a");
|
await click(".preferences-nav .nav-categories a");
|
||||||
|
|
||||||
const categorySelector = selectKit(
|
const categorySelector = selectKit(
|
||||||
".tracking-controls .category-selector "
|
".tracking-controls .category-selector "
|
||||||
);
|
);
|
||||||
|
|
||||||
await categorySelector.expand();
|
await categorySelector.expand();
|
||||||
await categorySelector.fillInFilter("faq");
|
await categorySelector.fillInFilter("faq");
|
||||||
await savePreferences();
|
await savePreferences();
|
||||||
|
|
||||||
this.siteSettings.tagging_enabled = false;
|
this.siteSettings.tagging_enabled = false;
|
||||||
|
|
||||||
await visit("/");
|
await visit("/");
|
||||||
await visit("/u/eviltrout/preferences");
|
await visit("/u/eviltrout/preferences");
|
||||||
|
|
||||||
assert.ok(
|
assert.ok(
|
||||||
!exists(".preferences-nav .nav-tags a"),
|
!exists(".preferences-nav .nav-tags a"),
|
||||||
"tags tab isn't there when tags are disabled"
|
"tags tab isn't there when tags are disabled"
|
||||||
|
@ -564,7 +572,7 @@ acceptance("Ignored users", function (needs) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
acceptance("Security", function (needs) {
|
acceptance("User Preferences - Security", function (needs) {
|
||||||
needs.user();
|
needs.user();
|
||||||
needs.pretender(preferencesPretender);
|
needs.pretender(preferencesPretender);
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
import { acceptance, exists } from "discourse/tests/helpers/qunit-helpers";
|
||||||
|
import { click, visit } from "@ember/test-helpers";
|
||||||
|
import { test } from "qunit";
|
||||||
|
import selectKit from "discourse/tests/helpers/select-kit-helper";
|
||||||
|
|
||||||
|
acceptance(
|
||||||
|
"New User Menu - Horizontal nav and preferences relocation",
|
||||||
|
function (needs) {
|
||||||
|
needs.user({
|
||||||
|
redesigned_user_page_nav_enabled: true,
|
||||||
|
user_api_keys: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
application_name: "Discourse Hub",
|
||||||
|
scopes: ["Read and clear notifications"],
|
||||||
|
created_at: "2020-11-14T00:57:09.093Z",
|
||||||
|
last_used_at: "2022-09-22T18:55:41.672Z",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Horizontal user nav exists", async function (assert) {
|
||||||
|
await visit("/u/eviltrout/preferences");
|
||||||
|
assert.ok(exists(".horizontal-overflow-nav"), "horizontal nav exists");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("User Tracking page exists", async function (assert) {
|
||||||
|
await visit("/u/eviltrout/preferences");
|
||||||
|
assert.ok(exists(".nav-tracking"), "the new tracking page link exists");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("User Categories page no longer exists", async function (assert) {
|
||||||
|
await visit("/u/eviltrout/preferences");
|
||||||
|
assert.ok(!exists(".nav-categories"), "Categories tab no longer exists");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Can save category tracking preferences", async function (assert) {
|
||||||
|
await visit("/u/eviltrout/preferences/tracking");
|
||||||
|
|
||||||
|
const categorySelector = selectKit(
|
||||||
|
".tracking-controls .category-selector"
|
||||||
|
);
|
||||||
|
|
||||||
|
const savePreferences = async () => {
|
||||||
|
assert.notOk(exists(".saved"), "it hasn't been saved yet");
|
||||||
|
await click(".save-changes");
|
||||||
|
assert.ok(exists(".saved"), "it displays the saved message");
|
||||||
|
};
|
||||||
|
|
||||||
|
await categorySelector.expand();
|
||||||
|
await categorySelector.fillInFilter("faq");
|
||||||
|
await savePreferences();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("Can view user api keys on security page", async function (assert) {
|
||||||
|
await visit("/u/eviltrout/preferences/security");
|
||||||
|
assert.ok(exists(".control-group.apps"), "User can see apps section");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
|
@ -184,3 +184,26 @@
|
||||||
margin: 1em 0;
|
margin: 1em 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.user-preferences-tracking-page {
|
||||||
|
.user-preferences .form-vertical {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-preferences_tracking-topics-wrapper {
|
||||||
|
margin-bottom: 3em;
|
||||||
|
.control-label {
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-preferences_tracking-categories-tags-wrapper {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(16em, 1fr));
|
||||||
|
gap: 2em;
|
||||||
|
.control-group {
|
||||||
|
width: 100%;
|
||||||
|
min-width: 16em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1326,6 +1326,7 @@ en:
|
||||||
profile: "Profile"
|
profile: "Profile"
|
||||||
emails: "Emails"
|
emails: "Emails"
|
||||||
notifications: "Notifications"
|
notifications: "Notifications"
|
||||||
|
tracking: "Tracking"
|
||||||
categories: "Categories"
|
categories: "Categories"
|
||||||
users: "Users"
|
users: "Users"
|
||||||
tags: "Tags"
|
tags: "Tags"
|
||||||
|
@ -1604,6 +1605,7 @@ en:
|
||||||
|
|
||||||
other_settings: "Other"
|
other_settings: "Other"
|
||||||
categories_settings: "Categories"
|
categories_settings: "Categories"
|
||||||
|
topics_settings: "Topics"
|
||||||
|
|
||||||
new_topic_duration:
|
new_topic_duration:
|
||||||
label: "Consider topics new when"
|
label: "Consider topics new when"
|
||||||
|
|
|
@ -494,6 +494,7 @@ Discourse::Application.routes.draw do
|
||||||
put "#{root_path}/:username/preferences/primary-email" => "users#update_primary_email", format: :json, constraints: { username: RouteFormat.username }
|
put "#{root_path}/:username/preferences/primary-email" => "users#update_primary_email", format: :json, constraints: { username: RouteFormat.username }
|
||||||
delete "#{root_path}/:username/preferences/email" => "users#destroy_email", constraints: { username: RouteFormat.username }
|
delete "#{root_path}/:username/preferences/email" => "users#destroy_email", constraints: { username: RouteFormat.username }
|
||||||
get "#{root_path}/:username/preferences/notifications" => "users#preferences", constraints: { username: RouteFormat.username }
|
get "#{root_path}/:username/preferences/notifications" => "users#preferences", constraints: { username: RouteFormat.username }
|
||||||
|
get "#{root_path}/:username/preferences/tracking" => "users#preferences", constraints: { username: RouteFormat.username }
|
||||||
get "#{root_path}/:username/preferences/categories" => "users#preferences", constraints: { username: RouteFormat.username }
|
get "#{root_path}/:username/preferences/categories" => "users#preferences", constraints: { username: RouteFormat.username }
|
||||||
get "#{root_path}/:username/preferences/users" => "users#preferences", constraints: { username: RouteFormat.username }
|
get "#{root_path}/:username/preferences/users" => "users#preferences", constraints: { username: RouteFormat.username }
|
||||||
get "#{root_path}/:username/preferences/tags" => "users#preferences", constraints: { username: RouteFormat.username }
|
get "#{root_path}/:username/preferences/tags" => "users#preferences", constraints: { username: RouteFormat.username }
|
||||||
|
|
Loading…
Reference in New Issue