mirror of
https://github.com/wassname/talk.git
synced 2026-09-12 13:01:11 +08:00
[CORL-1029] Better HTML Support (#2956)
* feat: Improve html handling, integrate new @coralproject/rte * chore: refactor and add comments * chore: remove obsolete line * chore: rename `inputId` to `inputID` * chore: upgrade @coralproject/rte * fix: update snapshots * chore: apply review suggestions * fix: snapshot / tests * fix: merge issues * [CORL-1056] Configurable RTE (#2967) * fix: merge issues * feat: Configure RTE * test: add tests * chore: just a comment * chore: remove unused translations
This commit is contained in:
@@ -551,6 +551,163 @@ here:
|
||||
</fieldset>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset
|
||||
className="FieldSet-root Box-root ConfigBox-root"
|
||||
>
|
||||
<div
|
||||
className="Box-root Flex-root ConfigBox-title Flex-flex Flex-justifySpaceBetween"
|
||||
>
|
||||
<div>
|
||||
<legend
|
||||
className="Header-root"
|
||||
>
|
||||
Rich-text comments
|
||||
</legend>
|
||||
</div>
|
||||
<div />
|
||||
</div>
|
||||
<div
|
||||
className="ConfigBox-content"
|
||||
>
|
||||
<fieldset
|
||||
className="FieldSet-root Box-root HorizontalGutter-root HorizontalGutter-spacing-4"
|
||||
>
|
||||
<p
|
||||
className="FormFieldDescription-root"
|
||||
>
|
||||
Give your community more ways to express themselves beyond plain text with rich-text formatting.
|
||||
</p>
|
||||
<fieldset
|
||||
className="Box-root HorizontalGutter-root FormField-root HorizontalGutter-spacing-2"
|
||||
>
|
||||
<label
|
||||
className="Label-root"
|
||||
>
|
||||
Rich-text comments
|
||||
</label>
|
||||
<div>
|
||||
<div
|
||||
className="Box-root Flex-root RadioButton-root Flex-flex Flex-alignCenter"
|
||||
>
|
||||
<input
|
||||
checked={true}
|
||||
className="RadioButton-input"
|
||||
disabled={false}
|
||||
id="rte.enabled-true"
|
||||
name="rte.enabled"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
type="radio"
|
||||
value="true"
|
||||
/>
|
||||
<label
|
||||
className="RadioButton-label RadioButton-labelChecked"
|
||||
htmlFor="rte.enabled-true"
|
||||
>
|
||||
<span>
|
||||
On - bold, italics, block quotes, and bulletted lists
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
className="Box-root Flex-root RadioButton-root Flex-flex Flex-alignCenter"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="RadioButton-input"
|
||||
disabled={false}
|
||||
id="rte.enabled-false"
|
||||
name="rte.enabled"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
type="radio"
|
||||
value="false"
|
||||
/>
|
||||
<label
|
||||
className="RadioButton-label"
|
||||
htmlFor="rte.enabled-false"
|
||||
>
|
||||
<span>
|
||||
Off
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset
|
||||
className="Box-root HorizontalGutter-root FormField-root HorizontalGutter-spacing-2"
|
||||
>
|
||||
<label
|
||||
className="Label-root"
|
||||
>
|
||||
Additional rich-text options
|
||||
</label>
|
||||
<div
|
||||
className="CheckBox-root"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="CheckBox-input"
|
||||
disabled={false}
|
||||
id="rte.strikethrough"
|
||||
name="rte.strikethrough"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
type="checkbox"
|
||||
value={false}
|
||||
/>
|
||||
<label
|
||||
className="CheckBox-label"
|
||||
htmlFor="rte.strikethrough"
|
||||
>
|
||||
<span
|
||||
className="CheckBox-labelSpan"
|
||||
>
|
||||
Strikethrough
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
className="CheckBox-root"
|
||||
>
|
||||
<input
|
||||
checked={false}
|
||||
className="CheckBox-input"
|
||||
disabled={false}
|
||||
id="rte.spoiler"
|
||||
name="rte.spoiler"
|
||||
onBlur={[Function]}
|
||||
onChange={[Function]}
|
||||
onFocus={[Function]}
|
||||
type="checkbox"
|
||||
value={false}
|
||||
/>
|
||||
<label
|
||||
className="CheckBox-label"
|
||||
htmlFor="rte.spoiler"
|
||||
>
|
||||
<span
|
||||
className="CheckBox-labelSpan"
|
||||
>
|
||||
Spoiler
|
||||
</span>
|
||||
</label>
|
||||
</div>
|
||||
<div
|
||||
className="RTEConfig-spoilerDesc"
|
||||
>
|
||||
Words and phrases formatted as Spoiler are hidden behind a
|
||||
dark background until the reader chooses to reveal the text.
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</fieldset>
|
||||
</div>
|
||||
</fieldset>
|
||||
<fieldset
|
||||
className="FieldSet-root Box-root ConfigBox-root"
|
||||
>
|
||||
|
||||
@@ -148,7 +148,7 @@ it("prevents admin lock out", async () => {
|
||||
|
||||
// Let's disable local auth.
|
||||
act(() => {
|
||||
within(container).getByLabelText("Enabled").props.onChange();
|
||||
within(container).getByLabelText("Enabled").props.onChange(false);
|
||||
});
|
||||
|
||||
// Send form
|
||||
@@ -203,7 +203,8 @@ it("prevents stream lock out", async () => {
|
||||
try {
|
||||
window.confirm = stubCancel;
|
||||
// Let's disable stream target in local auth.
|
||||
act(() => streamTarget.props.onChange());
|
||||
act(() => streamTarget.props.onChange(false));
|
||||
within(streamTarget).debug();
|
||||
|
||||
// Send form
|
||||
await act(async () => await form.props.onSubmit());
|
||||
@@ -215,9 +216,6 @@ it("prevents stream lock out", async () => {
|
||||
});
|
||||
|
||||
window.confirm = stubContinue;
|
||||
// Let's enable stream target in local auth.
|
||||
act(() => streamTarget.props.onChange());
|
||||
|
||||
// Send form
|
||||
await act(async () => await form.props.onSubmit());
|
||||
|
||||
|
||||
@@ -538,3 +538,66 @@ it("handle server error", async () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it("change rte config", async () => {
|
||||
const resolvers = createResolversStub<GQLResolver>({
|
||||
Mutation: {
|
||||
updateSettings: ({ variables }) => {
|
||||
expectAndFail(variables.settings.rte).toEqual({
|
||||
enabled: true,
|
||||
strikethrough: true,
|
||||
spoiler: false,
|
||||
});
|
||||
return {
|
||||
settings: pureMerge(settings, variables.settings),
|
||||
};
|
||||
},
|
||||
},
|
||||
});
|
||||
const {
|
||||
configureContainer,
|
||||
generalContainer,
|
||||
saveChangesButton,
|
||||
} = await createTestRenderer({
|
||||
resolvers,
|
||||
});
|
||||
|
||||
const rteContainer = within(
|
||||
generalContainer
|
||||
).getAllByText("Rich-text comments", { selector: "fieldset" })[0];
|
||||
const onField = within(rteContainer).getByLabelText("On", { exact: false });
|
||||
const offField = within(rteContainer).getByLabelText("Off", { exact: false });
|
||||
const strikethroughField = within(rteContainer).getByLabelText(
|
||||
"Strikethrough"
|
||||
);
|
||||
|
||||
// Turn off rte will disable additional options.
|
||||
act(() => offField.props.onChange(offField.props.value.toString()));
|
||||
expect(strikethroughField.props.disabled).toBe(true);
|
||||
|
||||
// Turn on rte will enable additional options.
|
||||
act(() => onField.props.onChange(onField.props.value.toString()));
|
||||
expect(strikethroughField.props.disabled).toBe(false);
|
||||
|
||||
// Enable strikethrough option.
|
||||
act(() => strikethroughField.props.onChange(true));
|
||||
|
||||
// Send form
|
||||
act(() => {
|
||||
within(configureContainer).getByType("form").props.onSubmit();
|
||||
});
|
||||
|
||||
// Submit button and text field should be disabled.
|
||||
expect(saveChangesButton.props.disabled).toBe(true);
|
||||
expect(onField.props.disabled).toBe(true);
|
||||
expect(strikethroughField.props.disabled).toBe(true);
|
||||
|
||||
// Wait for submission to be finished
|
||||
await act(async () => {
|
||||
await wait(() => {
|
||||
expect(onField.props.disabled).toBe(false);
|
||||
expect(strikethroughField.props.disabled).toBe(false);
|
||||
});
|
||||
});
|
||||
expect(resolvers.Mutation!.updateSettings!.called).toBe(true);
|
||||
});
|
||||
|
||||
@@ -188,6 +188,11 @@ export const settings = createFixture<GQLSettings>({
|
||||
},
|
||||
multisite: false,
|
||||
featureFlags: [],
|
||||
rte: {
|
||||
enabled: true,
|
||||
strikethrough: false,
|
||||
spoiler: false,
|
||||
},
|
||||
});
|
||||
|
||||
export const settingsWithEmptyAuth = createFixture<GQLSettings>(
|
||||
|
||||
Reference in New Issue
Block a user