From 7d66b45e74264275f797a21d8d02c1de49fcfceb Mon Sep 17 00:00:00 2001 From: Boris Trombert Date: Tue, 24 Sep 2024 10:19:19 +0200 Subject: [PATCH] custom keywords notifications in params for dekstop Changelog: added --- .../rhs_settings_notifications.tsx | 210 ++++++++++++++++-- webapp/channels/src/i18n/de.json | 4 + webapp/channels/src/i18n/en.json | 4 + webapp/channels/src/i18n/es.json | 4 + webapp/channels/src/i18n/fr.json | 4 + webapp/channels/src/i18n/it.json | 4 + .../channels/src/sass/routes/_settings.scss | 7 +- 7 files changed, 222 insertions(+), 15 deletions(-) diff --git a/webapp/channels/src/components/rhs_settings/rhs_settings_notifications/rhs_settings_notifications.tsx b/webapp/channels/src/components/rhs_settings/rhs_settings_notifications/rhs_settings_notifications.tsx index 1366cce4bc..bad612cb38 100644 --- a/webapp/channels/src/components/rhs_settings/rhs_settings_notifications/rhs_settings_notifications.tsx +++ b/webapp/channels/src/components/rhs_settings/rhs_settings_notifications/rhs_settings_notifications.tsx @@ -8,7 +8,9 @@ import debounce from 'lodash/debounce'; import type {RefObject} from 'react'; import React from 'react'; import {FormattedMessage} from 'react-intl'; +import type {ValueType} from 'react-select'; import ReactSelect from 'react-select'; +import CreatableSelect from 'react-select/creatable'; import semver from 'semver'; import type {PreferenceType} from '@mattermost/types/preferences'; @@ -21,15 +23,25 @@ import type {ActionResult} from 'mattermost-redux/types/actions'; import Toggle from 'components/toggle'; import Constants, {NotificationLevels, Preferences} from 'utils/constants'; +import {t} from 'utils/i18n'; import {isDesktopApp} from 'utils/user_agent'; import {localizeMessage, moveCursorToEnd} from 'utils/utils'; -import DesktopNotificationSettings from './desktop_notification_setting/desktop_notification_settings'; - import RhsSettingsItem from '../rhs_settings_item/rhs_settings_item'; import './rhs_settings_notifications.scss'; - +import DesktopNotificationSettings from './desktop_notification_setting/desktop_notification_settings'; +type InputProps ={ + display: string; + description: { + id: string; + message: string; + }; + title: { + id: string; + message: string; + }; +} export type Props = { user: UserProfile; updateSection: (section: string) => void; @@ -64,6 +76,9 @@ type State = { isSaving: boolean; serverError: string; emailInterval: number; + keywordsValues: Array<{ label: string; value: string }>; + inputValue: string; + showSelect: boolean; }; function getNotificationsStateFromProps(props: Props, state?: State): State { @@ -177,6 +192,9 @@ function getNotificationsStateFromProps(props: Props, state?: State): State { notifyCommentsLevel: comments, isSaving: false, serverError: '', + keywordsValues: state?.keywordsValues || [], + inputValue: state?.inputValue || '', + showSelect: state?.showSelect || false, emailInterval: props.emailInterval, }; } @@ -212,6 +230,16 @@ export default class RhsNotificationsTab extends React.PureComponent this.createOption(keyword)) : []; + this.setState({ + keywordsValues: keywordsArray, + showSelect: keywordsArray.length > 0, + }); + } + handleSubmit = (): void => { const data: UserNotifyProps = {} as UserNotifyProps; data.email = this.state.enableEmail; @@ -236,19 +264,9 @@ export default class RhsNotificationsTab extends React.PureComponent 0 && this.state.customKeysChecked) { - stringKeys += ',' + this.state.customKeys; - } - - data.mention_keys = stringKeys; data.first_name = this.state.firstNameKey.toString() as UserNotifyProps['first_name']; data.channel = this.state.channelKey.toString() as UserNotifyProps['channel']; + data.mention_keys = (this.state.keywordsValues || []).map((keyword: { value: string }) => keyword.value).join(','); this.setState({isSaving: true}); @@ -348,6 +366,156 @@ export default class RhsNotificationsTab extends React.PureComponent ({ + label, + value: label.toLowerCase().replace(/\W/g, ''), + }); + + createInput(props: InputProps) { + const { + display, + description, + title, + } = props; + + const messageTitle = ( + + ); + + const messageDesc = ( + + ); + + const helpMessage = ( + + ); + + const placeholderMessage = ( + + ); + + const handleKeyDown = (event: React.KeyboardEvent) => { + if (!this.state.inputValue) { + return; + } + + const newKeywords = this.state.inputValue.split(',').map((keyword: string) => this.createOption(keyword.trim())); + + switch (event.key) { + case 'Enter': + case 'Tab': + this.setState((prevState) => ({ + keywordsValues: Array.isArray(prevState.keywordsValues) ? [...prevState.keywordsValues, ...newKeywords] : newKeywords, + inputValue: '', + }), () => { + this.handleSubmit(); + }); + event.preventDefault(); + break; + default: + break; + } + }; + + const handleOnChange = (newValues: ValueType<{ label: string; value: string }>) => { + const valuesArray = Array.isArray(newValues) ? newValues : []; + this.setState({keywordsValues: valuesArray}, () => { + this.handleSubmit(); + }); + }; + + const toggleSelectVisibility = () => { + this.setState((prevState) => { + const newShowSelect = !prevState.showSelect; + const newKeywordsValues = newShowSelect ? prevState.keywordsValues : []; + + return { + showSelect: newShowSelect, + keywordsValues: newKeywordsValues, + inputValue: newShowSelect ? prevState.inputValue : '', + }; + }, async () => { + if (!this.state.showSelect) { + this.handleSubmit(); + } + }); + }; + + const handleInputChange = (inputValue: string) => { + this.setState({inputValue}); + }; + + const handleBlur = () => { + if (!this.state.inputValue) { + return; + } + + const newKeywords = this.state.inputValue.split(',').map((keyword: string) => this.createOption(keyword.trim())); + + this.setState((prevState) => ({ + keywordsValues: Array.isArray(prevState.keywordsValues) ? [...prevState.keywordsValues, ...newKeywords] : newKeywords, + inputValue: '', + }), () => { + this.handleSubmit(); + }); + }; + + return ( + <> + +
+ +
+ + + } + saving={this.state.isSaving} + messageDesc={messageDesc} + updateSection={this.props.updateSection} + /> + {this.state.showSelect && ( +
+ +
+ {helpMessage} +
+
+ )} + + ); + } + createPushNotificationSection = () => { const options = [ { @@ -748,6 +916,18 @@ export default class RhsNotificationsTab extends React.PureComponent
@@ -792,6 +972,8 @@ export default class RhsNotificationsTab extends React.PureComponent
{this.createEmailNotificationSection()} +
+ {keywordsSection}
diff --git a/webapp/channels/src/i18n/de.json b/webapp/channels/src/i18n/de.json index da8ad89ca6..d85f3c21ab 100644 --- a/webapp/channels/src/i18n/de.json +++ b/webapp/channels/src/i18n/de.json @@ -5681,6 +5681,10 @@ "user.settings.display.fixedWidthCentered": "Feste Breite, zentriert", "user.settings.display.fullScreen": "Ganze Breite", "user.settings.display.icon": "Anzeigeeinstellungen-Symbol", + "user.settings.display.keywords": "Benachrichtigungen für bestimmte Schlüsselwörter erhalten", + "user.settings.display.keywords_desc": "Schlüsselwörter sind nicht case-sensitiv.", + "user.settings.display.keywords_help": "Drücken Sie Tab oder verwenden Sie Kommas, um Schlüsselwörter zu trennen.", + "user.settings.display.keywords_placeholder": "Schlüsselwörter", "user.settings.display.language": "Sprache", "user.settings.display.lastActiveDesc": "Wenn aktiviert, können andere Benutzer sehen, wann du zuletzt aktiv warst.", "user.settings.display.lastActiveDisplay": "Zuletzt Aktiv teilen", diff --git a/webapp/channels/src/i18n/en.json b/webapp/channels/src/i18n/en.json index 3d2d517cc8..59c1c667c6 100644 --- a/webapp/channels/src/i18n/en.json +++ b/webapp/channels/src/i18n/en.json @@ -5698,6 +5698,10 @@ "user.settings.display.fixedWidthCentered": "Fixed width, centered", "user.settings.display.fullScreen": "Full width", "user.settings.display.icon": "Display Settings Icon", + "user.settings.display.keywords": "Receive notifications for certain keywords", + "user.settings.display.keywords_desc": "Keywords are case insensitive.", + "user.settings.display.keywords_help": "Press Tab or use commas to separate keywords.", + "user.settings.display.keywords_placeholder": "Keywords", "user.settings.display.language": "Language", "user.settings.display.lastActiveDesc": "When enabled, other users will see when you were last active.", "user.settings.display.lastActiveDisplay": "Share last active time", diff --git a/webapp/channels/src/i18n/es.json b/webapp/channels/src/i18n/es.json index bb5180d1ae..ec64b510e8 100644 --- a/webapp/channels/src/i18n/es.json +++ b/webapp/channels/src/i18n/es.json @@ -4675,6 +4675,10 @@ "user.settings.display.fixedWidthCentered": "De ancho fijo, centrado", "user.settings.display.fullScreen": "De ancho total", "user.settings.display.icon": "Icono de Configuración de Visualización", + "user.settings.display.keywords": "Recibir notificaciones para ciertas palabras clave", + "user.settings.display.keywords_desc": "Las palabras clave no distinguen entre mayúsculas y minúsculas.", + "user.settings.display.keywords_help": "Presione Tab o use comas para separar las palabras clave.", + "user.settings.display.keywords_placeholder": "Palabras clave", "user.settings.display.language": "Idioma", "user.settings.display.lastActiveOff": "Apagar", "user.settings.display.lastActiveOn": "Encender", diff --git a/webapp/channels/src/i18n/fr.json b/webapp/channels/src/i18n/fr.json index 2058882c79..ee8f3c6c9b 100644 --- a/webapp/channels/src/i18n/fr.json +++ b/webapp/channels/src/i18n/fr.json @@ -4606,6 +4606,10 @@ "user.settings.display.fixedWidthCentered": "Largeur fixe, centré", "user.settings.display.fullScreen": "Largeur pleine", "user.settings.display.icon": "Icône de paramètres d'affichage", + "user.settings.display.keywords": "Recevoir des notifications pour certains mots-clés", + "user.settings.display.keywords_desc": "Les mots-clés sont non sensibles à la casse.", + "user.settings.display.keywords_help": "Appuyez sur Tab ou utilisez des virgules pour séparer les mots-clés.", + "user.settings.display.keywords_placeholder": "Mots-clés", "user.settings.display.language": "Langue", "user.settings.display.linkPreviewDesc": "Lorsque disponible, le premier lien web du message affichera un aperçu du contenu du site web en dessous du message.", "user.settings.display.linkPreviewDisplay": "Aperçus des liens de site web", diff --git a/webapp/channels/src/i18n/it.json b/webapp/channels/src/i18n/it.json index 91b0f5bbe1..ce17299cca 100644 --- a/webapp/channels/src/i18n/it.json +++ b/webapp/channels/src/i18n/it.json @@ -3512,6 +3512,10 @@ "user.settings.display.fixedWidthCentered": "Larghezza fissa, centrato", "user.settings.display.fullScreen": "A tutta larghezza", "user.settings.display.icon": "Icona Impostazioni aspetto", + "user.settings.display.keywords": "Ricevi notifiche per determinate parole chiave", + "user.settings.display.keywords_desc": "Le parole chiave non sono sensibili alle maiuscole.", + "user.settings.display.keywords_help": "Premi Tab o usa le virgole per separare le parole chiave.", + "user.settings.display.keywords_placeholder": "Parole chiave", "user.settings.display.language": "Lingua", "user.settings.display.linkPreviewDesc": "Se disponibile, il primo collegamento web in un messaggio visualizzerà un'anteprima del contenuto del sito sotto il messaggio.", "user.settings.display.linkPreviewDisplay": "Anteprima siti web", diff --git a/webapp/channels/src/sass/routes/_settings.scss b/webapp/channels/src/sass/routes/_settings.scss index c89ea9a4f4..b4d3843a5a 100644 --- a/webapp/channels/src/sass/routes/_settings.scss +++ b/webapp/channels/src/sass/routes/_settings.scss @@ -83,7 +83,12 @@ .settings-desc { font-size: 12px; - color: rgba(var(--center-channel-color-rgb),0.785) + color: rgba(var(--center-channel-color-rgb),0.785); + + &.help-keyword { + padding-top: 15px; + padding-bottom: 15px; + } } .title-select { display: flex;