mirror of
https://github.com/discourse/discourse.git
synced 2025-02-09 21:04:48 +00:00
FEATURE: settings tab for permalinks (#30192)
Setting tab should be added to permalinks so admins do not need to have left `/permalinks`. A new component called `AreaSetting` was added to avoid duplications and simplify adding settings to other sections.
This commit is contained in:
parent
4305b64460
commit
fdb6634fa9
@ -0,0 +1,69 @@
|
|||||||
|
import Component from "@glimmer/component";
|
||||||
|
import { tracked } from "@glimmer/tracking";
|
||||||
|
import { action } from "@ember/object";
|
||||||
|
import { service } from "@ember/service";
|
||||||
|
import DBreadcrumbsItem from "discourse/components/d-breadcrumbs-item";
|
||||||
|
import { ajax } from "discourse/lib/ajax";
|
||||||
|
import { bind } from "discourse-common/utils/decorators";
|
||||||
|
import { i18n } from "discourse-i18n";
|
||||||
|
import AdminConfigAreaEmptyList from "admin/components/admin-config-area-empty-list";
|
||||||
|
import AdminFilteredSiteSettings from "admin/components/admin-filtered-site-settings";
|
||||||
|
import SiteSetting from "admin/models/site-setting";
|
||||||
|
|
||||||
|
export default class AdminAreaSettings extends Component {
|
||||||
|
@service siteSettings;
|
||||||
|
@service router;
|
||||||
|
@tracked settings = [];
|
||||||
|
@tracked filter = "";
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super(...arguments);
|
||||||
|
this.#loadSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
@bind
|
||||||
|
async #loadSettings() {
|
||||||
|
this.filter = this.args.filter;
|
||||||
|
const result = await ajax("/admin/config/site_settings.json", {
|
||||||
|
data: {
|
||||||
|
filter_area: this.args.area,
|
||||||
|
plugin: this.args.plugin,
|
||||||
|
categories: this.args.categories,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
this.settings = [
|
||||||
|
{
|
||||||
|
name: "All",
|
||||||
|
nameKey: "all_results",
|
||||||
|
siteSettings: result.site_settings.map((setting) =>
|
||||||
|
SiteSetting.create(setting)
|
||||||
|
),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
@action
|
||||||
|
adminSettingsFilterChangedCallback(filterData) {
|
||||||
|
this.args.adminSettingsFilterChangedCallback(filterData.filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<DBreadcrumbsItem @path={{@path}} @label={{i18n "settings"}} />
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="content-body admin-config-area__settings admin-detail pull-left"
|
||||||
|
>
|
||||||
|
{{#if this.settings}}
|
||||||
|
<AdminFilteredSiteSettings
|
||||||
|
@initialFilter={{this.filter}}
|
||||||
|
@onFilterChanged={{this.adminSettingsFilterChangedCallback}}
|
||||||
|
@settings={{this.settings}}
|
||||||
|
/>
|
||||||
|
{{else}}
|
||||||
|
<AdminConfigAreaEmptyList
|
||||||
|
@emptyLabelTranslated={{i18n "admin.settings.not_found"}}
|
||||||
|
/>
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
}
|
@ -1,54 +0,0 @@
|
|||||||
import Component from "@glimmer/component";
|
|
||||||
import { tracked } from "@glimmer/tracking";
|
|
||||||
import didInsert from "@ember/render-modifiers/modifiers/did-insert";
|
|
||||||
import { service } from "@ember/service";
|
|
||||||
import DBreadcrumbsItem from "discourse/components/d-breadcrumbs-item";
|
|
||||||
import { ajax } from "discourse/lib/ajax";
|
|
||||||
import { bind } from "discourse-common/utils/decorators";
|
|
||||||
import { i18n } from "discourse-i18n";
|
|
||||||
import AdminFilteredSiteSettings from "admin/components/admin-filtered-site-settings";
|
|
||||||
import SiteSetting from "admin/models/site-setting";
|
|
||||||
|
|
||||||
export default class AdminConfigAreasEmojisSettings extends Component {
|
|
||||||
@service siteSettings;
|
|
||||||
@tracked settings;
|
|
||||||
|
|
||||||
@bind
|
|
||||||
loadSettings() {
|
|
||||||
ajax("/admin/config/site_settings.json", {
|
|
||||||
data: {
|
|
||||||
filter_area: "emojis",
|
|
||||||
},
|
|
||||||
}).then((result) => {
|
|
||||||
this.settings = [
|
|
||||||
{
|
|
||||||
name: "All",
|
|
||||||
nameKey: "all_results",
|
|
||||||
siteSettings: result.site_settings.map((setting) =>
|
|
||||||
SiteSetting.create(setting)
|
|
||||||
),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<DBreadcrumbsItem
|
|
||||||
@path="/admin/customize/emojis/settings"
|
|
||||||
@label={{i18n "settings"}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="content-body admin-config-area__settings admin-detail pull-left"
|
|
||||||
{{didInsert this.loadSettings}}
|
|
||||||
>
|
|
||||||
{{#if this.settings}}
|
|
||||||
<AdminFilteredSiteSettings
|
|
||||||
@initialFilter={{@initialFilter}}
|
|
||||||
@onFilterChanged={{@onFilterChanged}}
|
|
||||||
@settings={{this.settings}}
|
|
||||||
/>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
}
|
|
@ -1,54 +0,0 @@
|
|||||||
import Component from "@glimmer/component";
|
|
||||||
import { tracked } from "@glimmer/tracking";
|
|
||||||
import didInsert from "@ember/render-modifiers/modifiers/did-insert";
|
|
||||||
import { service } from "@ember/service";
|
|
||||||
import DBreadcrumbsItem from "discourse/components/d-breadcrumbs-item";
|
|
||||||
import { ajax } from "discourse/lib/ajax";
|
|
||||||
import { bind } from "discourse-common/utils/decorators";
|
|
||||||
import { i18n } from "discourse-i18n";
|
|
||||||
import AdminFilteredSiteSettings from "admin/components/admin-filtered-site-settings";
|
|
||||||
import SiteSetting from "admin/models/site-setting";
|
|
||||||
|
|
||||||
export default class AdminConfigAreasFlagsSettings extends Component {
|
|
||||||
@service siteSettings;
|
|
||||||
@tracked settings;
|
|
||||||
|
|
||||||
@bind
|
|
||||||
loadSettings() {
|
|
||||||
ajax("/admin/config/site_settings.json", {
|
|
||||||
data: {
|
|
||||||
filter_area: "flags",
|
|
||||||
},
|
|
||||||
}).then((result) => {
|
|
||||||
this.settings = [
|
|
||||||
{
|
|
||||||
name: "All",
|
|
||||||
nameKey: "all_results",
|
|
||||||
siteSettings: result.site_settings.map((setting) =>
|
|
||||||
SiteSetting.create(setting)
|
|
||||||
),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<DBreadcrumbsItem
|
|
||||||
@path="/admin/config/flags/settings"
|
|
||||||
@label={{i18n "settings"}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="content-body admin-config-area__settings admin-detail pull-left"
|
|
||||||
{{didInsert this.loadSettings}}
|
|
||||||
>
|
|
||||||
{{#if this.settings}}
|
|
||||||
<AdminFilteredSiteSettings
|
|
||||||
@initialFilter={{@initialFilter}}
|
|
||||||
@onFilterChanged={{@onFilterChanged}}
|
|
||||||
@settings={{this.settings}}
|
|
||||||
/>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
}
|
|
@ -0,0 +1,13 @@
|
|||||||
|
import { tracked } from "@glimmer/tracking";
|
||||||
|
import Controller from "@ember/controller";
|
||||||
|
import { action } from "@ember/object";
|
||||||
|
|
||||||
|
export default class AdminAreaSettingsBaseController extends Controller {
|
||||||
|
@tracked filter = "";
|
||||||
|
queryParams = ["filter"];
|
||||||
|
|
||||||
|
@action
|
||||||
|
adminSettingsFilterChangedCallback(filter) {
|
||||||
|
this.filter = filter;
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,3 @@
|
|||||||
import Controller from "@ember/controller";
|
import AdminAreaSettingsBaseController from "admin/controllers/admin-area-settings-base";
|
||||||
import { action } from "@ember/object";
|
|
||||||
|
|
||||||
export default class AdminBackupsSettingsController extends Controller {
|
export default class AdminBackupsSettingsController extends AdminAreaSettingsBaseController {}
|
||||||
filter = "";
|
|
||||||
|
|
||||||
@action
|
|
||||||
filterChanged(filterData) {
|
|
||||||
this.set("filter", filterData.filter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,12 +1,3 @@
|
|||||||
import Controller from "@ember/controller";
|
import AdminAreaSettingsBaseController from "admin/controllers/admin-area-settings-base";
|
||||||
import { action } from "@ember/object";
|
|
||||||
|
|
||||||
export default class AdminConfigFlagsSettingsController extends Controller {
|
export default class AdminConfigFlagsSettingsController extends AdminAreaSettingsBaseController {}
|
||||||
filter = "";
|
|
||||||
queryParams = ["filter"];
|
|
||||||
|
|
||||||
@action
|
|
||||||
filterChangedCallback(filterData) {
|
|
||||||
this.set("filter", filterData.filter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,12 +1,3 @@
|
|||||||
import Controller from "@ember/controller";
|
import AdminAreaSettingsBaseController from "admin/controllers/admin-area-settings-base";
|
||||||
import { action } from "@ember/object";
|
|
||||||
|
|
||||||
export default class AdminEmojisSettingsController extends Controller {
|
export default class AdminEmojisSettingsController extends AdminAreaSettingsBaseController {}
|
||||||
filter = "";
|
|
||||||
queryParams = ["filter"];
|
|
||||||
|
|
||||||
@action
|
|
||||||
filterChangedCallback(filterData) {
|
|
||||||
this.set("filter", filterData.filter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
import AdminAreaSettingsBaseController from "admin/controllers/admin-area-settings-base";
|
||||||
|
|
||||||
|
export default class AdminPermalinksSettingsController extends AdminAreaSettingsBaseController {}
|
@ -1,11 +1,3 @@
|
|||||||
import Controller from "@ember/controller";
|
import AdminAreaSettingsBaseController from "admin/controllers/admin-area-settings-base";
|
||||||
import { action } from "@ember/object";
|
|
||||||
|
|
||||||
export default class AdminPluginsShowSettingsController extends Controller {
|
export default class AdminPluginsShowSettingsController extends AdminAreaSettingsBaseController {}
|
||||||
filter = "";
|
|
||||||
|
|
||||||
@action
|
|
||||||
filterChanged(filterData) {
|
|
||||||
this.set("filter", filterData.filter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,20 +1,8 @@
|
|||||||
import DiscourseRoute from "discourse/routes/discourse";
|
import DiscourseRoute from "discourse/routes/discourse";
|
||||||
import { i18n } from "discourse-i18n";
|
import { i18n } from "discourse-i18n";
|
||||||
import SiteSetting from "admin/models/site-setting";
|
|
||||||
|
|
||||||
export default class AdminBackupsSettingsRoute extends DiscourseRoute {
|
export default class AdminBackupsSettingsRoute extends DiscourseRoute {
|
||||||
queryParams = {
|
|
||||||
filter: { replace: true },
|
|
||||||
};
|
|
||||||
|
|
||||||
titleToken() {
|
titleToken() {
|
||||||
return i18n("admin.backups.settings");
|
return i18n("admin.backups.settings");
|
||||||
}
|
}
|
||||||
|
|
||||||
async model(params) {
|
|
||||||
return {
|
|
||||||
settings: await SiteSetting.findAll({ categories: ["backups"] }),
|
|
||||||
initialFilter: params.filter,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,6 @@ import DiscourseRoute from "discourse/routes/discourse";
|
|||||||
import { i18n } from "discourse-i18n";
|
import { i18n } from "discourse-i18n";
|
||||||
|
|
||||||
export default class AdminEmojisSettingsRoute extends DiscourseRoute {
|
export default class AdminEmojisSettingsRoute extends DiscourseRoute {
|
||||||
queryParams = {
|
|
||||||
filter: { replace: true },
|
|
||||||
};
|
|
||||||
|
|
||||||
titleToken() {
|
titleToken() {
|
||||||
return i18n("settings");
|
return i18n("settings");
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { service } from "@ember/service";
|
import { service } from "@ember/service";
|
||||||
import DiscourseRoute from "discourse/routes/discourse";
|
import DiscourseRoute from "discourse/routes/discourse";
|
||||||
import { i18n } from "discourse-i18n";
|
import { i18n } from "discourse-i18n";
|
||||||
import SiteSetting from "admin/models/site-setting";
|
|
||||||
|
|
||||||
export default class AdminPluginsShowSettingsRoute extends DiscourseRoute {
|
export default class AdminPluginsShowSettingsRoute extends DiscourseRoute {
|
||||||
@service router;
|
@service router;
|
||||||
@ -14,7 +13,6 @@ export default class AdminPluginsShowSettingsRoute extends DiscourseRoute {
|
|||||||
const plugin = this.modelFor("adminPlugins.show");
|
const plugin = this.modelFor("adminPlugins.show");
|
||||||
return {
|
return {
|
||||||
plugin,
|
plugin,
|
||||||
settings: await SiteSetting.findAll({ plugin: plugin.name }),
|
|
||||||
initialFilter: params.filter,
|
initialFilter: params.filter,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -91,6 +91,8 @@ export default function () {
|
|||||||
{ path: "/permalinks", resetNamespace: true },
|
{ path: "/permalinks", resetNamespace: true },
|
||||||
function () {
|
function () {
|
||||||
this.route("new");
|
this.route("new");
|
||||||
|
this.route("index", { path: "/" });
|
||||||
|
this.route("settings");
|
||||||
this.route("edit", { path: "/:permalink_id" });
|
this.route("edit", { path: "/:permalink_id" });
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
<DBreadcrumbsItem @path="/admin/backups/settings" @label={{i18n "settings"}} />
|
<AdminAreaSettings
|
||||||
|
@categories="backups"
|
||||||
<div class="content-body admin-config-area__settings admin-detail pull-left">
|
@path="/admin/backups/settings"
|
||||||
<AdminFilteredSiteSettings
|
@filter={{this.filter}}
|
||||||
@initialFilter={{@model.initialFilter}}
|
@adminSettingsFilterChangedCallback={{this.adminSettingsFilterChangedCallback}}
|
||||||
@settings={{@model.settings}}
|
/>
|
||||||
@onFilterChanged={{this.filterChanged}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
@ -1,5 +1,6 @@
|
|||||||
<AdminConfigAreas::FlagsSettings
|
<AdminAreaSettings
|
||||||
@model={{this.model}}
|
@area="flags"
|
||||||
@onFilterChanged={{this.filterChangedCallback}}
|
@path="/admin/config/flags/settings"
|
||||||
@initialFilter={{this.filter}}
|
@filter={{this.filter}}
|
||||||
|
@adminSettingsFilterChangedCallback={{this.adminSettingsFilterChangedCallback}}
|
||||||
/>
|
/>
|
@ -1,4 +1,6 @@
|
|||||||
<AdminConfigAreas::EmojisSettings
|
<AdminAreaSettings
|
||||||
@onFilterChanged={{this.filterChangedCallback}}
|
@area="emojis"
|
||||||
@initialFilter={{this.filter}}
|
@path="/admin/customize/emojis/settings"
|
||||||
|
@filter={{this.filter}}
|
||||||
|
@adminSettingsFilterChangedCallback={{this.adminSettingsFilterChangedCallback}}
|
||||||
/>
|
/>
|
@ -1,138 +1,112 @@
|
|||||||
<div class="admin-permalinks admin-config-page">
|
<ConditionalLoadingSpinner @condition={{this.loading}}>
|
||||||
<DPageHeader
|
<div class="d-admin-filter">
|
||||||
@titleLabel={{i18n "admin.permalink.title"}}
|
<div class="admin-filter__input-container permalink-search">
|
||||||
@descriptionLabel={{i18n "admin.permalink.description"}}
|
<TextField
|
||||||
@learnMoreUrl="https://meta.discourse.org/t/redirect-old-forum-urls-to-new-discourse-urls/20930"
|
@value={{this.filter}}
|
||||||
>
|
@placeholderKey="admin.permalink.form.filter"
|
||||||
<:breadcrumbs>
|
@autocorrect="off"
|
||||||
<DBreadcrumbsItem @path="/admin" @label={{i18n "admin_title"}} />
|
@autocapitalize="off"
|
||||||
<DBreadcrumbsItem
|
class="admin-filter__input"
|
||||||
@path="/admin/customize/permalinks"
|
|
||||||
@label={{i18n "admin.permalink.title"}}
|
|
||||||
/>
|
/>
|
||||||
</:breadcrumbs>
|
</div>
|
||||||
<:actions as |actions|>
|
|
||||||
<actions.Primary
|
|
||||||
@route="adminPermalinks.new"
|
|
||||||
@title="admin.permalink.add"
|
|
||||||
@label="admin.permalink.add"
|
|
||||||
@icon="plus"
|
|
||||||
class="admin-permalinks__header-add-permalink"
|
|
||||||
/>
|
|
||||||
</:actions>
|
|
||||||
</DPageHeader>
|
|
||||||
<div class="admin-container admin-config-page__main-area">
|
|
||||||
<ConditionalLoadingSpinner @condition={{this.loading}}>
|
|
||||||
<div class="permalink-search">
|
|
||||||
<TextField
|
|
||||||
@value={{this.filter}}
|
|
||||||
@placeholderKey="admin.permalink.form.filter"
|
|
||||||
@autocorrect="off"
|
|
||||||
@autocapitalize="off"
|
|
||||||
class="url-input"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="permalink-results">
|
|
||||||
{{#if this.model.length}}
|
|
||||||
<table class="d-admin-table permalinks">
|
|
||||||
<thead>
|
|
||||||
<th>{{i18n "admin.permalink.url"}}</th>
|
|
||||||
<th>{{i18n "admin.permalink.destination"}}</th>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
{{#each this.model as |pl|}}
|
|
||||||
<tr
|
|
||||||
class={{concat-class
|
|
||||||
"admin-permalink-item d-admin-row__content"
|
|
||||||
pl.key
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<td class="d-admin-row__overview">
|
|
||||||
<FlatButton
|
|
||||||
@title="admin.permalink.copy_to_clipboard"
|
|
||||||
@icon="far-clipboard"
|
|
||||||
@action={{fn this.copyUrl pl}}
|
|
||||||
/>
|
|
||||||
<span
|
|
||||||
id="admin-permalink-{{pl.id}}"
|
|
||||||
class="admin-permalink-item__url"
|
|
||||||
title={{pl.url}}
|
|
||||||
>{{pl.url}}</span>
|
|
||||||
</td>
|
|
||||||
<td class="d-admin-row__detail destination">
|
|
||||||
{{#if pl.topic_id}}
|
|
||||||
<a href={{pl.topic_url}}>{{pl.topic_title}}</a>
|
|
||||||
{{/if}}
|
|
||||||
{{#if pl.post_id}}
|
|
||||||
<a href={{pl.post_url}}>{{pl.post_topic_title}}
|
|
||||||
#{{pl.post_number}}</a>
|
|
||||||
{{/if}}
|
|
||||||
{{#if pl.category_id}}
|
|
||||||
{{category-link pl.category}}
|
|
||||||
{{/if}}
|
|
||||||
{{#if pl.tag_id}}
|
|
||||||
<a href={{pl.tag_url}}>{{pl.tag_name}}</a>
|
|
||||||
{{/if}}
|
|
||||||
{{#if pl.external_url}}
|
|
||||||
{{#if pl.linkIsExternal}}
|
|
||||||
{{d-icon "up-right-from-square"}}
|
|
||||||
{{/if}}
|
|
||||||
<a href={{pl.external_url}}>{{pl.external_url}}</a>
|
|
||||||
{{/if}}
|
|
||||||
{{#if pl.user_id}}
|
|
||||||
<a href={{pl.user_url}}>{{pl.username}}</a>
|
|
||||||
{{/if}}
|
|
||||||
</td>
|
|
||||||
<td class="d-admin-row__controls">
|
|
||||||
<div class="d-admin-row__controls-options">
|
|
||||||
<DButton
|
|
||||||
class="btn-small admin-permalink-item__edit"
|
|
||||||
@route="adminPermalinks.edit"
|
|
||||||
@routeModels={{pl}}
|
|
||||||
@label="admin.config_areas.flags.edit"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<DMenu
|
|
||||||
@identifier="permalink-menu"
|
|
||||||
@title={{i18n "admin.permalinks.more_options"}}
|
|
||||||
@icon="ellipsis-vertical"
|
|
||||||
@onRegisterApi={{this.onRegisterApi}}
|
|
||||||
>
|
|
||||||
<:content>
|
|
||||||
<DropdownMenu as |dropdown|>
|
|
||||||
<dropdown.item>
|
|
||||||
<DButton
|
|
||||||
@action={{fn this.destroyRecord pl}}
|
|
||||||
@icon="trash-can"
|
|
||||||
class="btn-transparent admin-permalink-item__delete"
|
|
||||||
@label="admin.config_areas.flags.delete"
|
|
||||||
/>
|
|
||||||
</dropdown.item>
|
|
||||||
</DropdownMenu>
|
|
||||||
</:content>
|
|
||||||
</DMenu>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
{{/each}}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
{{else}}
|
|
||||||
{{#if this.filter}}
|
|
||||||
<p class="permalink-results__no-result">{{i18n
|
|
||||||
"search.no_results"
|
|
||||||
}}</p>
|
|
||||||
{{else}}
|
|
||||||
<AdminConfigAreaEmptyList
|
|
||||||
@ctaLabel="admin.permalink.add"
|
|
||||||
@ctaRoute="adminPermalinks.new"
|
|
||||||
@ctaClass="admin-permalinks__add-permalink"
|
|
||||||
@emptyLabel="admin.permalink.no_permalinks"
|
|
||||||
/>
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
</ConditionalLoadingSpinner>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
<div class="permalink-results">
|
||||||
|
{{#if this.model.length}}
|
||||||
|
<table class="d-admin-table permalinks">
|
||||||
|
<thead>
|
||||||
|
<th>{{i18n "admin.permalink.url"}}</th>
|
||||||
|
<th>{{i18n "admin.permalink.destination"}}</th>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{{#each this.model as |pl|}}
|
||||||
|
<tr
|
||||||
|
class={{concat-class
|
||||||
|
"admin-permalink-item d-admin-row__content"
|
||||||
|
pl.key
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<td class="d-admin-row__overview">
|
||||||
|
<FlatButton
|
||||||
|
@title="admin.permalink.copy_to_clipboard"
|
||||||
|
@icon="far-clipboard"
|
||||||
|
@action={{fn this.copyUrl pl}}
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
id="admin-permalink-{{pl.id}}"
|
||||||
|
class="admin-permalink-item__url"
|
||||||
|
title={{pl.url}}
|
||||||
|
>{{pl.url}}</span>
|
||||||
|
</td>
|
||||||
|
<td class="d-admin-row__detail destination">
|
||||||
|
{{#if pl.topic_id}}
|
||||||
|
<a href={{pl.topic_url}}>{{pl.topic_title}}</a>
|
||||||
|
{{/if}}
|
||||||
|
{{#if pl.post_id}}
|
||||||
|
<a href={{pl.post_url}}>{{pl.post_topic_title}}
|
||||||
|
#{{pl.post_number}}</a>
|
||||||
|
{{/if}}
|
||||||
|
{{#if pl.category_id}}
|
||||||
|
{{category-link pl.category}}
|
||||||
|
{{/if}}
|
||||||
|
{{#if pl.tag_id}}
|
||||||
|
<a href={{pl.tag_url}}>{{pl.tag_name}}</a>
|
||||||
|
{{/if}}
|
||||||
|
{{#if pl.external_url}}
|
||||||
|
{{#if pl.linkIsExternal}}
|
||||||
|
{{d-icon "up-right-from-square"}}
|
||||||
|
{{/if}}
|
||||||
|
<a href={{pl.external_url}}>{{pl.external_url}}</a>
|
||||||
|
{{/if}}
|
||||||
|
{{#if pl.user_id}}
|
||||||
|
<a href={{pl.user_url}}>{{pl.username}}</a>
|
||||||
|
{{/if}}
|
||||||
|
</td>
|
||||||
|
<td class="d-admin-row__controls">
|
||||||
|
<div class="d-admin-row__controls-options">
|
||||||
|
<DButton
|
||||||
|
class="btn-small admin-permalink-item__edit"
|
||||||
|
@route="adminPermalinks.edit"
|
||||||
|
@routeModels={{pl}}
|
||||||
|
@label="admin.config_areas.flags.edit"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<DMenu
|
||||||
|
@identifier="permalink-menu"
|
||||||
|
@title={{i18n "admin.permalinks.more_options"}}
|
||||||
|
@icon="ellipsis-vertical"
|
||||||
|
@onRegisterApi={{this.onRegisterApi}}
|
||||||
|
>
|
||||||
|
<:content>
|
||||||
|
<DropdownMenu as |dropdown|>
|
||||||
|
<dropdown.item>
|
||||||
|
<DButton
|
||||||
|
@action={{fn this.destroyRecord pl}}
|
||||||
|
@icon="trash-can"
|
||||||
|
class="btn-transparent admin-permalink-item__delete"
|
||||||
|
@label="admin.config_areas.flags.delete"
|
||||||
|
/>
|
||||||
|
</dropdown.item>
|
||||||
|
</DropdownMenu>
|
||||||
|
</:content>
|
||||||
|
</DMenu>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{{/each}}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
{{else}}
|
||||||
|
{{#if this.filter}}
|
||||||
|
<p class="permalink-results__no-result">{{i18n "search.no_results"}}</p>
|
||||||
|
{{else}}
|
||||||
|
<AdminConfigAreaEmptyList
|
||||||
|
@ctaLabel="admin.permalink.add"
|
||||||
|
@ctaRoute="adminPermalinks.new"
|
||||||
|
@ctaClass="admin-permalinks__add-permalink"
|
||||||
|
@emptyLabel="admin.permalink.no_permalinks"
|
||||||
|
/>
|
||||||
|
{{/if}}
|
||||||
|
{{/if}}
|
||||||
|
</div>
|
||||||
|
</ConditionalLoadingSpinner>
|
@ -0,0 +1,6 @@
|
|||||||
|
<AdminAreaSettings
|
||||||
|
@area="permalinks"
|
||||||
|
@path="/admin/customize/permalinks/settings"
|
||||||
|
@filter={{this.filter}}
|
||||||
|
@adminSettingsFilterChangedCallback={{this.adminSettingsFilterChangedCallback}}
|
||||||
|
/>
|
39
app/assets/javascripts/admin/addon/templates/permalinks.hbs
Normal file
39
app/assets/javascripts/admin/addon/templates/permalinks.hbs
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
<div class="admin-permalinks admin-config-page">
|
||||||
|
<DPageHeader
|
||||||
|
@titleLabel={{i18n "admin.permalink.title"}}
|
||||||
|
@descriptionLabel={{i18n "admin.permalink.description"}}
|
||||||
|
@learnMoreUrl="https://meta.discourse.org/t/20930"
|
||||||
|
>
|
||||||
|
<:breadcrumbs>
|
||||||
|
<DBreadcrumbsItem @path="/admin" @label={{i18n "admin_title"}} />
|
||||||
|
<DBreadcrumbsItem
|
||||||
|
@path="/admin/customize/permalinks"
|
||||||
|
@label={{i18n "admin.permalink.title"}}
|
||||||
|
/>
|
||||||
|
</:breadcrumbs>
|
||||||
|
<:actions as |actions|>
|
||||||
|
<actions.Primary
|
||||||
|
@route="adminPermalinks.new"
|
||||||
|
@title="admin.permalink.add"
|
||||||
|
@label="admin.permalink.add"
|
||||||
|
@icon="plus"
|
||||||
|
class="admin-permalinks__header-add-permalink"
|
||||||
|
/>
|
||||||
|
</:actions>
|
||||||
|
<:tabs>
|
||||||
|
<NavItem
|
||||||
|
@route="adminPermalinks.settings"
|
||||||
|
@label="admin.permalink.nav.settings"
|
||||||
|
class="admin-permalinks-tabs__settings"
|
||||||
|
/>
|
||||||
|
<NavItem
|
||||||
|
@route="adminPermalinks.index"
|
||||||
|
@label="admin.permalink.nav.permalinks"
|
||||||
|
class="admin-permalins-permalinks"
|
||||||
|
/>
|
||||||
|
</:tabs>
|
||||||
|
</DPageHeader>
|
||||||
|
<div class="admin-container admin-config-page__main-area">
|
||||||
|
{{outlet}}
|
||||||
|
</div>
|
||||||
|
</div>
|
@ -1,15 +1,10 @@
|
|||||||
<DBreadcrumbsItem
|
|
||||||
@path="/admin/plugins/{{@model.plugin.name}}/settings"
|
|
||||||
@label={{i18n "admin.plugins.change_settings_short"}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="content-body admin-plugin-config-area__settings admin-detail pull-left"
|
class="content-body admin-plugin-config-area__settings admin-detail pull-left"
|
||||||
>
|
>
|
||||||
<AdminFilteredSiteSettings
|
<AdminAreaSettings
|
||||||
@initialFilter={{@model.initialFilter}}
|
@plugin={{@model.plugin.id}}
|
||||||
@plugin={{@model.plugin}}
|
@path="/admin/plugins/{{@model.plugin.name}}/settings"
|
||||||
@settings={{@model.settings}}
|
@filter={{this.filter}}
|
||||||
@onFilterChanged={{this.filterChanged}}
|
@adminSettingsFilterChangedCallback={{this.adminSettingsFilterChangedCallback}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
@ -0,0 +1,83 @@
|
|||||||
|
import { fillIn, render } from "@ember/test-helpers";
|
||||||
|
import { module, test } from "qunit";
|
||||||
|
import { setupRenderingTest } from "discourse/tests/helpers/component-test";
|
||||||
|
import pretender, { response } from "discourse/tests/helpers/create-pretender";
|
||||||
|
import AdminAreaSettings from "admin/components/admin-area-settings";
|
||||||
|
|
||||||
|
module("Integration | Component | AdminAreaSettings", function (hooks) {
|
||||||
|
hooks.beforeEach(function () {
|
||||||
|
pretender.get("/admin/config/site_settings.json", () =>
|
||||||
|
response({
|
||||||
|
site_settings: [
|
||||||
|
{
|
||||||
|
setting: "silence_new_user_sensitivity",
|
||||||
|
description:
|
||||||
|
"The likelihood that a new user will be silenced based on spam flags",
|
||||||
|
keywords: [],
|
||||||
|
default: "3",
|
||||||
|
value: "3",
|
||||||
|
category: "spam",
|
||||||
|
preview: null,
|
||||||
|
secret: false,
|
||||||
|
placeholder: null,
|
||||||
|
mandatory_values: null,
|
||||||
|
requires_confirmation: null,
|
||||||
|
type: "enum",
|
||||||
|
valid_values: [
|
||||||
|
{
|
||||||
|
name: "Disabled",
|
||||||
|
value: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Low",
|
||||||
|
value: 9,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Medium",
|
||||||
|
value: 6,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "High",
|
||||||
|
value: 3,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
translate_names: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
setting: "num_users_to_silence_new_user",
|
||||||
|
description:
|
||||||
|
"If a new user's posts exceed the hide_post_sensitivity setting, and has spam flags from this many different users, hide all their posts and prevent future posting. 0 to disable.",
|
||||||
|
keywords: [],
|
||||||
|
default: "3",
|
||||||
|
value: "4",
|
||||||
|
category: "spam",
|
||||||
|
preview: null,
|
||||||
|
secret: false,
|
||||||
|
placeholder: null,
|
||||||
|
mandatory_values: null,
|
||||||
|
requires_confirmation: null,
|
||||||
|
type: "integer",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
);
|
||||||
|
});
|
||||||
|
setupRenderingTest(hooks);
|
||||||
|
|
||||||
|
test("renders area settings and allows to filter", async function (assert) {
|
||||||
|
const callback = () => {};
|
||||||
|
await render(<template>
|
||||||
|
<AdminAreaSettings
|
||||||
|
@area="flags"
|
||||||
|
@adminSettingsFilterChangedCallback={{callback}}
|
||||||
|
@filter=""
|
||||||
|
/>
|
||||||
|
</template>);
|
||||||
|
|
||||||
|
assert.dom(".admin-site-settings-filter-controls").exists();
|
||||||
|
assert.dom(".setting-label").exists({ count: 2 });
|
||||||
|
|
||||||
|
await fillIn("#setting-filter", "num");
|
||||||
|
assert.dom(".setting-label").exists({ count: 1 });
|
||||||
|
});
|
||||||
|
});
|
@ -424,20 +424,6 @@ $mobile-breakpoint: 700px;
|
|||||||
color: var(--primary-medium);
|
color: var(--primary-medium);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.admin-users-list {
|
|
||||||
&__search {
|
|
||||||
@media screen and (max-width: 500px) {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
input {
|
|
||||||
min-width: 15em;
|
|
||||||
@media screen and (max-width: 500px) {
|
|
||||||
box-sizing: border-box;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.ip-lookup {
|
.ip-lookup {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -1,10 +1,22 @@
|
|||||||
.d-admin-filter {
|
.d-admin-filter {
|
||||||
background-color: var(--primary-very-low);
|
background-color: var(--primary-very-low);
|
||||||
padding: var(--space-2);
|
padding: var(--space-2);
|
||||||
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-users-list__search {
|
.admin-filter__input-container {
|
||||||
min-width: 50%;
|
min-width: 50%;
|
||||||
|
@media screen and (max-width: 500px) {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
input {
|
||||||
|
min-width: 15em;
|
||||||
|
margin: 0;
|
||||||
|
@media screen and (max-width: 500px) {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.admin-filter__input {
|
.admin-filter__input {
|
||||||
|
@ -813,10 +813,11 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.permalink-search input {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
.admin-config-area__settings-no-results {
|
||||||
|
padding-left: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
.admin-permalink-item {
|
.admin-permalink-item {
|
||||||
&__delete.btn,
|
&__delete.btn,
|
||||||
&__delete.btn:hover {
|
&__delete.btn:hover {
|
||||||
|
@ -12,7 +12,8 @@ class Admin::Config::SiteSettingsController < Admin::AdminController
|
|||||||
# UI itself uses the Admin::SiteSettingsController#index endpoint,
|
# UI itself uses the Admin::SiteSettingsController#index endpoint,
|
||||||
# which also supports a `category` and `plugin` filter.
|
# which also supports a `category` and `plugin` filter.
|
||||||
def index
|
def index
|
||||||
if params[:filter_names].blank? && SiteSetting.valid_areas.exclude?(params[:filter_area])
|
if params[:plugin].blank? && params[:categories].blank? && params[:filter_names].blank? &&
|
||||||
|
SiteSetting.valid_areas.exclude?(params[:filter_area])
|
||||||
raise Discourse::InvalidParameters
|
raise Discourse::InvalidParameters
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -21,6 +22,8 @@ class Admin::Config::SiteSettingsController < Admin::AdminController
|
|||||||
SiteSetting.all_settings(
|
SiteSetting.all_settings(
|
||||||
filter_names: params[:filter_names],
|
filter_names: params[:filter_names],
|
||||||
filter_area: params[:filter_area],
|
filter_area: params[:filter_area],
|
||||||
|
filter_plugin: params[:plugin],
|
||||||
|
filter_categories: Array.wrap(params[:categories]),
|
||||||
include_locale_setting: false,
|
include_locale_setting: false,
|
||||||
include_hidden: true,
|
include_hidden: true,
|
||||||
filter_allowed_hidden: ADMIN_CONFIG_AREA_ALLOWLISTED_HIDDEN_SETTINGS,
|
filter_allowed_hidden: ADMIN_CONFIG_AREA_ALLOWLISTED_HIDDEN_SETTINGS,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class SiteSetting < ActiveRecord::Base
|
class SiteSetting < ActiveRecord::Base
|
||||||
VALID_AREAS = %w[flags about emojis]
|
VALID_AREAS = %w[flags about emojis permalinks]
|
||||||
|
|
||||||
extend GlobalPath
|
extend GlobalPath
|
||||||
extend SiteSettingExtension
|
extend SiteSettingExtension
|
||||||
|
@ -7087,6 +7087,7 @@ en:
|
|||||||
save: "save"
|
save: "save"
|
||||||
cancel: "cancel"
|
cancel: "cancel"
|
||||||
unmask: "unmask input"
|
unmask: "unmask input"
|
||||||
|
not_found: "Settings could not be found"
|
||||||
site_settings:
|
site_settings:
|
||||||
emoji_list:
|
emoji_list:
|
||||||
invalid_input: "Emoji list should only contain valid emoji names, eg: hugs"
|
invalid_input: "Emoji list should only contain valid emoji names, eg: hugs"
|
||||||
@ -7352,6 +7353,9 @@ en:
|
|||||||
back: "Back to Permalinks"
|
back: "Back to Permalinks"
|
||||||
more_options: "More options"
|
more_options: "More options"
|
||||||
copy_success: "Permalink copied to clipboard"
|
copy_success: "Permalink copied to clipboard"
|
||||||
|
nav:
|
||||||
|
settings: "Settings"
|
||||||
|
permalinks: "Permalinks"
|
||||||
form:
|
form:
|
||||||
label: "New:"
|
label: "New:"
|
||||||
add_header: "Add permalink"
|
add_header: "Add permalink"
|
||||||
|
@ -2700,6 +2700,7 @@ uncategorized:
|
|||||||
type: list
|
type: list
|
||||||
list_type: simple
|
list_type: simple
|
||||||
validator: "RegexpListValidator"
|
validator: "RegexpListValidator"
|
||||||
|
area: "permalinks"
|
||||||
|
|
||||||
max_similar_results: 5
|
max_similar_results: 5
|
||||||
minimum_topics_similar: 50
|
minimum_topics_similar: 50
|
||||||
|
@ -27,4 +27,10 @@ describe "Admin Permalinks Page", type: :system do
|
|||||||
|
|
||||||
expect(admin_permalinks_page).to have_no_permalinks
|
expect(admin_permalinks_page).to have_no_permalinks
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "allows admin to go to permalink settings page" do
|
||||||
|
admin_permalinks_page.visit
|
||||||
|
admin_permalinks_page.click_tab("settings")
|
||||||
|
expect(admin_permalinks_page).to have_active_tab("settings")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -49,6 +49,15 @@ module PageObjects
|
|||||||
def has_closed_permalink_menu?
|
def has_closed_permalink_menu?
|
||||||
has_no_css?(".permalink-menu-content")
|
has_no_css?(".permalink-menu-content")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def click_tab(tab)
|
||||||
|
has_css?(".admin-permalinks-tabs__#{tab}")
|
||||||
|
find(".admin-permalinks-tabs__#{tab}").click
|
||||||
|
end
|
||||||
|
|
||||||
|
def has_active_tab?(tab)
|
||||||
|
has_css?(".admin-permalinks-tabs__#{tab} .active")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user