DEV: Update linting setup and fix issues (#17345)
Re-lands #16119 and #17298 * Update eslint-config-discourse * Update linting workflow * Prettier-ignore stuff * Update template-lint config * Auto-fix template issues * Fix various template issues Mostly incorrect attributes and unused templates * Prettier js files * Fix template auto-fix regressions * Small css tweak Co-authored-by: Peter Wagenet <peter.wagenet@gmail.com>
This commit is contained in:
parent
f7c133ac74
commit
c3fd91670e
|
@ -86,8 +86,9 @@ jobs:
|
|||
if: ${{ always() }}
|
||||
run: |
|
||||
yarn ember-template-lint \
|
||||
app/assets/javascripts \
|
||||
plugins/**/assets/javascripts
|
||||
--no-error-on-unmatched-pattern \
|
||||
"app/assets/javascripts/**/*.hbs" \
|
||||
"plugins/**/assets/javascripts/**/*.hbs"
|
||||
|
||||
- name: English locale lint (core)
|
||||
if: ${{ always() }}
|
||||
|
|
|
@ -22,4 +22,10 @@ app/assets/javascripts/discourse/tests/fixtures
|
|||
spec/
|
||||
node_modules/
|
||||
dist/
|
||||
tmp/
|
||||
|
||||
**/*.rb
|
||||
**/*.hbs
|
||||
**/*.html
|
||||
**/*.json
|
||||
**/*.md
|
||||
|
|
|
@ -1,58 +1,9 @@
|
|||
module.exports = {
|
||||
extends: "recommended",
|
||||
ignore: ["**/*.raw"],
|
||||
plugins: ["ember-template-lint-plugin-discourse"],
|
||||
extends: "discourse:recommended",
|
||||
|
||||
rules: {
|
||||
"block-indentation": true,
|
||||
"deprecated-render-helper": true,
|
||||
"eol-last": "always",
|
||||
"linebreak-style": true,
|
||||
"link-rel-noopener": "strict",
|
||||
"no-abstract-roles": true,
|
||||
"no-args-paths": true,
|
||||
"no-attrs-in-components": true,
|
||||
"no-debugger": true,
|
||||
"no-duplicate-attributes": true,
|
||||
"no-extra-mut-helper-argument": true,
|
||||
"no-html-comments": true,
|
||||
"no-index-component-invocation": true,
|
||||
"no-inline-styles": false,
|
||||
"no-input-block": true,
|
||||
"no-input-tagname": true,
|
||||
"no-implicit-this": {
|
||||
allow: [
|
||||
'loading-spinner'
|
||||
]
|
||||
},
|
||||
"no-invalid-interactive": true,
|
||||
"no-invalid-link-text": true,
|
||||
"no-invalid-meta": true,
|
||||
"no-invalid-role": true,
|
||||
"no-log": true,
|
||||
"no-negated-condition": true,
|
||||
"no-nested-interactive": true,
|
||||
"no-multiple-empty-lines": true,
|
||||
"no-obsolete-elements": true,
|
||||
"no-outlet-outside-routes": true,
|
||||
"no-partial": true,
|
||||
"no-positive-tabindex": false,
|
||||
"no-quoteless-attributes": true,
|
||||
"no-shadowed-elements": true,
|
||||
"no-trailing-spaces": true,
|
||||
"no-triple-curlies": true,
|
||||
"no-unbound": true,
|
||||
"no-unnecessary-concat": true,
|
||||
"no-unnecessary-component-helper": true,
|
||||
"no-unused-block-params": true,
|
||||
quotes: "double",
|
||||
"require-button-type": true,
|
||||
"require-iframe-title": true,
|
||||
"require-valid-alt-text": false,
|
||||
"self-closing-void-elements": true,
|
||||
"simple-unless": true,
|
||||
"style-concatenation": true,
|
||||
"table-groups": true,
|
||||
"link-href-attributes": false,
|
||||
"no-capital-arguments": false, // TODO: we extensively use `args` argument name
|
||||
"no-curly-component-invocation": {
|
||||
allow: [
|
||||
// These are helpers, not components
|
||||
|
@ -64,5 +15,8 @@ module.exports = {
|
|||
"mobile-directory-item-label",
|
||||
],
|
||||
},
|
||||
"no-implicit-this": {
|
||||
allow: ["loading-spinner"],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -5,7 +5,8 @@ import I18n from "I18n";
|
|||
import { bind, observes } from "discourse-common/utils/decorators";
|
||||
import { on } from "@ember/object/evented";
|
||||
|
||||
const COLOR_VARS_REGEX = /\$(primary|secondary|tertiary|quaternary|header_background|header_primary|highlight|danger|success|love)(\s|;|-(low|medium|high))/g;
|
||||
const COLOR_VARS_REGEX =
|
||||
/\$(primary|secondary|tertiary|quaternary|header_background|header_primary|highlight|danger|success|love)(\s|;|-(low|medium|high))/g;
|
||||
|
||||
export default Component.extend({
|
||||
mode: "css",
|
||||
|
|
|
@ -12,7 +12,7 @@ export default Controller.extend({
|
|||
"filter",
|
||||
"siteSettings.dashboard_hidden_reports"
|
||||
)
|
||||
filterReports(reports, filter) {
|
||||
filteredReports(reports, filter) {
|
||||
if (filter) {
|
||||
filter = filter.toLowerCase();
|
||||
reports = reports.filter((report) => {
|
||||
|
|
|
@ -32,8 +32,9 @@ export default Route.extend({
|
|||
|
||||
actions: {
|
||||
installModal() {
|
||||
const currentTheme = this.controllerFor("adminCustomizeThemes.show")
|
||||
.model;
|
||||
const currentTheme = this.controllerFor(
|
||||
"adminCustomizeThemes.show"
|
||||
).model;
|
||||
if (currentTheme && currentTheme.warnUnassignedComponent) {
|
||||
showUnassignedComponentWarning(currentTheme, (result) => {
|
||||
if (!result) {
|
||||
|
|
|
@ -12,8 +12,9 @@ export default DiscourseRoute.extend({
|
|||
const routeName = "adminUsersList.show";
|
||||
|
||||
if (transition.targetName === routeName) {
|
||||
const params = transition.routeInfos.find((a) => a.name === routeName)
|
||||
.params;
|
||||
const params = transition.routeInfos.find(
|
||||
(a) => a.name === routeName
|
||||
).params;
|
||||
const controller = this.controllerFor(routeName);
|
||||
if (controller) {
|
||||
controller.setProperties({
|
||||
|
|
|
@ -46,9 +46,10 @@ export default Service.extend({
|
|||
});
|
||||
controller.setProperties({ postId: opts.postId, postEdit: opts.postEdit });
|
||||
|
||||
return (user.adminUserView
|
||||
? Promise.resolve(user)
|
||||
: AdminUser.find(user.get("id"))
|
||||
return (
|
||||
user.adminUserView
|
||||
? Promise.resolve(user)
|
||||
: AdminUser.find(user.get("id"))
|
||||
).then((loadedUser) => {
|
||||
controller.setProperties({
|
||||
user: loadedUser,
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
</AdminFormRow>
|
||||
{{else}}
|
||||
<AdminFormRow @label="admin.api.description">
|
||||
<Input @value={{this.model.description}} @maxlength="255" placeholder={{i18n "admin.api.description_placeholder"}} />
|
||||
<Input @value={{this.model.description}} maxlength="255" placeholder={{i18n "admin.api.description_placeholder"}} />
|
||||
</AdminFormRow>
|
||||
|
||||
<AdminFormRow @label="admin.api.user_mode">
|
||||
|
@ -76,7 +76,7 @@
|
|||
</td>
|
||||
<td>
|
||||
{{#each act.params as |p|}}
|
||||
<Input @maxlength="255" @value={{get act p}} placeholder={{p}} />
|
||||
<Input maxlength="255" @value={{get act p}} placeholder={{p}} />
|
||||
{{/each}}
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
<AdminFormRow @label="admin.api.description">
|
||||
{{#if this.editingDescription}}
|
||||
<Input @value={{this.buffered.description}} @maxlength="255" placeholder={{i18n "admin.api.description_placeholder"}} />
|
||||
<Input @value={{this.buffered.description}} maxlength="255" placeholder={{i18n "admin.api.description_placeholder"}} />
|
||||
{{else}}
|
||||
<span>
|
||||
{{if this.model.description this.model.description (i18n "admin.api.no_description")}}
|
||||
|
|
|
@ -3,14 +3,14 @@
|
|||
<div class="control-group">
|
||||
<label for="name">{{i18n "admin.badges.name"}}</label>
|
||||
{{#if this.readOnly}}
|
||||
<Input @type="text" @name="name" @value={{this.buffered.name}} @disabled={{true}} />
|
||||
<Input @type="text" name="name" @value={{this.buffered.name}} disabled={{true}} />
|
||||
<p class="help">
|
||||
<LinkTo @route="adminSiteText" @query={{hash q=(concat this.textCustomizationPrefix "name")}}>
|
||||
{{i18n "admin.badges.read_only_setting_help"}}
|
||||
</LinkTo>
|
||||
</p>
|
||||
{{else}}
|
||||
<Input @type="text" @name="name" @value={{this.buffered.name}} />
|
||||
<Input @type="text" name="name" @value={{this.buffered.name}} />
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
|
@ -56,28 +56,28 @@
|
|||
<div class="control-group">
|
||||
<label for="description">{{i18n "admin.badges.description"}}</label>
|
||||
{{#if this.buffered.system}}
|
||||
<Textarea @name="description" @value={{this.buffered.description}} @disabled={{true}} />
|
||||
<Textarea name="description" @value={{this.buffered.description}} disabled={{true}} />
|
||||
<p class="help">
|
||||
<LinkTo @route="adminSiteText" @query={{hash q=(concat this.textCustomizationPrefix "description")}}>
|
||||
{{i18n "admin.badges.read_only_setting_help"}}
|
||||
</LinkTo>
|
||||
</p>
|
||||
{{else}}
|
||||
<Textarea @name="description" @value={{this.buffered.description}} />
|
||||
<Textarea name="description" @value={{this.buffered.description}} />
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label for="long_description">{{i18n "admin.badges.long_description"}}</label>
|
||||
{{#if this.buffered.system}}
|
||||
<Textarea @name="long_description" @value={{this.buffered.long_description}} @disabled={{true}} />
|
||||
<Textarea name="long_description" @value={{this.buffered.long_description}} disabled={{true}} />
|
||||
<p class="help">
|
||||
<LinkTo @route="adminSiteText" @query={{hash q=(concat this.textCustomizationPrefix "long_description")}}>
|
||||
{{i18n "admin.badges.read_only_setting_help"}}
|
||||
</LinkTo>
|
||||
</p>
|
||||
{{else}}
|
||||
<Textarea @name="long_description" @value={{this.buffered.long_description}} />
|
||||
<Textarea name="long_description" @value={{this.buffered.long_description}} />
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
|
@ -97,14 +97,14 @@
|
|||
|
||||
<div class="control-group">
|
||||
<label>
|
||||
<Input @type="checkbox" @checked={{this.buffered.auto_revoke}} @disabled={{this.readOnly}} />
|
||||
<Input @type="checkbox" @checked={{this.buffered.auto_revoke}} disabled={{this.readOnly}} />
|
||||
{{i18n "admin.badges.auto_revoke"}}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label>
|
||||
<Input @type="checkbox" @checked={{this.buffered.target_posts}} @disabled={{this.readOnly}} />
|
||||
<Input @type="checkbox" @checked={{this.buffered.target_posts}} disabled={{this.readOnly}} />
|
||||
{{i18n "admin.badges.target_posts"}}
|
||||
</label>
|
||||
</div>
|
||||
|
@ -128,21 +128,21 @@
|
|||
|
||||
<div>
|
||||
<label>
|
||||
<Input @type="checkbox" @checked={{this.buffered.multiple_grant}} @disabled={{this.readOnly}} />
|
||||
<Input @type="checkbox" @checked={{this.buffered.multiple_grant}} disabled={{this.readOnly}} />
|
||||
{{i18n "admin.badges.multiple_grant"}}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label>
|
||||
<Input @type="checkbox" @checked={{this.buffered.listable}} @disabled={{this.readOnly}} />
|
||||
<Input @type="checkbox" @checked={{this.buffered.listable}} disabled={{this.readOnly}} />
|
||||
{{i18n "admin.badges.listable"}}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label>
|
||||
<Input @type="checkbox" @checked={{this.buffered.show_posts}} @disabled={{this.readOnly}} />
|
||||
<Input @type="checkbox" @checked={{this.buffered.show_posts}} disabled={{this.readOnly}} />
|
||||
{{i18n "admin.badges.show_posts"}}
|
||||
</label>
|
||||
</div>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<ul class="nav nav-pills target">
|
||||
{{#each this.visibleTargets as |target|}}
|
||||
<li>
|
||||
<LinkTo @route={{this.editRouteName}} @models={{array this.theme.id target.name this.fieldName}} @replace={{true}} @title={{this.field.title}} class={{if target.edited "edited" "blank"}}>
|
||||
<LinkTo @route={{this.editRouteName}} @models={{array this.theme.id target.name this.fieldName}} @replace={{true}} title={{this.field.title}} class={{if target.edited "edited" "blank"}}>
|
||||
{{#if target.error}}{{d-icon "exclamation-triangle"}}{{/if}}
|
||||
{{#if target.icon}}{{d-icon target.icon}}{{/if}}
|
||||
{{i18n (concat "admin.customize.theme." target.name)}}
|
||||
|
@ -24,7 +24,7 @@
|
|||
<li class="spacer"></li>
|
||||
<li>
|
||||
<label>
|
||||
<Input @type="checkbox" @checked={{this.onlyOverridden}} @click={{action "onlyOverriddenChanged" value="target.checked"}} />
|
||||
<Input @type="checkbox" @checked={{this.onlyOverridden}} {{on "click" (action "onlyOverriddenChanged" value="target.checked")}} />
|
||||
{{i18n "admin.customize.theme.hide_unused_fields"}}
|
||||
</label>
|
||||
</li>
|
||||
|
@ -37,7 +37,7 @@
|
|||
<ul class="nav nav-pills fields">
|
||||
{{#each this.visibleFields as |field|}}
|
||||
<li>
|
||||
<LinkTo @route={{this.editRouteName}} @models={{array this.theme.id this.currentTargetName field.name}} @replace={{true}} @title={{field.title}} class={{if field.edited "edited" "blank"}}>
|
||||
<LinkTo @route={{this.editRouteName}} @models={{array this.theme.id this.currentTargetName field.name}} @replace={{true}} title={{field.title}} class={{if field.edited "edited" "blank"}}>
|
||||
{{#if field.error}}{{d-icon "exclamation-triangle"}}{{/if}}
|
||||
{{#if field.icon}}{{d-icon field.icon}}{{/if}}
|
||||
{{field.translatedName}}
|
||||
|
|
|
@ -5,11 +5,11 @@
|
|||
</AdminFormRow>
|
||||
|
||||
<AdminFormRow @label="admin.user_fields.name">
|
||||
<Input @value={{this.buffered.name}} class="user-field-name" @maxlength="255" />
|
||||
<Input @value={{this.buffered.name}} class="user-field-name" maxlength="255" />
|
||||
</AdminFormRow>
|
||||
|
||||
<AdminFormRow @label="admin.user_fields.description">
|
||||
<Input @value={{this.buffered.description}} class="user-field-desc" @maxlength="255" />
|
||||
<Input @value={{this.buffered.description}} class="user-field-desc" maxlength="255" />
|
||||
</AdminFormRow>
|
||||
|
||||
{{#if this.bufferedFieldType.hasOptions}}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
<Input @id={{this.typeName}} @type="checkbox" @name="event-choice" @checked={{this.enabled}} />
|
||||
<Input id={{this.typeName}} @type="checkbox" name="event-choice" @checked={{this.enabled}} />
|
||||
<label for={{this.typeName}}>{{this.name}}</label>
|
||||
<p>{{this.details}}</p>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{{#if this.editing}}
|
||||
<td class="editing-input">
|
||||
<div class="label">{{i18n "admin.embedding.host"}}</div>
|
||||
<Input @value={{this.buffered.host}} placeholder="example.com" @enter={{action "save"}} class="host-name" @autofocus={{true}} />
|
||||
<Input @value={{this.buffered.host}} placeholder="example.com" @enter={{action "save"}} class="host-name" autofocus={{true}} />
|
||||
</td>
|
||||
<td class="editing-input">
|
||||
<div class="label">{{i18n "admin.embedding.class_name"}}</div>
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
{{#if this.isCheckbox}}
|
||||
<label for={{this.inputId}}>
|
||||
<Input @checked={{this.checked}} @id={{this.inputId}} @type="checkbox" />
|
||||
<Input @checked={{this.checked}} id={{this.inputId}} @type="checkbox" />
|
||||
{{i18n this.translationKey}}
|
||||
</label>
|
||||
{{else}}
|
||||
<label for={{this.inputId}}>{{i18n this.translationKey}}</label>
|
||||
<Input @value={{this.value}} @id={{this.inputId}} placeholder={{this.placeholder}} />
|
||||
<Input @value={{this.value}} id={{this.inputId}} placeholder={{this.placeholder}} />
|
||||
{{/if}}
|
||||
|
||||
<div class="clearfix"></div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<label class="checkbox-label">
|
||||
<Input @type="checkbox" @disabled={{this.disabled}} @checked={{this.buffer}} />
|
||||
<Input @type="checkbox" disabled={{this.disabled}} @checked={{this.buffer}} />
|
||||
{{i18n this.labelKey}}
|
||||
</label>
|
||||
{{#if this.changed}}
|
||||
|
|
|
@ -1 +1 @@
|
|||
<Input @type="checkbox" @checked={{this.checked}} @click={{action "onChange"}} />
|
||||
<Input @type="checkbox" @checked={{this.checked}} {{on "click" (action "onChange")}} />
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
{{#each this.collection as |value index|}}
|
||||
<div class="value" data-index={{index}}>
|
||||
<DButton @action={{action "removeValue"}} @actionParam={{value}} @icon="times" @class="remove-value-btn btn-small" />
|
||||
<Input @value={{value.key}} class="value-input" @focus-out={{action "changeKey" index}} />
|
||||
<Input @value={{value.secret}} class="value-input" @focus-out={{action "changeSecret" index}} @type={{if this.isSecret "password" "text"}} />
|
||||
<Input @value={{value.key}} class="value-input" {{on "focusout" (action "changeKey" index)}} />
|
||||
<Input @value={{value.secret}} class="value-input" @type={{if this.isSecret "password" "text"}} {{on "focusout" (action "changeSecret" index)}} />
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
|
|
|
@ -4,21 +4,19 @@
|
|||
<div data-index={{index}} class="value">
|
||||
<DButton @action={{action "removeValue"}} @actionParam={{value}} @icon="times" @class="remove-value-btn btn-small" />
|
||||
|
||||
<Input @title={{value}} @value={{value}} class="value-input" @focus-out={{action "changeValue" index}} />
|
||||
<Input title={{value}} @value={{value}} class="value-input" {{on "focusout" (action "changeValue" index)}} />
|
||||
|
||||
{{#if this.showUpDownButtons}}
|
||||
<DButton @action={{action "shift" -1 index}} @icon="arrow-up" @class="shift-up-value-btn btn-small" />
|
||||
<DButton @action={{action "shift" 1 index}} @icon="arrow-down" @class="shift-down-value-btn btn-small" />
|
||||
{{/if}}
|
||||
</div>
|
||||
|
||||
{{/each}}
|
||||
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="simple-list-input">
|
||||
<Input @type="text" @value={{this.newValue}} @placeholderKey="admin.site_settings.simple_list.add_item" class="add-value-input" @autocomplete="off" @autocorrect="off" @autocapitalize="off" />
|
||||
<Input @type="text" @value={{this.newValue}} placeholder={{i18n "admin.site_settings.simple_list.add_item"}} class="add-value-input" autocomplete="off" autocorrect="off" autocapitalize="off" />
|
||||
|
||||
<DButton @action={{action "addValue"}} @actionParam={{this.newValue}} @disabled={{this.inputEmpty}} @icon="plus" @class="add-value-btn btn-small" />
|
||||
</div>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<h3>
|
||||
{{#if this.staffLogFilter}}
|
||||
{{this.settingName}}
|
||||
<LinkTo @route="adminLogs.staffActionLogs" @query={{hash filters=this.staffLogFilter force_refresh=true}} @title={{i18n "admin.settings.history"}}>
|
||||
<LinkTo @route="adminLogs.staffActionLogs" @query={{hash filters=this.staffLogFilter force_refresh=true}} title={{i18n "admin.settings.history"}}>
|
||||
<span class="history-icon">
|
||||
{{d-icon "history"}}
|
||||
</span>
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
{{#if this.setting.textarea}}
|
||||
<Textarea @value={{this.value}} @classNames="input-setting-textarea" />
|
||||
<Textarea @value={{this.value}} class="input-setting-textarea" />
|
||||
{{else if this.setting.json_schema}}
|
||||
<DButton @action={{action "launchJsonEditorModal"}} @icon="pencil-alt" @label="admin.site_settings.json_schema.edit" />
|
||||
{{else if this.isSecret}}
|
||||
<Input @type="password" @value={{this.value}} @classNames="input-setting-string" />
|
||||
<Input @type="password" @value={{this.value}} class="input-setting-string" />
|
||||
{{else}}
|
||||
<TextField @value={{this.value}} @classNames="input-setting-string" />
|
||||
{{/if}}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
{{!-- template-lint-disable no-invalid-interactive --}}
|
||||
<div class="table staff-actions" {{on "click" (fn this.openLinks)}}>
|
||||
<div class="table staff-actions" {{on "click" this.openLinks}}>
|
||||
{{yield}}
|
||||
</div>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<div class="themes-list-container">
|
||||
{{#if this.showFilter}}
|
||||
<div class="themes-list-filter themes-list-item">
|
||||
<Input class="filter-input" placeholder={{i18n "admin.customize.theme.filter_placeholder"}} @autocomplete="off" @type="search" @value={{mut this.filterTerm}} />
|
||||
<Input class="filter-input" placeholder={{i18n "admin.customize.theme.filter_placeholder"}} autocomplete="off" @type="search" @value={{mut this.filterTerm}} />
|
||||
{{d-icon "search"}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<div data-index={{index}} class="value">
|
||||
<DButton @action={{action "removeValue"}} @actionParam={{value}} @icon="times" @class="remove-value-btn btn-small" />
|
||||
|
||||
<Input @title={{value}} @value={{value}} class="value-input" @focus-out={{action "changeValue" index}} />
|
||||
<Input title={{value}} @value={{value}} class="value-input" {{on "focusout" (action "changeValue" index)}} />
|
||||
|
||||
{{#if this.showUpDownButtons}}
|
||||
<DButton @action={{action "shift" -1 index}} @icon="arrow-up" @class="shift-up-value-btn btn-small" />
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
|
||||
{{#if this.canLink}}
|
||||
<div class="watched-word-input">
|
||||
<label for="watched-replacement">{{i18n "admin.watched_words.form.link_label"}}</label>
|
||||
<TextField @id="watched-replacement" @value={{this.replacement}} @disabled={{this.formSubmitted}} @class="watched-word-input-field" @autocorrect="off" @autocapitalize="off" @placeholderKey="admin.watched_words.form.link_placeholder" />
|
||||
<label for="watched-link">{{i18n "admin.watched_words.form.link_label"}}</label>
|
||||
<TextField @id="watched-link" @value={{this.replacement}} @disabled={{this.formSubmitted}} @class="watched-word-input-field" @autocorrect="off" @autocapitalize="off" @placeholderKey="admin.watched_words.form.link_placeholder" />
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
|
|
|
@ -2,11 +2,11 @@
|
|||
<div class="reports-index section">
|
||||
<div class="section-title">
|
||||
<h2>{{i18n "admin.reports.title"}}</h2>
|
||||
<Input class="filter-reports-input" @input={{action "filterReports" value="target.value"}} placeholder={{i18n "admin.dashboard.filter_reports"}} @autofocus={{true}} />
|
||||
<Input class="filter-reports-input" placeholder={{i18n "admin.dashboard.filter_reports"}} autofocus={{true}} {{on "input" (action "filterReports" value="target.value")}} />
|
||||
</div>
|
||||
|
||||
<ul class="reports-list">
|
||||
{{#each this.filterReports as |report|}}
|
||||
{{#each this.filteredReports as |report|}}
|
||||
<li class="report">
|
||||
<LinkTo @route="adminReports.show" @model={{report.type}}>
|
||||
<h3 class="report-title">{{report.title}}</h3>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<div class="email-advanced-test">
|
||||
<label for="email">{{i18n "admin.email.advanced_test.email"}}</label>
|
||||
<Textarea @name="email" @value={{this.email}} class="email-body" /> <DButton @action={{action "run"}} @label="admin.email.advanced_test.run" />
|
||||
<Textarea name="email" @value={{this.email}} class="email-body" /> <DButton @action={{action "run"}} @label="admin.email.advanced_test.run" />
|
||||
</div>
|
||||
|
||||
<ConditionalLoadingSpinner @condition={{this.loading}}>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<p>
|
||||
{{i18n "admin.logs.screened_urls.description"}}
|
||||
</p>
|
||||
<DButton @class="btn-default" @action={{action "exportScreenedUrlList"}} @title="admin.export_csv.button_title.screened_url" @icon="download" @label="admin.export_csv.button_text" />
|
||||
<DButton @class="btn-default" @action={{action "exportScreenedUrlList"}} @title="admin.export_csv.button_title.screened_url" @icon="download" @label="admin.export_csv.button_text" />
|
||||
<br>
|
||||
|
||||
<ConditionalLoadingSpinner @condition={{this.loading}}>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
</section>
|
||||
<section class="field">
|
||||
<label for="theme-variable-name">{{i18n "admin.customize.theme.variable_name"}}</label>
|
||||
<Input @id="theme-variable-name" @value={{this.name}} />
|
||||
<Input id="theme-variable-name" @value={{this.name}} />
|
||||
</section>
|
||||
{{#if this.fileSelected}}
|
||||
{{#if this.errorMessage}}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
<div class="control-group">
|
||||
<label>{{i18n "admin.email.incoming_emails.modal.headers"}}</label>
|
||||
<div class="controls">
|
||||
<Textarea @value={{this.model.headers}} @wrap="off" />
|
||||
<Textarea @value={{this.model.headers}} wrap="off" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@
|
|||
<div class="public-key">
|
||||
<div class="label">{{i18n "admin.customize.theme.public_key"}}</div>
|
||||
<div class="public-key-text-wrapper">
|
||||
<Textarea class="public-key-value" @readonly={{true}} @value={{this.publicKey}} /> <CopyButton @selector="textarea.public-key-value" />
|
||||
<Textarea class="public-key-value" readonly={{true}} @value={{this.publicKey}} /> <CopyButton @selector="textarea.public-key-value" />
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<DModalBody @rawTitle={{i18n "admin.watched_words.test.modal_title" action=this.model.name}} @class="watched-words-test-modal">
|
||||
<p>{{i18n "admin.watched_words.test.description"}}</p>
|
||||
<Textarea @name="test_value" @value={{this.value}} @autofocus="autofocus" />
|
||||
<Textarea name="test_value" @value={{this.value}} autofocus="autofocus" />
|
||||
{{#if this.matches}}
|
||||
<p>
|
||||
{{i18n "admin.watched_words.test.found_matches"}}
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
</div>
|
||||
|
||||
<label>
|
||||
<Input @type="checkbox" @checked={{this.overridden}} @click={{action "toggleOverridden"}} />
|
||||
<Input @type="checkbox" @checked={{this.overridden}} {{on "click" (action "toggleOverridden")}} />
|
||||
{{i18n "admin.site_text.show_overriden"}}
|
||||
</label>
|
||||
</p>
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
|
||||
{{#if this.currentAction.words}}
|
||||
<label class="show-words-checkbox">
|
||||
<Input @type="checkbox" @checked={{this.adminWatchedWords.showWords}} @disabled={{this.adminWatchedWords.disableShowWords}} />
|
||||
<Input @type="checkbox" @checked={{this.adminWatchedWords.showWords}} disabled={{this.adminWatchedWords.disableShowWords}} />
|
||||
{{i18n "admin.watched_words.show_words" count=this.currentAction.words.length}}
|
||||
</label>
|
||||
{{/if}}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<div class="web-hook-direction">
|
||||
<LinkTo @route="adminWebHooks" @tagName="button" @classNames="btn">
|
||||
<LinkTo @route="adminWebHooks" class="btn">
|
||||
{{d-icon "list"}} {{i18n "admin.web_hooks.events.go_list"}}
|
||||
</LinkTo>
|
||||
<DButton @icon="paper-plane" @label="admin.web_hooks.events.ping" @action={{action "ping"}} @disabled={{this.pingDisabled}} />
|
||||
<LinkTo @route="adminWebHooks.show" @model={{this.model.extras.web_hook_id}} @tagName="button" @classNames="btn">
|
||||
<LinkTo @route="adminWebHooks.show" @model={{this.model.extras.web_hook_id}} class="btn">
|
||||
{{d-icon "far-edit"}} {{i18n "admin.web_hooks.events.go_details"}}
|
||||
</LinkTo>
|
||||
</div>
|
||||
|
|
|
@ -66,11 +66,11 @@
|
|||
<PluginOutlet @name="web-hook-fields" @tagName="span" @connectorTagName="div" @args={{hash model=this.model}} />
|
||||
|
||||
<div>
|
||||
<Input @type="checkbox" @name="verify_certificate" @checked={{this.model.verify_certificate}} /> {{i18n "admin.web_hooks.verify_certificate"}}
|
||||
<Input @type="checkbox" name="verify_certificate" @checked={{this.model.verify_certificate}} /> {{i18n "admin.web_hooks.verify_certificate"}}
|
||||
</div>
|
||||
<div>
|
||||
<div>
|
||||
<Input @type="checkbox" @name="active" @checked={{this.model.active}} /> {{i18n "admin.web_hooks.active"}}
|
||||
<Input @type="checkbox" name="active" @checked={{this.model.active}} /> {{i18n "admin.web_hooks.active"}}
|
||||
</div>
|
||||
{{#if this.model.active}}
|
||||
<div class="instructions">{{i18n "admin.web_hooks.active_notice"}}</div>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div class="web-hooks-listing">
|
||||
<p>{{i18n "admin.web_hooks.instruction"}}</p>
|
||||
<div class="new-webhook">
|
||||
<LinkTo @route="adminWebHooks.show" @model="new" @tagName="button" @classNames="btn btn-default">
|
||||
<LinkTo @route="adminWebHooks.show" @model="new" class="btn btn-default">
|
||||
{{d-icon "plus"}} {{i18n "admin.web_hooks.new"}}
|
||||
</LinkTo>
|
||||
</div>
|
||||
|
@ -23,7 +23,7 @@
|
|||
<td class="payload-url"><LinkTo @route="adminWebHooks.show" @model={{webHook}}>{{webHook.payload_url}}</LinkTo></td>
|
||||
<td class="description">{{webHook.description}}</td>
|
||||
<td class="controls">
|
||||
<LinkTo @route="adminWebHooks.show" @model={{webHook}} @tagName="button" @classNames="btn btn-default no-text">{{d-icon "far-edit"}}</LinkTo>
|
||||
<LinkTo @route="adminWebHooks.show" @model={{webHook}} class="btn btn-default no-text">{{d-icon "far-edit"}}</LinkTo>
|
||||
<DButton @class="destroy btn-danger" @action={{action "destroy"}} @actionParam={{webHook}} @icon="times" />
|
||||
</td>
|
||||
</tr>
|
||||
|
|
|
@ -10,9 +10,8 @@ if (security) {
|
|||
.getElementById("security-key-allowed-credential-ids")
|
||||
.value.split(","),
|
||||
(credentialData) => {
|
||||
document.getElementById(
|
||||
"security-key-credential"
|
||||
).value = JSON.stringify(credentialData);
|
||||
document.getElementById("security-key-credential").value =
|
||||
JSON.stringify(credentialData);
|
||||
|
||||
$(e.target).parents("form").submit();
|
||||
},
|
||||
|
|
|
@ -130,7 +130,8 @@ TemplateCompiler.prototype.targetExtension = "js";
|
|||
|
||||
TemplateCompiler.prototype.registerPlugins = function registerPlugins() {};
|
||||
|
||||
TemplateCompiler.prototype.initializeFeatures = function initializeFeatures() {};
|
||||
TemplateCompiler.prototype.initializeFeatures =
|
||||
function initializeFeatures() {};
|
||||
|
||||
TemplateCompiler.prototype.processString = function (string, relativePath) {
|
||||
let filename = relativePath.replace(/^templates\//, "").replace(/\.hbr$/, "");
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
"use strict";
|
||||
|
||||
const WidgetHbsCompiler = require("../../../../lib/javascripts/widget-hbs-compiler")
|
||||
.WidgetHbsCompiler;
|
||||
const WidgetHbsCompiler =
|
||||
require("../../../../lib/javascripts/widget-hbs-compiler").WidgetHbsCompiler;
|
||||
|
||||
const glimmer = require("@glimmer/syntax");
|
||||
|
||||
|
|
|
@ -48,7 +48,8 @@ import userSearch from "discourse/lib/user-search";
|
|||
// Group 3 is optional. group 4 can match images with or without a markdown title.
|
||||
// All matches are whitespace tolerant as long it's still valid markdown.
|
||||
// If the image is inside a code block, we'll ignore it `(?!(.*`))`.
|
||||
const IMAGE_MARKDOWN_REGEX = /!\[(.*?)\|(\d{1,4}x\d{1,4})(,\s*\d{1,3}%)?(.*?)\]\((upload:\/\/.*?)\)(?!(.*`))/g;
|
||||
const IMAGE_MARKDOWN_REGEX =
|
||||
/!\[(.*?)\|(\d{1,4}x\d{1,4})(,\s*\d{1,3}%)?(.*?)\]\((upload:\/\/.*?)\)(?!(.*`))/g;
|
||||
|
||||
let uploadHandlers = [];
|
||||
export function addComposerUploadHandler(extensions, method) {
|
||||
|
@ -565,9 +566,8 @@ export default Component.extend(ComposerUploadUppy, {
|
|||
);
|
||||
|
||||
const scale = event.target.dataset.scale;
|
||||
const matchingPlaceholder = this.get("composer.reply").match(
|
||||
IMAGE_MARKDOWN_REGEX
|
||||
);
|
||||
const matchingPlaceholder =
|
||||
this.get("composer.reply").match(IMAGE_MARKDOWN_REGEX);
|
||||
|
||||
if (matchingPlaceholder) {
|
||||
const match = matchingPlaceholder[index];
|
||||
|
@ -608,9 +608,8 @@ export default Component.extend(ComposerUploadUppy, {
|
|||
|
||||
commitAltText(buttonWrapper) {
|
||||
const index = parseInt(buttonWrapper.getAttribute("data-image-index"), 10);
|
||||
const matchingPlaceholder = this.get("composer.reply").match(
|
||||
IMAGE_MARKDOWN_REGEX
|
||||
);
|
||||
const matchingPlaceholder =
|
||||
this.get("composer.reply").match(IMAGE_MARKDOWN_REGEX);
|
||||
const match = matchingPlaceholder[index];
|
||||
const input = buttonWrapper.querySelector("input.alt-text-input");
|
||||
const replacement = match.replace(
|
||||
|
|
|
@ -51,9 +51,8 @@ export default Component.extend({
|
|||
let userTextFields = document.getElementsByClassName("user-fields")[0];
|
||||
|
||||
if (userTextFields) {
|
||||
userTextFields = userTextFields.getElementsByClassName(
|
||||
"ember-text-field"
|
||||
);
|
||||
userTextFields =
|
||||
userTextFields.getElementsByClassName("ember-text-field");
|
||||
}
|
||||
|
||||
if (userTextFields) {
|
||||
|
@ -76,9 +75,8 @@ export default Component.extend({
|
|||
let userTextFields = document.getElementsByClassName("user-fields")[0];
|
||||
|
||||
if (userTextFields) {
|
||||
userTextFields = userTextFields.getElementsByClassName(
|
||||
"ember-text-field"
|
||||
);
|
||||
userTextFields =
|
||||
userTextFields.getElementsByClassName("ember-text-field");
|
||||
}
|
||||
|
||||
if (userTextFields) {
|
||||
|
|
|
@ -499,9 +499,10 @@ export default Component.extend(TextareaTextManipulation, {
|
|||
return false;
|
||||
}
|
||||
|
||||
const matches = /(?:^|[\s.\?,@\/#!%&*;:\[\]{}=\-_()])(:(?!:).?[\w-]*:?(?!:)(?:t\d?)?:?) ?$/gi.exec(
|
||||
text.substring(0, cp)
|
||||
);
|
||||
const matches =
|
||||
/(?:^|[\s.\?,@\/#!%&*;:\[\]{}=\-_()])(:(?!:).?[\w-]*:?(?!:)(?:t\d?)?:?) ?$/gi.exec(
|
||||
text.substring(0, cp)
|
||||
);
|
||||
|
||||
if (matches && matches[1]) {
|
||||
return [matches[1]];
|
||||
|
|
|
@ -200,9 +200,8 @@ export default Component.extend({
|
|||
}
|
||||
|
||||
focusableElements = focusableElements + ", button:enabled";
|
||||
const firstFocusableElement = innerContainer.querySelectorAll(
|
||||
focusableElements
|
||||
)?.[0];
|
||||
const firstFocusableElement =
|
||||
innerContainer.querySelectorAll(focusableElements)?.[0];
|
||||
const focusableContent = innerContainer.querySelectorAll(focusableElements);
|
||||
const lastFocusableElement = focusableContent[focusableContent.length - 1];
|
||||
|
||||
|
|
|
@ -17,12 +17,9 @@ export default Component.extend({
|
|||
"form.imap_port"
|
||||
)
|
||||
missingSettings(email_username, email_password, imap_server, imap_port) {
|
||||
return [
|
||||
email_username,
|
||||
email_password,
|
||||
imap_server,
|
||||
imap_port,
|
||||
].some((value) => isEmpty(value));
|
||||
return [email_username, email_password, imap_server, imap_port].some(
|
||||
(value) => isEmpty(value)
|
||||
);
|
||||
},
|
||||
|
||||
@discourseComputed("group.imap_mailboxes")
|
||||
|
|
|
@ -17,12 +17,9 @@ export default Component.extend({
|
|||
"form.smtp_port"
|
||||
)
|
||||
missingSettings(email_username, email_password, smtp_server, smtp_port) {
|
||||
return [
|
||||
email_username,
|
||||
email_password,
|
||||
smtp_server,
|
||||
smtp_port,
|
||||
].some((value) => isEmpty(value));
|
||||
return [email_username, email_password, smtp_server, smtp_port].some(
|
||||
(value) => isEmpty(value)
|
||||
);
|
||||
},
|
||||
|
||||
@action
|
||||
|
|
|
@ -206,9 +206,8 @@ export default Controller.extend(ModalFunctionality, {
|
|||
} else {
|
||||
this.set("loggedIn", true);
|
||||
// Trigger the browser's password manager using the hidden static login form:
|
||||
const hiddenLoginForm = document.getElementById(
|
||||
"hidden-login-form"
|
||||
);
|
||||
const hiddenLoginForm =
|
||||
document.getElementById("hidden-login-form");
|
||||
const applyHiddenFormInputValue = (value, key) => {
|
||||
if (!hiddenLoginForm) {
|
||||
return;
|
||||
|
|
|
@ -74,9 +74,10 @@ export default Controller.extend({
|
|||
saveEmail() {
|
||||
this.set("saving", true);
|
||||
|
||||
return (this.new
|
||||
? this.model.addEmail(this.newEmail)
|
||||
: this.model.changeEmail(this.newEmail)
|
||||
return (
|
||||
this.new
|
||||
? this.model.addEmail(this.newEmail)
|
||||
: this.model.changeEmail(this.newEmail)
|
||||
).then(
|
||||
() => {
|
||||
this.set("success", true);
|
||||
|
|
|
@ -781,8 +781,8 @@ export default Controller.extend(bufferedProperty("model"), {
|
|||
Bookmark.create({
|
||||
bookmarkable_id: post.id,
|
||||
bookmarkable_type: "Post",
|
||||
auto_delete_preference: this.currentUser
|
||||
.bookmark_auto_delete_preference,
|
||||
auto_delete_preference:
|
||||
this.currentUser.bookmark_auto_delete_preference,
|
||||
}),
|
||||
post
|
||||
);
|
||||
|
@ -1335,8 +1335,8 @@ export default Controller.extend(bufferedProperty("model"), {
|
|||
Bookmark.create({
|
||||
bookmarkable_id: this.model.id,
|
||||
bookmarkable_type: "Topic",
|
||||
auto_delete_preference: this.currentUser
|
||||
.bookmark_auto_delete_preference,
|
||||
auto_delete_preference:
|
||||
this.currentUser.bookmark_auto_delete_preference,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
|
|
@ -31,11 +31,9 @@ export default Controller.extend({
|
|||
discourseDebounce(
|
||||
this,
|
||||
function () {
|
||||
Invite.findInvitedBy(
|
||||
this.user,
|
||||
this.filter,
|
||||
this.searchTerm
|
||||
).then((invites) => this.set("model", invites));
|
||||
Invite.findInvitedBy(this.user, this.filter, this.searchTerm).then(
|
||||
(invites) => this.set("model", invites)
|
||||
);
|
||||
},
|
||||
INPUT_DELAY
|
||||
);
|
||||
|
|
|
@ -46,8 +46,8 @@ export default function offsetCalculator() {
|
|||
|
||||
const windowHeight = window.innerHeight;
|
||||
const documentHeight = document.body.clientHeight;
|
||||
const topicBottomOffsetTop = document.getElementById("topic-bottom")
|
||||
.offsetTop;
|
||||
const topicBottomOffsetTop =
|
||||
document.getElementById("topic-bottom").offsetTop;
|
||||
|
||||
// the footer is bigger than the window, we can scroll down past the last post
|
||||
if (documentHeight - windowHeight > topicBottomOffsetTop) {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
import { prioritizeNameFallback } from "discourse/lib/settings";
|
||||
import { helperContext } from "discourse-common/lib/helpers";
|
||||
|
||||
export const QUOTE_REGEXP = /\[quote=([^\]]*)\]((?:[\s\S](?!\[quote=[^\]]*\]))*?)\[\/quote\]/im;
|
||||
export const QUOTE_REGEXP =
|
||||
/\[quote=([^\]]*)\]((?:[\s\S](?!\[quote=[^\]]*\]))*?)\[\/quote\]/im;
|
||||
|
||||
// Build the BBCode quote around the selected text
|
||||
export function buildQuote(post, contents, opts = {}) {
|
||||
|
|
|
@ -90,8 +90,8 @@ export default class StickyAvatars {
|
|||
return;
|
||||
}
|
||||
|
||||
const postContentHeight = entry.target.querySelector(".contents")
|
||||
?.clientHeight;
|
||||
const postContentHeight =
|
||||
entry.target.querySelector(".contents")?.clientHeight;
|
||||
if (
|
||||
this.direction === "⬆️" ||
|
||||
postContentHeight > window.innerHeight - headerOffset()
|
||||
|
|
|
@ -127,7 +127,8 @@ export function validateUploadedFile(file, opts) {
|
|||
return true;
|
||||
}
|
||||
|
||||
export const IMAGES_EXTENSIONS_REGEX = /(png|jpe?g|gif|svg|ico|heic|heif|webp)/i;
|
||||
export const IMAGES_EXTENSIONS_REGEX =
|
||||
/(png|jpe?g|gif|svg|ico|heic|heif|webp)/i;
|
||||
|
||||
function extensionsToArray(exts) {
|
||||
return exts
|
||||
|
|
|
@ -51,8 +51,8 @@ export default class UppyMediaOptimization extends UploadPreProcessorPlugin {
|
|||
|
||||
@bind
|
||||
async _optimizeSerial(fileIds) {
|
||||
let optimizeTasks = fileIds.map((fileId) => () =>
|
||||
this._optimizeFile(fileId)
|
||||
let optimizeTasks = fileIds.map(
|
||||
(fileId) => () => this._optimizeFile(fileId)
|
||||
);
|
||||
|
||||
for (const task of optimizeTasks) {
|
||||
|
|
|
@ -199,7 +199,8 @@ function organizeResults(r, options) {
|
|||
// will not find me, which is a reasonable compromise
|
||||
//
|
||||
// we also ignore if we notice a double space or a string that is only a space
|
||||
const ignoreRegex = /([\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*,\/:;<=>?\[\]^`{|}~])|\s\s|^\s$|^[^+]*\+[^@]*$/;
|
||||
const ignoreRegex =
|
||||
/([\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*,\/:;<=>?\[\]^`{|}~])|\s\s|^\s$|^[^+]*\+[^@]*$/;
|
||||
|
||||
export function skipSearch(term, allowEmails, lastSeenUsers = false) {
|
||||
if (lastSeenUsers) {
|
||||
|
|
|
@ -139,13 +139,15 @@ export function highlightPost(postNumber) {
|
|||
|
||||
export function emailValid(email) {
|
||||
// see: http://stackoverflow.com/questions/46155/validate-email-address-in-javascript
|
||||
const re = /^[a-zA-Z0-9!#$%&'*+\/=?\^_`{|}~\-]+(?:\.[a-zA-Z0-9!#$%&'\*+\/=?\^_`{|}~\-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9\-]*[a-zA-Z0-9])?$/;
|
||||
const re =
|
||||
/^[a-zA-Z0-9!#$%&'*+\/=?\^_`{|}~\-]+(?:\.[a-zA-Z0-9!#$%&'\*+\/=?\^_`{|}~\-]+)*@(?:[a-zA-Z0-9](?:[a-zA-Z0-9\-]*[a-zA-Z0-9])?\.)+[a-zA-Z0-9](?:[a-zA-Z0-9\-]*[a-zA-Z0-9])?$/;
|
||||
return re.test(email);
|
||||
}
|
||||
|
||||
export function hostnameValid(hostname) {
|
||||
// see: https://stackoverflow.com/questions/106179/regular-expression-to-match-dns-hostname-or-ip-address
|
||||
const re = /^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)+([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/;
|
||||
const re =
|
||||
/^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)+([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9])$/;
|
||||
return hostname && re.test(hostname);
|
||||
}
|
||||
|
||||
|
@ -457,7 +459,8 @@ export function postRNWebviewMessage(prop, value) {
|
|||
}
|
||||
}
|
||||
|
||||
const CODE_BLOCKS_REGEX = /^( |\t).*|`[^`]+`|^```[^]*?^```|\[code\][^]*?\[\/code\]/gm;
|
||||
const CODE_BLOCKS_REGEX =
|
||||
/^( |\t).*|`[^`]+`|^```[^]*?^```|\[code\][^]*?\[\/code\]/gm;
|
||||
// | ^ | ^ | ^ | ^ |
|
||||
// | | | |
|
||||
// | | | code blocks between [code]
|
||||
|
|
|
@ -125,8 +125,8 @@ export default Mixin.create(ExtendableUploader, UppyS3Multipart, {
|
|||
user: this.currentUser,
|
||||
siteSettings: this.siteSettings,
|
||||
isPrivateMessage,
|
||||
allowStaffToUploadAnyFileInPm: this.siteSettings
|
||||
.allow_staff_to_upload_any_file_in_pm,
|
||||
allowStaffToUploadAnyFileInPm:
|
||||
this.siteSettings.allow_staff_to_upload_any_file_in_pm,
|
||||
};
|
||||
|
||||
const isUploading = validateUploadedFile(currentFile, validationOpts);
|
||||
|
|
|
@ -95,9 +95,10 @@ export default Mixin.create({
|
|||
const post = value.slice(end);
|
||||
|
||||
if (opts && opts.lineVal) {
|
||||
const lineVal = value.split("\n")[
|
||||
value.slice(0, this._textarea.selectionStart).split("\n").length - 1
|
||||
];
|
||||
const lineVal =
|
||||
value.split("\n")[
|
||||
value.slice(0, this._textarea.selectionStart).split("\n").length - 1
|
||||
];
|
||||
return { start, end, value: selVal, pre, post, lineVal };
|
||||
} else {
|
||||
return { start, end, value: selVal, pre, post };
|
||||
|
|
|
@ -81,9 +81,8 @@ Badge.reopenClass({
|
|||
if ("badge_groupings" in json) {
|
||||
json.badge_groupings.forEach(
|
||||
(badgeGroupingJson) =>
|
||||
(badgeGroupings[badgeGroupingJson.id] = BadgeGrouping.create(
|
||||
badgeGroupingJson
|
||||
))
|
||||
(badgeGroupings[badgeGroupingJson.id] =
|
||||
BadgeGrouping.create(badgeGroupingJson))
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -221,8 +221,8 @@ const Category = RestModel.extend({
|
|||
custom_fields: this.custom_fields,
|
||||
topic_template: this.topic_template,
|
||||
all_topics_wiki: this.all_topics_wiki,
|
||||
allow_unlimited_owner_edits_on_first_post: this
|
||||
.allow_unlimited_owner_edits_on_first_post,
|
||||
allow_unlimited_owner_edits_on_first_post:
|
||||
this.allow_unlimited_owner_edits_on_first_post,
|
||||
allowed_tags: this.allowed_tags,
|
||||
allowed_tag_groups: this.allowed_tag_groups,
|
||||
allow_global_tags: this.allow_global_tags,
|
||||
|
|
|
@ -258,8 +258,8 @@ const Group = RestModel.extend({
|
|||
default_notification_level: this.default_notification_level,
|
||||
membership_request_template: this.membership_request_template,
|
||||
publish_read_state: this.publish_read_state,
|
||||
allow_unknown_sender_topic_replies: this
|
||||
.allow_unknown_sender_topic_replies,
|
||||
allow_unknown_sender_topic_replies:
|
||||
this.allow_unknown_sender_topic_replies,
|
||||
};
|
||||
|
||||
["muted", "regular", "watching", "tracking", "watching_first_post"].forEach(
|
||||
|
|
|
@ -26,15 +26,12 @@ export default {
|
|||
const site = Site.current();
|
||||
site.get("filters").forEach((filter) => {
|
||||
const filterCapitalized = capitalize(filter);
|
||||
app[
|
||||
`Discovery${filterCapitalized}Controller`
|
||||
] = DiscoverySortableController.extend();
|
||||
app[
|
||||
`Discovery${filterCapitalized}CategoryController`
|
||||
] = DiscoverySortableController.extend();
|
||||
app[
|
||||
`Discovery${filterCapitalized}CategoryNoneController`
|
||||
] = DiscoverySortableController.extend();
|
||||
app[`Discovery${filterCapitalized}Controller`] =
|
||||
DiscoverySortableController.extend();
|
||||
app[`Discovery${filterCapitalized}CategoryController`] =
|
||||
DiscoverySortableController.extend();
|
||||
app[`Discovery${filterCapitalized}CategoryNoneController`] =
|
||||
DiscoverySortableController.extend();
|
||||
|
||||
if (filter === "top") {
|
||||
app.DiscoveryTopRoute = buildTopicRoute("top", {
|
||||
|
@ -50,12 +47,10 @@ export default {
|
|||
app[`Discovery${filterCapitalized}Route`] = buildTopicRoute(filter);
|
||||
}
|
||||
|
||||
app[`Discovery${filterCapitalized}CategoryRoute`] = buildCategoryRoute(
|
||||
filter
|
||||
);
|
||||
app[
|
||||
`Discovery${filterCapitalized}CategoryNoneRoute`
|
||||
] = buildCategoryRoute(filter, { no_subcategories: true });
|
||||
app[`Discovery${filterCapitalized}CategoryRoute`] =
|
||||
buildCategoryRoute(filter);
|
||||
app[`Discovery${filterCapitalized}CategoryNoneRoute`] =
|
||||
buildCategoryRoute(filter, { no_subcategories: true });
|
||||
});
|
||||
|
||||
app["TagsShowCategoryRoute"] = TagShowRoute.extend();
|
||||
|
@ -70,15 +65,12 @@ export default {
|
|||
app["TagShow" + capitalize(filter) + "Route"] = TagShowRoute.extend({
|
||||
navMode: filter,
|
||||
});
|
||||
app[
|
||||
"TagsShowCategory" + capitalize(filter) + "Route"
|
||||
] = TagShowRoute.extend({ navMode: filter });
|
||||
app[
|
||||
"TagsShowCategoryNone" + capitalize(filter) + "Route"
|
||||
] = TagShowRoute.extend({ navMode: filter, noSubcategories: true });
|
||||
app[
|
||||
"TagsShowCategoryAll" + capitalize(filter) + "Route"
|
||||
] = TagShowRoute.extend({ navMode: filter, noSubcategories: false });
|
||||
app["TagsShowCategory" + capitalize(filter) + "Route"] =
|
||||
TagShowRoute.extend({ navMode: filter });
|
||||
app["TagsShowCategoryNone" + capitalize(filter) + "Route"] =
|
||||
TagShowRoute.extend({ navMode: filter, noSubcategories: true });
|
||||
app["TagsShowCategoryAll" + capitalize(filter) + "Route"] =
|
||||
TagShowRoute.extend({ navMode: filter, noSubcategories: false });
|
||||
});
|
||||
},
|
||||
};
|
||||
|
|
|
@ -48,9 +48,8 @@ export default {
|
|||
|
||||
caps.isiOSPWA = caps.isPwa && caps.isIOS;
|
||||
|
||||
caps.wasLaunchedFromDiscourseHub = window.location.search.includes(
|
||||
"discourse_app=1"
|
||||
);
|
||||
caps.wasLaunchedFromDiscourseHub =
|
||||
window.location.search.includes("discourse_app=1");
|
||||
caps.isAppWebview = window.ReactNativeWebView !== undefined;
|
||||
|
||||
// Inject it
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import Route from "@ember/routing/route";
|
||||
export default Route.extend({
|
||||
setupController(controller) {
|
||||
const accountCreated = this.controllerFor("account-created").get(
|
||||
"accountCreated"
|
||||
);
|
||||
const accountCreated =
|
||||
this.controllerFor("account-created").get("accountCreated");
|
||||
controller.set("accountCreated", accountCreated);
|
||||
controller.set("newEmail", accountCreated.email);
|
||||
},
|
||||
|
|
|
@ -6,9 +6,8 @@ const ForgotPasswordRoute = buildStaticRoute("password-reset");
|
|||
|
||||
ForgotPasswordRoute.reopen({
|
||||
beforeModel() {
|
||||
const loginRequired = this.controllerFor("application").get(
|
||||
"loginRequired"
|
||||
);
|
||||
const loginRequired =
|
||||
this.controllerFor("application").get("loginRequired");
|
||||
this.replaceWith(
|
||||
loginRequired ? "login" : `discovery.${defaultHomepage()}`
|
||||
).then((e) => {
|
||||
|
|
|
@ -73,18 +73,23 @@ export default class MediaOptimizationWorkerService extends Service {
|
|||
width: imageData.width,
|
||||
height: imageData.height,
|
||||
settings: {
|
||||
resize_threshold: this.siteSettings
|
||||
.composer_media_optimization_image_resize_dimensions_threshold,
|
||||
resize_target: this.siteSettings
|
||||
.composer_media_optimization_image_resize_width_target,
|
||||
resize_pre_multiply: this.siteSettings
|
||||
.composer_media_optimization_image_resize_pre_multiply,
|
||||
resize_linear_rgb: this.siteSettings
|
||||
.composer_media_optimization_image_resize_linear_rgb,
|
||||
encode_quality: this.siteSettings
|
||||
.composer_media_optimization_image_encode_quality,
|
||||
debug_mode: this.siteSettings
|
||||
.composer_media_optimization_debug_mode,
|
||||
resize_threshold:
|
||||
this.siteSettings
|
||||
.composer_media_optimization_image_resize_dimensions_threshold,
|
||||
resize_target:
|
||||
this.siteSettings
|
||||
.composer_media_optimization_image_resize_width_target,
|
||||
resize_pre_multiply:
|
||||
this.siteSettings
|
||||
.composer_media_optimization_image_resize_pre_multiply,
|
||||
resize_linear_rgb:
|
||||
this.siteSettings
|
||||
.composer_media_optimization_image_resize_linear_rgb,
|
||||
encode_quality:
|
||||
this.siteSettings
|
||||
.composer_media_optimization_image_encode_quality,
|
||||
debug_mode:
|
||||
this.siteSettings.composer_media_optimization_debug_mode,
|
||||
},
|
||||
},
|
||||
[imageData.data.buffer]
|
||||
|
|
|
@ -293,9 +293,8 @@ export default class PresenceService extends Service {
|
|||
_getInitialData(channelName) {
|
||||
let promiseProxy = this._initialDataRequests[channelName];
|
||||
if (!promiseProxy) {
|
||||
promiseProxy = this._initialDataRequests[
|
||||
channelName
|
||||
] = createPromiseProxy();
|
||||
promiseProxy = this._initialDataRequests[channelName] =
|
||||
createPromiseProxy();
|
||||
}
|
||||
|
||||
once(this, this._makeInitialDataRequest);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
<tbody class="topic-list-body">
|
||||
{{#each this.content as |bookmark|}}
|
||||
<tr class="topic-list-item bookmark-list-item">
|
||||
<td class="main-link topic-list-data" role="rowheader">
|
||||
<th scope="row" class="main-link topic-list-data">
|
||||
<span class="link-top-line">
|
||||
<div class="bookmark-metadata">
|
||||
{{#if bookmark.reminder_at}}
|
||||
|
@ -58,7 +58,7 @@
|
|||
{{/if}}
|
||||
{{!-- template-lint-disable --}}
|
||||
<p class="post-excerpt" {{on "click" this.screenExcerptForExternalLink}}>{{html-safe bookmark.excerpt}}</p>
|
||||
</td>
|
||||
</th>
|
||||
{{#unless this.site.mobileView}}
|
||||
<td class="topic-list-data">
|
||||
{{#if bookmark.user.avatar_template}}
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
{{/if}}
|
||||
|
||||
<div class="control-group bookmark-name-wrap">
|
||||
<Input @id="bookmark-name" @value={{this.model.name}} @name="bookmark-name" class="bookmark-name" @enter={{action "saveAndClose"}} placeholder={{i18n "post.bookmarks.name_placeholder"}} @maxlength="100" />
|
||||
<Input id="bookmark-name" @value={{this.model.name}} name="bookmark-name" class="bookmark-name" @enter={{action "saveAndClose"}} placeholder={{i18n "post.bookmarks.name_placeholder"}} maxlength="100" />
|
||||
<DButton @icon="cog" @action={{action "toggleShowOptions"}} @class="bookmark-options-button" @ariaLabel="post.bookmarks.options" />
|
||||
</div>
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
{{#each this.topics as |t|}}
|
||||
<div class="controls existing-topic">
|
||||
<label class="radio">
|
||||
<Input @id={{concat "choose-topic-" t.id}} @checked={{eq t.id this.selectedTopicId}} @click={{action "chooseTopic" t}} @type="radio" @name="choose_topic_id" />
|
||||
<Input id={{concat "choose-topic-" t.id}} @checked={{eq t.id this.selectedTopicId}} @type="radio" name="choose_topic_id" {{on "click" (action "chooseTopic" t)}} />
|
||||
<TopicStatus @topic={{t}} @disableActions={{true}} />
|
||||
<span class="topic-title">
|
||||
{{replace-emoji t.fancy_title}}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<Input @type={{this.inputType}} class="date-picker" placeholder={{this.placeholder}} @value={{readonly this.value}} @input={{action "onChangeDate"}} @id={{this.inputId}} />
|
||||
<Input @type={{this.inputType}} class="date-picker" placeholder={{this.placeholder}} @value={{readonly this.value}} id={{this.inputId}} {{on "input" (action "onChangeDate")}} />
|
||||
|
||||
{{#unless this.useGlobalPickerContainer}}
|
||||
<div class="picker-container"></div>
|
||||
|
|
|
@ -1 +1 @@
|
|||
<Input @type={{this.inputType}} class="date-picker" placeholder={{this.placeholder}} @value={{this.value}} @autocomplete="off" />
|
||||
<Input @type={{this.inputType}} class="date-picker" placeholder={{this.placeholder}} @value={{this.value}} autocomplete="off" />
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
<section class="field allow-global-tags">
|
||||
<label>
|
||||
<Input @type="checkbox" @checked={{this.category.allow_global_tags}} @id="allow_global_tags" @disabled={{this.disableAllowGlobalTags}} />
|
||||
<Input @type="checkbox" @checked={{this.category.allow_global_tags}} id="allow_global_tags" disabled={{this.disableAllowGlobalTags}} />
|
||||
{{i18n "category.allow_global_tags_label"}}
|
||||
</label>
|
||||
</section>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{{#if this.isActive}}
|
||||
{{!-- template-lint-disable no-invalid-interactive --}}
|
||||
{{!-- template-lint-disable no-invalid-interactive no-down-event-binding --}}
|
||||
<div {{on "keydown" (action "keydown")}} class="emoji-picker {{if this.isActive "opened"}}">
|
||||
{{!-- template-lint-enable no-invalid-interactive --}}
|
||||
{{!-- template-lint-enable no-invalid-interactive no-down-event-binding --}}
|
||||
<div class="emoji-picker-category-buttons">
|
||||
{{#if this.recentEmojis.length}}
|
||||
<button type="button" data-section="recent" {{action "onCategorySelection" "recent"}} class="btn btn-default category-button emoji">
|
||||
|
@ -20,7 +20,7 @@
|
|||
|
||||
<div class="emoji-picker-content">
|
||||
<div class="emoji-picker-search-container">
|
||||
<Input class="filter" @name="filter" @value={{@initialFilter}} placeholder={{i18n "emoji_picker.filter_placeholder"}} @autocomplete="off" @type="search" @autocorrect="off" @autocapitalize="off" @input={{action "onFilterChange"}} />
|
||||
<Input class="filter" name="filter" @value={{@initialFilter}} placeholder={{i18n "emoji_picker.filter_placeholder"}} autocomplete="off" @type="search" autocorrect="off" autocapitalize="off" {{on "input" (action "onFilterChange")}} />
|
||||
|
||||
{{d-icon "search"}}
|
||||
</div>
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
{{i18n "admin.emoji.name"}}
|
||||
</span>
|
||||
<div class="input">
|
||||
<Input @id="emoji-name" @name="name" @placeholderKey="admin.emoji.name" @value={{readonly this.name}} @input={{action (mut this.name) value="target.value"}} />
|
||||
<Input id="emoji-name" name="name" placeholder={{i18n "admin.emoji.name"}} @value={{readonly this.name}} {{on "input" (action (mut this.name) value="target.value")}} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<div class="flag-action-type-details">
|
||||
<span class="description">{{html-safe this.flag.description}}</span>
|
||||
{{#if this.showMessageInput}}
|
||||
<Textarea @name="message" class="flag-message" placeholder={{this.customPlaceholder}} @value={{this.message}} /> <div class="custom-message-length {{this.customMessageLengthClasses}}">{{this.customMessageLength}}</div>
|
||||
<Textarea name="message" class="flag-message" placeholder={{this.customPlaceholder}} @value={{this.message}} /> <div class="custom-message-length {{this.customMessageLengthClasses}}">{{this.customMessageLength}}</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</label>
|
||||
|
@ -26,7 +26,7 @@
|
|||
<div class="description">{{html-safe this.description}}</div>
|
||||
{{/if}}
|
||||
{{#if this.showMessageInput}}
|
||||
<Textarea @name="message" class="flag-message" placeholder={{this.customPlaceholder}} @value={{this.message}} /> <div class="custom-message-length {{this.customMessageLengthClasses}}">{{this.customMessageLength}}</div>
|
||||
<Textarea name="message" class="flag-message" placeholder={{this.customPlaceholder}} @value={{this.message}} /> <div class="custom-message-length {{this.customMessageLengthClasses}}">{{this.customMessageLength}}</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
</label>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
<div class="control-group future-date-input-time-picker">
|
||||
{{d-icon "far-clock"}}
|
||||
<Input placeholder="--:--" @type="time" class="time-input" @value={{this._time}} @disabled={{this.timeInputDisabled}} @input={{action "onChangeTime" value="target.value"}} />
|
||||
<Input placeholder="--:--" @type="time" class="time-input" @value={{this._time}} disabled={{this.timeInputDisabled}} {{on "input" (action "onChangeTime" value="target.value")}} />
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
|
|
@ -3,11 +3,11 @@
|
|||
<div>
|
||||
<div class="control-group">
|
||||
<label for="imap_server">{{i18n "groups.manage.email.credentials.imap_server"}}</label>
|
||||
<Input @type="text" @name="imap_server" @value={{this.form.imap_server}} @tabindex="8" @onChange={{action "resetSettingsValid"}} />
|
||||
<Input @type="text" name="imap_server" @value={{this.form.imap_server}} tabindex="8" {{on "change" (action "resetSettingsValid")}} />
|
||||
</div>
|
||||
|
||||
<label for="enable_ssl_imap">
|
||||
<Input @type="checkbox" @checked={{this.form.imap_ssl}} @id="enable_ssl_imap" @tabindex="11" @onChange={{action "resetSettingsValid"}} />
|
||||
<Input @type="checkbox" @checked={{this.form.imap_ssl}} id="enable_ssl_imap" tabindex="11" {{on "change" (action "resetSettingsValid")}} />
|
||||
{{i18n "groups.manage.email.credentials.imap_ssl"}}
|
||||
</label>
|
||||
</div>
|
||||
|
@ -15,7 +15,7 @@
|
|||
<div>
|
||||
<div class="control-group">
|
||||
<label for="imap_port">{{i18n "groups.manage.email.credentials.imap_port"}}</label>
|
||||
<Input @type="text" @name="imap_port" @value={{this.form.imap_port}} @tabindex="9" @onChange={{action "resetSettingsValid" this.form.imap_port}} />
|
||||
<Input @type="text" name="imap_port" @value={{this.form.imap_port}} tabindex="9" {{on "change" (action "resetSettingsValid" this.form.imap_port)}} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<p>{{i18n "groups.manage.email.smtp_instructions"}}</p>
|
||||
|
||||
<label for="enable_smtp">
|
||||
<Input @type="checkbox" @checked={{this.group.smtp_enabled}} @id="enable_smtp" @change={{action "smtpEnabledChange"}} @tabindex="1" />
|
||||
<Input @type="checkbox" @checked={{this.group.smtp_enabled}} id="enable_smtp" tabindex="1" {{on "change" (action "smtpEnabledChange")}} />
|
||||
{{i18n "groups.manage.email.enable_smtp"}}
|
||||
</label>
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
|||
<div class="alert alert-warning">{{i18n "groups.manage.email.imap_alpha_warning"}}</div>
|
||||
|
||||
<label for="enable_imap">
|
||||
<Input @type="checkbox" @disabled={{not this.enableImapSettings}} @checked={{this.group.imap_enabled}} @id="enable_imap" @change={{action "imapEnabledChange"}} @tabindex="8" />
|
||||
<Input @type="checkbox" disabled={{not this.enableImapSettings}} @checked={{this.group.imap_enabled}} id="enable_imap" tabindex="8" {{on "change" (action "imapEnabledChange")}} />
|
||||
{{i18n "groups.manage.email.enable_imap"}}
|
||||
</label>
|
||||
|
||||
|
@ -37,7 +37,7 @@
|
|||
<div class="control-group">
|
||||
<h3>{{i18n "groups.manage.email.imap_additional_settings"}}</h3>
|
||||
<label class="control-group-inline" for="allow_unknown_sender_topic_replies">
|
||||
<Input @type="checkbox" @name="allow_unknown_sender_topic_replies" @id="allow_unknown_sender_topic_replies" @checked={{this.group.allow_unknown_sender_topic_replies}} @tabindex="13" />
|
||||
<Input @type="checkbox" name="allow_unknown_sender_topic_replies" id="allow_unknown_sender_topic_replies" @checked={{this.group.allow_unknown_sender_topic_replies}} tabindex="13" />
|
||||
<span>{{i18n "groups.manage.email.settings.allow_unknown_sender_topic_replies"}}</span>
|
||||
</label>
|
||||
<p>{{i18n "groups.manage.email.settings.allow_unknown_sender_topic_replies_hint"}}</p>
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
{{#each this.tabs as |tab|}}
|
||||
<li>
|
||||
<LinkTo @route={{tab.route}} @model={{this.group}} @title={{tab.message}} class={{tab.name}}>
|
||||
<LinkTo @route={{tab.route}} @model={{this.group}} title={{tab.message}} class={{tab.name}}>
|
||||
{{#if tab.icon}}{{d-icon tab.icon}}{{/if}}
|
||||
{{tab.message}}
|
||||
{{#if tab.count}}<span class="count">({{tab.count}})</span>{{/if}}
|
||||
|
|
|
@ -3,16 +3,16 @@
|
|||
<div>
|
||||
<div class="control-group">
|
||||
<label for="username">{{i18n "groups.manage.email.credentials.username"}}</label>
|
||||
<Input @type="text" @name="username" @value={{this.form.email_username}} @tabindex="1" @onChange={{action "resetSettingsValid"}} />
|
||||
<Input @type="text" name="username" @value={{this.form.email_username}} tabindex="1" {{on "change" (action "resetSettingsValid")}} />
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label for="smtp_server">{{i18n "groups.manage.email.credentials.smtp_server"}}</label>
|
||||
<Input @type="text" @name="smtp_server" @value={{this.form.smtp_server}} @tabindex="4" @onChange={{action "resetSettingsValid"}} />
|
||||
<Input @type="text" name="smtp_server" @value={{this.form.smtp_server}} tabindex="4" {{on "change" (action "resetSettingsValid")}} />
|
||||
</div>
|
||||
|
||||
<label for="enable_ssl">
|
||||
<Input @type="checkbox" @checked={{this.form.smtp_ssl}} @id="enable_ssl" @tabindex="6" @onChange={{action "resetSettingsValid"}} />
|
||||
<Input @type="checkbox" @checked={{this.form.smtp_ssl}} id="enable_ssl" tabindex="6" {{on "change" (action "resetSettingsValid")}} />
|
||||
{{i18n "groups.manage.email.credentials.smtp_ssl"}}
|
||||
</label>
|
||||
</div>
|
||||
|
@ -20,19 +20,19 @@
|
|||
<div>
|
||||
<div class="control-group">
|
||||
<label for="password">{{i18n "groups.manage.email.credentials.password"}}</label>
|
||||
<Input @type="password" @name="password" @value={{this.form.email_password}} @tabindex="2" @onChange={{action "resetSettingsValid"}} />
|
||||
<Input @type="password" name="password" @value={{this.form.email_password}} tabindex="2" {{on "change" (action "resetSettingsValid")}} />
|
||||
</div>
|
||||
|
||||
<div class="control-group">
|
||||
<label for="smtp_port">{{i18n "groups.manage.email.credentials.smtp_port"}}</label>
|
||||
<Input @type="text" @name="smtp_port" @value={{this.form.smtp_port}} @tabindex="5" @onChange={{action "resetSettingsValid" this.form.smtp_port}} />
|
||||
<Input @type="text" name="smtp_port" @value={{this.form.smtp_port}} tabindex="5" {{on "change" (action "resetSettingsValid" this.form.smtp_port)}} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<div class="control-group">
|
||||
<label for="from_alias">{{i18n "groups.manage.email.settings.from_alias"}}</label>
|
||||
<Input @type="text" @name="from_alias" @id="from_alias" @value={{this.form.email_from_alias}} @onChange={{action "resetSettingsValid"}} @tabindex="3" />
|
||||
<Input @type="text" name="from_alias" id="from_alias" @value={{this.form.email_from_alias}} {{on "change" (action "resetSettingsValid")}} tabindex="3" />
|
||||
<p>{{i18n "groups.manage.email.settings.from_alias_hint"}}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<label class="control-label">{{i18n "groups.manage.membership.access"}}</label>
|
||||
|
||||
<label>
|
||||
<Input @type="checkbox" class="group-form-public-admission" @checked={{this.model.public_admission}} @disabled={{this.disablePublicSetting}} />
|
||||
<Input @type="checkbox" class="group-form-public-admission" @checked={{this.model.public_admission}} disabled={{this.disablePublicSetting}} />
|
||||
|
||||
{{i18n "groups.public_admission"}}
|
||||
</label>
|
||||
|
@ -14,7 +14,7 @@
|
|||
</label>
|
||||
|
||||
<label>
|
||||
<Input @type="checkbox" class="group-form-allow-membership-requests" @checked={{this.model.allow_membership_requests}} @disabled={{this.disableMembershipRequestSetting}} />
|
||||
<Input @type="checkbox" class="group-form-allow-membership-requests" @checked={{this.model.allow_membership_requests}} disabled={{this.disableMembershipRequestSetting}} />
|
||||
|
||||
{{i18n "groups.allow_membership_requests"}}
|
||||
</label>
|
||||
|
@ -68,7 +68,7 @@
|
|||
{{i18n "admin.groups.default_title"}}
|
||||
</label>
|
||||
|
||||
<Input @value={{this.model.title}} @name="title" class="input-xxlarge" />
|
||||
<Input @value={{this.model.title}} name="title" class="input-xxlarge" />
|
||||
|
||||
<div class="control-instructions">
|
||||
{{i18n "admin.groups.default_title_description"}}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
{{yield}}
|
|
@ -1 +0,0 @@
|
|||
{{yield}}
|
|
@ -1,4 +1,4 @@
|
|||
<label class="checkbox-label">
|
||||
<Input @type="checkbox" @disabled={{this.disabled}} @checked={{this.checked}} />
|
||||
<Input @type="checkbox" disabled={{this.disabled}} @checked={{this.checked}} />
|
||||
{{this.label}}
|
||||
</label>
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
{{#if this.siteSettings.enable_fast_edit}}
|
||||
{{#if this._displayFastEditInput}}
|
||||
<div class="fast-edit-container">
|
||||
<Textarea @id="fast-edit-input" @value={{this._fastEditNewSelection}} /> <DButton @action={{action "_saveFastEdit"}} @class="btn-small btn-primary save-fast-edit" @icon="pencil-alt" @label="composer.save_edit" @translatedTitle={{this._saveEditButtonTitle}} @disabled={{this._saveFastEditDisabled}} @isLoading={{this._isSavingFastEdit}} />
|
||||
<Textarea id="fast-edit-input" @value={{this._fastEditNewSelection}} /> <DButton @action={{action "_saveFastEdit"}} @class="btn-small btn-primary save-fast-edit" @icon="pencil-alt" @label="composer.save_edit" @translatedTitle={{this._saveEditButtonTitle}} @disabled={{this._saveFastEditDisabled}} @isLoading={{this._isSavingFastEdit}} />
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<div class="relative-time-picker">
|
||||
<Input class="relative-time-duration" @min={{this.durationMin}} @step={{this.durationStep}} @type="number" @value={{this.duration}} @onChange={{action "onChangeDuration"}} @id={{this.id}} />
|
||||
<Input class="relative-time-duration" min={{this.durationMin}} step={{this.durationStep}} @type="number" @value={{this.duration}} {{on "change" (action "onChangeDuration")}} id={{this.id}} />
|
||||
<ComboBox @content={{this.intervals}} @value={{this.selectedInterval}} @class="relative-time-intervals" @onChange={{action "onChangeInterval"}} />
|
||||
</div>
|
||||
|
|
|
@ -1 +1 @@
|
|||
<Input @value={{this.value}} @change={{this.valueChanged}} class="reviewable-input-text" />
|
||||
<Input @value={{this.value}} class="reviewable-input-text" {{on "change" this.valueChanged}} />
|
||||
|
|
|
@ -1 +1 @@
|
|||
<Textarea @value={{this.value}} @change={{this.valueChanged}} class="reviewable-input-textarea" />
|
||||
<Textarea @value={{this.value}} {{on "change" this.valueChanged}} class="reviewable-input-textarea" />
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
{{#if this.showAllTagsCheckbox}}
|
||||
<section class="field">
|
||||
<label>
|
||||
<Input @type="checkbox" class="all-tags" @checked={{this.searchedTerms.special.all_tags}} @click={{action "onChangeSearchTermForAllTags" value="target.checked"}} />
|
||||
<Input @type="checkbox" class="all-tags" @checked={{this.searchedTerms.special.all_tags}} {{on "click" (action "onChangeSearchTermForAllTags" value="target.checked")}} />
|
||||
{{i18n "search.advanced.filters.all_tags"}}
|
||||
</label>
|
||||
</section>
|
||||
|
@ -39,24 +39,24 @@
|
|||
|
||||
{{#if this.currentUser}}
|
||||
<div class="grouped-control-field">
|
||||
<Input @id="matching-title-only" @type="checkbox" class="in-title" @checked={{this.searchedTerms.special.in.title}} @click={{action "onChangeSearchTermForSpecialInTitle" value="target.checked"}} />
|
||||
<Input id="matching-title-only" @type="checkbox" class="in-title" @checked={{this.searchedTerms.special.in.title}} {{on "click" (action "onChangeSearchTermForSpecialInTitle" value="target.checked")}} />
|
||||
<label for="matching-title-only">
|
||||
{{i18n "search.advanced.filters.title"}}
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="grouped-control-field">
|
||||
<Input @id="matching-liked" @type="checkbox" class="in-likes" @checked={{this.searchedTerms.special.in.likes}} @click={{action "onChangeSearchTermForSpecialInLikes" value="target.checked"}} />
|
||||
<Input id="matching-liked" @type="checkbox" class="in-likes" @checked={{this.searchedTerms.special.in.likes}} {{on "click" (action "onChangeSearchTermForSpecialInLikes" value="target.checked")}} />
|
||||
<label for="matching-liked">{{i18n "search.advanced.filters.likes"}}</label>
|
||||
</div>
|
||||
|
||||
<div class="grouped-control-field">
|
||||
<Input @id="matching-in-messages" @type="checkbox" class="in-private" @checked={{this.searchedTerms.special.in.messages}} @click={{action "onChangeSearchTermForSpecialInMessages" value="target.checked"}} />
|
||||
<Input id="matching-in-messages" @type="checkbox" class="in-private" @checked={{this.searchedTerms.special.in.messages}} {{on "click" (action "onChangeSearchTermForSpecialInMessages" value="target.checked")}} />
|
||||
<label for="matching-in-messages">{{i18n "search.advanced.filters.private"}}</label>
|
||||
</div>
|
||||
|
||||
<div class="grouped-control-field">
|
||||
<Input @id="matching-seen" @type="checkbox" class="in-seen" @checked={{this.searchedTerms.special.in.seen}} @click={{action "onChangeSearchTermForSpecialInSeen" value="target.checked"}} />
|
||||
<Input id="matching-seen" @type="checkbox" class="in-seen" @checked={{this.searchedTerms.special.in.seen}} {{on "click" (action "onChangeSearchTermForSpecialInSeen" value="target.checked")}} />
|
||||
<label for="matching-seen">{{i18n "search.advanced.filters.seen"}}</label>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
@ -114,9 +114,9 @@
|
|||
{{!-- TODO: Using a label here fails no-nested-interactive lint rule --}}
|
||||
<span class="control-label">{{i18n "search.advanced.post.count.label"}}</span>
|
||||
<div class="controls">
|
||||
<Input @type="number" @value={{readonly this.searchedTerms.min_posts}} class="input-small" @id="search-min-post-count" @input={{action "onChangeSearchTermMinPostCount" value="target.value"}} placeholder={{i18n "search.advanced.post.min.placeholder"}} @aria-label={{i18n "search.advanced.post.min.aria_label"}} />
|
||||
<Input @type="number" @value={{readonly this.searchedTerms.min_posts}} class="input-small" id="search-min-post-count" placeholder={{i18n "search.advanced.post.min.placeholder"}} aria-label={{i18n "search.advanced.post.min.aria_label"}} {{on "input" (action "onChangeSearchTermMinPostCount" value="target.value")}} />
|
||||
{{d-icon "arrows-alt-h"}}
|
||||
<Input @type="number" @value={{readonly this.searchedTerms.max_posts}} class="input-small" @id="search-max-post-count" @input={{action "onChangeSearchTermMaxPostCount" value="target.value"}} placeholder={{i18n "search.advanced.post.max.placeholder"}} @aria-label={{i18n "search.advanced.post.max.aria_label"}} />
|
||||
<Input @type="number" @value={{readonly this.searchedTerms.max_posts}} class="input-small" id="search-max-post-count" placeholder={{i18n "search.advanced.post.max.placeholder"}} aria-label={{i18n "search.advanced.post.max.aria_label"}} {{on "input" (action "onChangeSearchTermMaxPostCount" value="target.value")}} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -124,9 +124,9 @@
|
|||
{{!-- TODO: Using a label here fails no-nested-interactive lint rule --}}
|
||||
<span class="control-label">{{i18n "search.advanced.views.label"}}</span>
|
||||
<div class="controls">
|
||||
<Input @type="number" @value={{readonly this.searchedTerms.min_views}} class="input-small" @id="search-min-views" @input={{action "onChangeSearchTermMinViews" value="target.value"}} placeholder={{i18n "search.advanced.min_views.placeholder"}} @aria-label={{i18n "search.advanced.min_views.aria_label"}} />
|
||||
<Input @type="number" @value={{readonly this.searchedTerms.min_views}} class="input-small" id="search-min-views" placeholder={{i18n "search.advanced.min_views.placeholder"}} aria-label={{i18n "search.advanced.min_views.aria_label"}} {{on "input" (action "onChangeSearchTermMinViews" value="target.value")}} />
|
||||
{{d-icon "arrows-alt-h"}}
|
||||
<Input @type="number" @value={{readonly this.searchedTerms.max_views}} class="input-small" @id="search-max-views" @input={{action "onChangeSearchTermMaxViews" value="target.value"}} placeholder={{i18n "search.advanced.max_views.placeholder"}} @aria-label={{i18n "search.advanced.max_views.aria_label"}} />
|
||||
<Input @type="number" @value={{readonly this.searchedTerms.max_views}} class="input-small" id="search-max-views" placeholder={{i18n "search.advanced.max_views.placeholder"}} aria-label={{i18n "search.advanced.max_views.aria_label"}} {{on "input" (action "onChangeSearchTermMaxViews" value="target.value")}} />
|
||||
</div>
|
||||
</div>
|
||||
</details>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
@route={{@headerRoute}}
|
||||
@query={{@headerQuery}}
|
||||
@models={{if @headerModel (array @headerModel) (if @headerModels @headerModels (array))}}
|
||||
@class="sidebar-section-header-link"
|
||||
class="sidebar-section-header-link"
|
||||
title={{@headerLinkTitle}}>
|
||||
|
||||
{{@headerLinkText}}
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
<section class="group-one-per-topic">
|
||||
<label>
|
||||
<Input @type="checkbox" @checked={{this.buffered.one_per_topic}} @name="onepertopic" />
|
||||
<Input @type="checkbox" @checked={{this.buffered.one_per_topic}} name="onepertopic" />
|
||||
{{i18n "tagging.groups.one_per_topic_label"}}
|
||||
</label>
|
||||
</section>
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
</div>
|
||||
<div class="tap-tile-time-input">
|
||||
{{d-icon "far-clock"}}
|
||||
<Input placeholder="--:--" @id="custom-time" @type="time" class="time-input" @value={{this.customTime}} />
|
||||
<Input placeholder="--:--" id="custom-time" @type="time" class="time-input" @value={{this.customTime}} />
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group custom-date-time-wrap custom-relative-wrap">
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
<div class="controls">
|
||||
<label class="control-label checkbox-label">
|
||||
<Input @id={{concat "user-" this.elementId}} @checked={{this.value}} @type="checkbox" />
|
||||
<Input id={{concat "user-" this.elementId}} @checked={{this.value}} @type="checkbox" />
|
||||
<span>
|
||||
{{html-safe this.field.description}} {{#unless this.field.name}}{{#if this.field.required}}<span class="required">*</span>{{/if}}{{/unless}}
|
||||
</span>
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
{{#if this.field.required}}<span class="required">*</span>{{/if}}
|
||||
</label>
|
||||
<div class="controls">
|
||||
<Input @id={{concat "user-" this.elementId}} @value={{this.value}} @maxlength={{this.site.user_field_max_length}} />
|
||||
<Input id={{concat "user-" this.elementId}} @value={{this.value}} maxlength={{this.site.user_field_max_length}} />
|
||||
<div class="instructions">{{html-safe this.field.description}}</div>
|
||||
</div>
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
{{#if this.context}}
|
||||
<div class="search-context">
|
||||
<label>
|
||||
<Input @type="checkbox" @name="searchContext" @checked={{this.searchContextEnabled}} /> {{this.searchContextDescription}}
|
||||
<Input @type="checkbox" name="searchContext" @checked={{this.searchContextEnabled}} /> {{this.searchContextDescription}}
|
||||
</label>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
<tr>
|
||||
{{#if this.isBulk}}
|
||||
<td class="bulk-select">
|
||||
<Input @type="checkbox" class="bulk-select" @click={{action "selectMember" m}} />
|
||||
<Input @type="checkbox" class="bulk-select" {{on "click" (action "selectMember" m)}} />
|
||||
</td>
|
||||
{{/if}}
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
{{/if}}
|
||||
|
||||
<div class="groups-header-filters">
|
||||
<Input @value={{readonly this.filter}} @placeholderKey="groups.index.all" class="groups-header-filters-name no-blur" @input={{action "onFilterChanged" value="target.value"}} />
|
||||
<Input @value={{readonly this.filter}} placeholder={{i18n "groups.index.all"}} class="groups-header-filters-name no-blur" {{on "input" (action "onFilterChanged" value="target.value")}} />
|
||||
|
||||
<ComboBox @value={{this.type}} @content={{this.types}} @class="groups-header-filters-type" @onChange={{action (mut this.type)}} @options={{hash
|
||||
clearable=true
|
||||
|
@ -22,7 +22,7 @@
|
|||
<div class="container">
|
||||
<div class="groups-boxes">
|
||||
{{#each this.groups as |group|}}
|
||||
<LinkTo @route="group.members" @model={{group.name}} @classNames={{concat "group-box " group.name}}>
|
||||
<LinkTo @route="group.members" @model={{group.name}} class={{concat "group-box " group.name}}>
|
||||
<div class="group-box-inner">
|
||||
<div class="group-info-wrapper">
|
||||
{{#if group.flair_url}}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue