diff --git a/packages/comment-widget/src/base-form.ts b/packages/comment-widget/src/base-form.ts
index f7e31c3..dcdaaad 100644
--- a/packages/comment-widget/src/base-form.ts
+++ b/packages/comment-widget/src/base-form.ts
@@ -496,6 +496,14 @@ export class BaseForm extends LitElement {
`
)}
+ ${when(
+ this.allowNotificationConfigurable,
+ () => html`
+
+
+
`
+ )}
+
${when(
this.showCaptcha &&
!this.useTurnstile &&
@@ -567,6 +575,10 @@ export class BaseForm extends LitElement {
`;
}
+ private get allowNotificationConfigurable() {
+ return this.configMapData?.basic.allowNotificationConfigurable === true;
+ }
+
private get canUploadImages() {
if (!this.configMapData?.editor?.enableUpload) {
return false;
@@ -589,6 +601,9 @@ export class BaseForm extends LitElement {
waitUntil: (submission: Promise) =>
submissions.push(submission),
content,
+ allowNotification: this.allowNotificationConfigurable
+ ? data.allowNotification === 'on'
+ : true,
uploadIds: uploadedIds(editor),
uploadSession: uploadSession(editor),
hidden: data.hidden === 'on',
diff --git a/packages/comment-widget/src/comment-form.ts b/packages/comment-widget/src/comment-form.ts
index 57e8551..b765c02 100644
--- a/packages/comment-widget/src/comment-form.ts
+++ b/packages/comment-widget/src/comment-form.ts
@@ -70,13 +70,12 @@ export class CommentForm extends LitElement {
onSubmit(e: SubmissionEvent) {
const data = e.detail;
- const { content, hidden } = data || {};
+ const { content, hidden, allowNotification } = data || {};
const commentRequest: CommentRequest = {
raw: content,
content: content,
- // TODO: support user input
- allowNotification: true,
+ allowNotification: allowNotification,
hidden: hidden || false,
subjectRef: {
group: this.group,
diff --git a/packages/comment-widget/src/generated/locales/es.ts b/packages/comment-widget/src/generated/locales/es.ts
index f848c2b..374f5e9 100644
--- a/packages/comment-widget/src/generated/locales/es.ts
+++ b/packages/comment-widget/src/generated/locales/es.ts
@@ -21,6 +21,7 @@
's107ccef507b51f2c': `Completa la verificación`,
's15e33945d13c5176': `Se está confirmando tu envío anterior. Inténtalo más tarde; se conservarán tus imágenes.`,
's176fe95698857ad9': `El comentario o la respuesta ha cambiado. Copia tu borrador y vuelve a abrir el editor para cargar la última versión.`,
+'s17c8f8524e36987d': `Permitir notificación`,
's19172ed3838854fc': `Copiar enlace`,
's1c6fefb092506753': `Error al cargar la lista de comentarios, por favor intente más tarde`,
's1d468f888124a55e': `Tu borrador ha cambiado. Vuelve a abrirlo antes de reintentar.`,
diff --git a/packages/comment-widget/src/generated/locales/zh-CN.ts b/packages/comment-widget/src/generated/locales/zh-CN.ts
index 6918843..d365136 100644
--- a/packages/comment-widget/src/generated/locales/zh-CN.ts
+++ b/packages/comment-widget/src/generated/locales/zh-CN.ts
@@ -21,6 +21,7 @@
's107ccef507b51f2c': `请完成人机验证`,
's15e33945d13c5176': `上次提交结果正在确认,请稍后重试;图片会被保留。`,
's176fe95698857ad9': `评论或回复已发生变化。请先复制草稿,再重新打开编辑框获取最新版本。`,
+'s17c8f8524e36987d': `允许通知`,
's19172ed3838854fc': `复制链接`,
's1c6fefb092506753': `加载评论列表失败,请稍后重试`,
's1d468f888124a55e': `草稿已更改,请重新打开后再重试。`,
diff --git a/packages/comment-widget/src/generated/locales/zh-TW.ts b/packages/comment-widget/src/generated/locales/zh-TW.ts
index 12ab640..cadaa87 100644
--- a/packages/comment-widget/src/generated/locales/zh-TW.ts
+++ b/packages/comment-widget/src/generated/locales/zh-TW.ts
@@ -21,6 +21,7 @@
's107ccef507b51f2c': `請完成人機驗證`,
's15e33945d13c5176': `上次提交結果正在確認,請稍後重試;圖片會被保留。`,
's176fe95698857ad9': `評論或回覆已發生變更。請先複製草稿,再重新開啟編輯框取得最新版本。`,
+'s17c8f8524e36987d': `允許通知`,
's19172ed3838854fc': `複製連結`,
's1c6fefb092506753': `載入評論列表失敗,請稍後重試`,
's1d468f888124a55e': `草稿已變更,請重新開啟後再重試。`,
diff --git a/packages/comment-widget/src/reply-form.ts b/packages/comment-widget/src/reply-form.ts
index a86df13..801089e 100644
--- a/packages/comment-widget/src/reply-form.ts
+++ b/packages/comment-widget/src/reply-form.ts
@@ -78,13 +78,12 @@ export class ReplyForm extends LitElement {
onSubmit(e: SubmissionEvent) {
const data = e.detail;
- const { content, hidden } = data || {};
+ const { content, hidden, allowNotification } = data || {};
const replyRequest: ReplyRequest = {
raw: content,
content: content,
- // TODO: support user input
- allowNotification: true,
+ allowNotification: allowNotification,
hidden: hidden || false,
};
diff --git a/packages/comment-widget/src/types/index.ts b/packages/comment-widget/src/types/index.ts
index 43e2433..bd67f61 100644
--- a/packages/comment-widget/src/types/index.ts
+++ b/packages/comment-widget/src/types/index.ts
@@ -11,6 +11,7 @@ interface BasicConfig {
size: number;
withReplySize: number;
replySize: number;
+ allowNotificationConfigurable?: boolean;
showCommenterDevice?: boolean;
enablePrivateComment?: boolean;
showPrivateCommentBadge?: boolean;
diff --git a/packages/comment-widget/src/utils/submission.ts b/packages/comment-widget/src/utils/submission.ts
index 403ad18..93aed29 100644
--- a/packages/comment-widget/src/utils/submission.ts
+++ b/packages/comment-widget/src/utils/submission.ts
@@ -29,6 +29,7 @@ export interface SubmissionDetail {
turnstileToken?: string;
altchaPayload?: string;
content: string;
+ allowNotification: boolean;
hidden: boolean;
uploadIds: string[];
uploadSession: UploadSession;
diff --git a/packages/comment-widget/tests/allow-notification.browser.test.js b/packages/comment-widget/tests/allow-notification.browser.test.js
new file mode 100644
index 0000000..f6e274d
--- /dev/null
+++ b/packages/comment-widget/tests/allow-notification.browser.test.js
@@ -0,0 +1,88 @@
+import { assert, test } from 'vitest';
+import { mockApi, until } from './browser-helpers.js';
+
+test.each(['comment-form', 'reply-form'])(
+ '%s submits the selected allow notification state',
+ async (tag) => {
+ const requests = [];
+ mockApi(async (_input, options = {}) => {
+ requests.push(JSON.parse(options.body));
+ return new Response(JSON.stringify({ spec: { approved: true } }), {
+ headers: { 'Content-Type': 'application/json' },
+ });
+ });
+ await import('../src/index.ts');
+
+ const form = document.createElement(tag);
+ form.comment = { metadata: { name: 'comment-1' } };
+ form.currentUser = { metadata: { name: 'commenter' }, spec: {} };
+ document.body.append(form);
+ await form.updateComplete;
+ const base = form.baseFormRef.value;
+ base.currentUser = form.currentUser;
+ base.configMapData = { basic: { allowNotificationConfigurable: true } };
+ await base.updateComplete;
+ await until(() => base.editorRef.value?.editor);
+
+ const checkbox = base.shadowRoot.querySelector('#allowNotification');
+ assert(checkbox, 'Allow notification must be selectable');
+ assert(checkbox.checked, 'Allow notification must be enabled by default');
+
+ base.editorRef.value.editor.commands.setContent('Notify me
');
+ base.shadowRoot.querySelector('form').requestSubmit();
+ await until(() => requests.length === 1 && !form.submitting);
+ assert(
+ requests[0].allowNotification === true,
+ 'Checked must send allowNotification=true'
+ );
+
+ checkbox.click();
+ assert(!checkbox.checked, 'Allow notification must be toggleable');
+ base.editorRef.value.editor.commands.setContent('Do not notify me
');
+ base.shadowRoot.querySelector('form').requestSubmit();
+ await until(() => requests.length === 2 && !form.submitting);
+ assert(
+ requests[1].allowNotification === false,
+ 'Unchecked must send allowNotification=false'
+ );
+ form.remove();
+ }
+);
+
+test.each(['comment-form', 'reply-form'])(
+ '%s always allows notifications when the option is disabled',
+ async (tag) => {
+ const requests = [];
+ mockApi(async (_input, options = {}) => {
+ requests.push(JSON.parse(options.body));
+ return new Response(JSON.stringify({ spec: { approved: true } }), {
+ headers: { 'Content-Type': 'application/json' },
+ });
+ });
+ await import('../src/index.ts');
+
+ const form = document.createElement(tag);
+ form.comment = { metadata: { name: 'comment-1' } };
+ form.currentUser = { metadata: { name: 'commenter' }, spec: {} };
+ document.body.append(form);
+ await form.updateComplete;
+ const base = form.baseFormRef.value;
+ base.currentUser = form.currentUser;
+ await base.updateComplete;
+ await until(() => base.editorRef.value?.editor);
+
+ assert(
+ !base.shadowRoot.querySelector('#allowNotification'),
+ 'Allow notification must be hidden when the option is disabled'
+ );
+
+ base.editorRef.value.editor.commands.setContent('Notify me
');
+ base.shadowRoot.querySelector('form').requestSubmit();
+ await until(() => requests.length === 1 && !form.submitting);
+ assert(
+ requests[0].allowNotification === true,
+ 'Disabled option must send allowNotification=true'
+ );
+ form.remove();
+ }
+);
diff --git a/packages/comment-widget/xliff/es.xlf b/packages/comment-widget/xliff/es.xlf
index 7fd7ea5..f467db7 100644
--- a/packages/comment-widget/xliff/es.xlf
+++ b/packages/comment-widget/xliff/es.xlf
@@ -382,6 +382,10 @@
Make private
Hacer privado
+
+ Allow notification
+ Permitir notificación
+