DEV: Convert admin-watched-word to glimmer/gjs/dbutton (#28340)
This commit is contained in:
parent
41593a5d7d
commit
eccfc946f1
|
@ -0,0 +1,60 @@
|
|||
import Component from "@glimmer/component";
|
||||
import { action } from "@ember/object";
|
||||
import { service } from "@ember/service";
|
||||
import { eq, or } from "truth-helpers";
|
||||
import DButton from "discourse/components/d-button";
|
||||
import i18n from "discourse-common/helpers/i18n";
|
||||
|
||||
export default class AdminWatchedWord extends Component {
|
||||
@service dialog;
|
||||
|
||||
get tags() {
|
||||
return this.args.word.replacement.replacement.split(",");
|
||||
}
|
||||
|
||||
@action
|
||||
async deleteWord() {
|
||||
try {
|
||||
await this.args.word.destroy();
|
||||
this.args.action(this.args.word);
|
||||
} catch (e) {
|
||||
this.dialog.alert(
|
||||
i18n("generic_error_with_reason", {
|
||||
error: `http: ${e.status} - ${e.body}`,
|
||||
})
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
<template>
|
||||
<div class="watched-word">
|
||||
<DButton
|
||||
@action={{this.deleteWord}}
|
||||
@icon="times"
|
||||
class="btn-transparent delete-word-record"
|
||||
/>
|
||||
|
||||
<span>{{@word.word}}</span>
|
||||
|
||||
{{#if (or (eq @actionKey "replace") (eq @actionKey "link"))}}
|
||||
→
|
||||
<span class="replacement">{{@word.replacement}}</span>
|
||||
{{else if (eq @actionKey "tag")}}
|
||||
→
|
||||
{{#each this.tags as |tag|}}
|
||||
<span class="tag">{{tag}}</span>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
|
||||
{{#if @word.case_sensitive}}
|
||||
<span class="case-sensitive">
|
||||
{{i18n "admin.watched_words.case_sensitive"}}
|
||||
</span>
|
||||
{{/if}}
|
||||
|
||||
{{#if @word.html}}
|
||||
<span class="html">{{i18n "admin.watched_words.html"}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
</template>
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
<span
|
||||
role="button"
|
||||
onclick={{this.deleteWord}}
|
||||
class="delete-word-record"
|
||||
>{{d-icon "times"}}</span>
|
||||
{{this.word.word}}
|
||||
{{#if (or this.isReplace this.isLink)}}
|
||||
→
|
||||
<span class="replacement">{{this.word.replacement}}</span>
|
||||
{{else if this.isTag}}
|
||||
→
|
||||
{{#each this.tags as |tag|}}
|
||||
<span class="tag">{{tag}}</span>
|
||||
{{/each}}
|
||||
{{/if}}
|
||||
{{#if this.isCaseSensitive}}
|
||||
<span class="case-sensitive">{{i18n
|
||||
"admin.watched_words.case_sensitive"
|
||||
}}</span>
|
||||
{{/if}}
|
||||
{{#if this.isHtml}}
|
||||
<span class="html">{{i18n "admin.watched_words.html"}}</span>
|
||||
{{/if}}
|
|
@ -1,39 +0,0 @@
|
|||
import Component from "@ember/component";
|
||||
import { action } from "@ember/object";
|
||||
import { alias, equal } from "@ember/object/computed";
|
||||
import { service } from "@ember/service";
|
||||
import { classNames } from "@ember-decorators/component";
|
||||
import discourseComputed from "discourse-common/utils/decorators";
|
||||
import I18n from "discourse-i18n";
|
||||
|
||||
@classNames("watched-word")
|
||||
export default class AdminWatchedWord extends Component {
|
||||
@service dialog;
|
||||
|
||||
@equal("actionKey", "replace") isReplace;
|
||||
@equal("actionKey", "tag") isTag;
|
||||
@equal("actionKey", "link") isLink;
|
||||
@alias("word.case_sensitive") isCaseSensitive;
|
||||
@alias("word.html") isHtml;
|
||||
|
||||
@discourseComputed("word.replacement")
|
||||
tags(replacement) {
|
||||
return replacement.split(",");
|
||||
}
|
||||
|
||||
@action
|
||||
deleteWord() {
|
||||
this.word
|
||||
.destroy()
|
||||
.then(() => {
|
||||
this.action(this.word);
|
||||
})
|
||||
.catch((e) => {
|
||||
this.dialog.alert(
|
||||
I18n.t("generic_error_with_reason", {
|
||||
error: `http: ${e.status} - ${e.body}`,
|
||||
})
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
|
@ -63,11 +63,13 @@
|
|||
{{#if this.showWordsList}}
|
||||
<div class="watched-words-list watched-words-{{this.actionNameKey}}">
|
||||
{{#each this.currentAction.words as |word|}}
|
||||
<div class="watched-word-box"><AdminWatchedWord
|
||||
<div class="watched-word-box">
|
||||
<AdminWatchedWord
|
||||
@actionKey={{this.actionNameKey}}
|
||||
@word={{word}}
|
||||
@action={{action "recordRemoved"}}
|
||||
/></div>
|
||||
/>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{/if}}
|
|
@ -2,8 +2,6 @@ import { click, fillIn, triggerKeyEvent, visit } from "@ember/test-helpers";
|
|||
import { test } from "qunit";
|
||||
import {
|
||||
acceptance,
|
||||
count,
|
||||
exists,
|
||||
query,
|
||||
queryAll,
|
||||
} from "discourse/tests/helpers/qunit-helpers";
|
||||
|
@ -15,49 +13,47 @@ acceptance("Admin - Watched Words", function (needs) {
|
|||
test("list words in groups", async function (assert) {
|
||||
await visit("/admin/customize/watched_words/action/block");
|
||||
|
||||
assert.ok(!exists(".admin-watched-words .alert-error"));
|
||||
assert.dom(".admin-watched-words .alert-error").doesNotExist();
|
||||
|
||||
assert.ok(
|
||||
!exists(".watched-words-list"),
|
||||
"Don't show bad words by default."
|
||||
);
|
||||
assert
|
||||
.dom(".watched-words-list")
|
||||
.doesNotExist("Don't show bad words by default.");
|
||||
|
||||
assert.ok(
|
||||
!exists(".watched-words-list .watched-word"),
|
||||
"Don't show bad words by default."
|
||||
);
|
||||
assert
|
||||
.dom(".watched-words-list .watched-word")
|
||||
.doesNotExist("Don't show bad words by default.");
|
||||
|
||||
await fillIn(".admin-controls .controls input[type=text]", "li");
|
||||
|
||||
assert.strictEqual(
|
||||
count(".watched-words-list .watched-word"),
|
||||
1,
|
||||
"When filtering, show words even if checkbox is unchecked."
|
||||
);
|
||||
assert
|
||||
.dom(".watched-words-list .watched-word")
|
||||
.exists(
|
||||
{ count: 1 },
|
||||
"When filtering, show words even if checkbox is unchecked."
|
||||
);
|
||||
|
||||
await fillIn(".admin-controls .controls input[type=text]", "");
|
||||
|
||||
assert.ok(
|
||||
!exists(".watched-words-list .watched-word"),
|
||||
"Clearing the filter hides words again."
|
||||
);
|
||||
assert
|
||||
.dom(".watched-words-list .watched-word")
|
||||
.doesNotExist("Clearing the filter hides words again.");
|
||||
|
||||
await click(".show-words-checkbox");
|
||||
|
||||
assert.ok(
|
||||
exists(".watched-words-list .watched-word"),
|
||||
"Always show the words when checkbox is checked."
|
||||
);
|
||||
assert
|
||||
.dom(".watched-words-list .watched-word")
|
||||
.exists("Always show the words when checkbox is checked.");
|
||||
|
||||
await click(".nav-stacked .censor a");
|
||||
|
||||
assert.ok(exists(".watched-words-list"));
|
||||
assert.ok(!exists(".watched-words-list .watched-word"), "Empty word list.");
|
||||
assert.dom(".watched-words-list").exists();
|
||||
assert
|
||||
.dom(".watched-words-list .watched-word")
|
||||
.doesNotExist("Empty word list.");
|
||||
});
|
||||
|
||||
test("add words", async function (assert) {
|
||||
await visit("/admin/customize/watched_words/action/block");
|
||||
const submitButton = query(".watched-word-form button");
|
||||
|
||||
await click(".show-words-checkbox");
|
||||
await click(".select-kit-header.multi-select-header");
|
||||
|
@ -68,33 +64,26 @@ acceptance("Admin - Watched Words", function (needs) {
|
|||
await fillIn(".select-kit-filter input", "cheese");
|
||||
await triggerKeyEvent(".select-kit-filter input", "keydown", "Enter");
|
||||
|
||||
assert.equal(
|
||||
query(".select-kit-header-wrapper .formatted-selection").innerText,
|
||||
"poutine, cheese",
|
||||
"has the correct words in the input field"
|
||||
assert
|
||||
.dom(".select-kit-header-wrapper .formatted-selection")
|
||||
.hasText("poutine, cheese", "has the correct words in the input field");
|
||||
|
||||
await click(".watched-word-form .btn-primary");
|
||||
|
||||
const words = [...queryAll(".watched-words-list .watched-word span")].map(
|
||||
(elem) => elem.innerText.trim()
|
||||
);
|
||||
|
||||
await click(submitButton);
|
||||
|
||||
const words = [...queryAll(".watched-words-list .watched-word")].map(
|
||||
(elem) => {
|
||||
return elem.innerText.trim();
|
||||
}
|
||||
);
|
||||
|
||||
assert.ok(words.includes("poutine"), "has word 'poutine'");
|
||||
assert.ok(words.includes("cheese"), "has word 'cheese'");
|
||||
assert.equal(count(".watched-words-list .case-sensitive"), 0);
|
||||
assert.true(words.includes("poutine"), "has word 'poutine'");
|
||||
assert.true(words.includes("cheese"), "has word 'cheese'");
|
||||
assert.dom(".watched-words-list .case-sensitive").doesNotExist();
|
||||
});
|
||||
|
||||
test("add case-sensitive words", async function (assert) {
|
||||
await visit("/admin/customize/watched_words/action/block");
|
||||
const submitButton = query(".watched-word-form button");
|
||||
assert.strictEqual(
|
||||
submitButton.disabled,
|
||||
true,
|
||||
"Add button is disabled by default"
|
||||
);
|
||||
assert
|
||||
.dom(".watched-word-form .btn-primary")
|
||||
.isDisabled("Add button is disabled by default");
|
||||
await click(".show-words-checkbox");
|
||||
|
||||
await click(".select-kit-header.multi-select-header");
|
||||
|
@ -102,62 +91,61 @@ acceptance("Admin - Watched Words", function (needs) {
|
|||
await triggerKeyEvent(".select-kit-filter input", "keydown", "Enter");
|
||||
|
||||
await click(".case-sensitivity-checkbox");
|
||||
assert.strictEqual(
|
||||
submitButton.disabled,
|
||||
false,
|
||||
"Add button should no longer be disabled after input is filled"
|
||||
);
|
||||
await click(submitButton);
|
||||
|
||||
assert
|
||||
.dom(".watched-words-list .watched-word")
|
||||
.hasText(`Discourse ${I18n.t("admin.watched_words.case_sensitive")}`);
|
||||
.dom(".watched-word-form .btn-primary")
|
||||
.isEnabled(
|
||||
"Add button should no longer be disabled after input is filled"
|
||||
);
|
||||
|
||||
await click(".watched-word-form .btn-primary");
|
||||
assert
|
||||
.dom(".watched-words-list .watched-word span:first-of-type")
|
||||
.hasText("Discourse");
|
||||
assert
|
||||
.dom(".watched-words-list .watched-word .case-sensitive")
|
||||
.hasText(I18n.t("admin.watched_words.case_sensitive"));
|
||||
|
||||
await click(".select-kit-header.multi-select-header");
|
||||
await fillIn(".select-kit-filter input", "discourse");
|
||||
await triggerKeyEvent(".select-kit-filter input", "keydown", "Enter");
|
||||
await click(".case-sensitivity-checkbox");
|
||||
await click(submitButton);
|
||||
await click(".watched-word-form .btn-primary");
|
||||
|
||||
assert
|
||||
.dom(".watched-words-list .watched-word")
|
||||
.hasText(`discourse ${I18n.t("admin.watched_words.case_sensitive")}`);
|
||||
.dom(".watched-words-list .watched-word span:first-of-type")
|
||||
.hasText("discourse");
|
||||
assert
|
||||
.dom(".watched-words-list .watched-word .case-sensitive")
|
||||
.hasText(I18n.t("admin.watched_words.case_sensitive"));
|
||||
});
|
||||
|
||||
test("remove words", async function (assert) {
|
||||
await visit("/admin/customize/watched_words/action/block");
|
||||
await click(".show-words-checkbox");
|
||||
|
||||
let wordId = null;
|
||||
assert.dom(".watched-words-list .watched-word").exists({ count: 3 });
|
||||
|
||||
[...queryAll(".watched-words-list .watched-word")].forEach((elem) => {
|
||||
if (elem.innerText.trim() === "anise") {
|
||||
wordId = elem.getAttribute("id");
|
||||
}
|
||||
});
|
||||
await click(`.delete-word-record`);
|
||||
|
||||
await click(`#${wordId} .delete-word-record`);
|
||||
|
||||
assert.strictEqual(count(".watched-words-list .watched-word"), 2);
|
||||
assert.dom(".watched-words-list .watched-word").exists({ count: 2 });
|
||||
});
|
||||
|
||||
test("test modal - replace", async function (assert) {
|
||||
await visit("/admin/customize/watched_words/action/replace");
|
||||
await click(".watched-word-test");
|
||||
await fillIn(".d-modal__body textarea", "Hi there!");
|
||||
assert.strictEqual(query(".d-modal__body li .match").innerText, "Hi");
|
||||
assert.strictEqual(
|
||||
query(".d-modal__body li .replacement").innerText,
|
||||
"hello"
|
||||
);
|
||||
|
||||
assert.dom(".d-modal__body li .match").hasText("Hi");
|
||||
assert.dom(".d-modal__body li .replacement").hasText("hello");
|
||||
});
|
||||
|
||||
test("test modal - tag", async function (assert) {
|
||||
await visit("/admin/customize/watched_words/action/tag");
|
||||
await click(".watched-word-test");
|
||||
await fillIn(".d-modal__body textarea", "Hello world!");
|
||||
assert.strictEqual(query(".d-modal__body li .match").innerText, "Hello");
|
||||
assert.strictEqual(query(".d-modal__body li .tag").innerText, "greeting");
|
||||
|
||||
assert.dom(".d-modal__body li .match").hasText("Hello");
|
||||
assert.dom(".d-modal__body li .tag").hasText("greeting");
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -176,13 +164,14 @@ acceptance("Admin - Watched Words - Emoji Replacement", function (needs) {
|
|||
await visit("/t/internationalization-localization/280");
|
||||
await click("button.reply-to-post");
|
||||
await fillIn(".d-editor-input", "betis betis betis");
|
||||
|
||||
const cooked = query(".d-editor-preview p");
|
||||
const cookedChildren = Array.from(cooked.children);
|
||||
const emojis = cookedChildren.filter((child) => child.nodeName === "IMG");
|
||||
|
||||
assert.strictEqual(emojis.length, 3, "three emojis have been rendered");
|
||||
assert.strictEqual(
|
||||
assert.true(
|
||||
emojis.every((emoji) => emoji.title === ":poop:"),
|
||||
true,
|
||||
"all emojis are :poop:"
|
||||
);
|
||||
});
|
||||
|
@ -215,6 +204,6 @@ acceptance("Admin - Watched Words - Bad regular expressions", function (needs) {
|
|||
|
||||
test("shows an error message if regex is invalid", async function (assert) {
|
||||
await visit("/admin/customize/watched_words/action/block");
|
||||
assert.strictEqual(count(".admin-watched-words .alert-error"), 1);
|
||||
assert.dom(".admin-watched-words .alert-error").exists({ count: 1 });
|
||||
});
|
||||
});
|
||||
|
|
|
@ -294,13 +294,8 @@ table.screened-ip-addresses {
|
|||
display: inline-block;
|
||||
cursor: pointer;
|
||||
|
||||
.d-icon {
|
||||
margin-right: 0.25em;
|
||||
color: var(--primary-medium);
|
||||
|
||||
&:hover {
|
||||
color: var(--danger);
|
||||
}
|
||||
.delete-word-record:hover {
|
||||
color: var(--danger);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue