From a151b866376daab234a64ac28beb5c4f86db2b23 Mon Sep 17 00:00:00 2001 From: Muhsin Date: Wed, 21 Dec 2022 16:17:07 +0530 Subject: [PATCH] Add variable support in the editor --- .../components/widgets/WootWriter/Editor.vue | 70 ++++++++++++++- .../widgets/conversation/VariableList.vue | 62 +++++++++++++ .../components/widgets/variable/Variable.vue | 86 +++++++++++++++++++ 3 files changed, 217 insertions(+), 1 deletion(-) create mode 100644 app/javascript/dashboard/components/widgets/conversation/VariableList.vue create mode 100644 app/javascript/dashboard/components/widgets/variable/Variable.vue diff --git a/app/javascript/dashboard/components/widgets/WootWriter/Editor.vue b/app/javascript/dashboard/components/widgets/WootWriter/Editor.vue index b6614dcc0..9654bd03c 100644 --- a/app/javascript/dashboard/components/widgets/WootWriter/Editor.vue +++ b/app/javascript/dashboard/components/widgets/WootWriter/Editor.vue @@ -10,6 +10,11 @@ :search-key="cannedSearchTerm" @click="insertCannedResponse" /> +
@@ -34,6 +39,7 @@ import { wootWriterSetup } from '@chatwoot/prosemirror-schema'; import TagAgents from '../conversation/TagAgents'; import CannedResponse from '../conversation/CannedResponse'; +import VariableList from '../conversation/VariableList'; const TYPING_INDICATOR_IDLE_TIME = 4000; @@ -64,7 +70,7 @@ const createState = (content, placeholder, plugins = []) => { export default { name: 'WootMessageEditor', - components: { TagAgents, CannedResponse }, + components: { TagAgents, CannedResponse, VariableList }, mixins: [eventListenerMixins, uiSettingsMixin], props: { value: { type: String, default: '' }, @@ -74,13 +80,16 @@ export default { enableSuggestions: { type: Boolean, default: true }, overrideLineBreaks: { type: Boolean, default: false }, updateSelectionWith: { type: String, default: '' }, + enableVariables: { type: Boolean, default: true }, }, data() { return { showUserMentions: false, showCannedMenu: false, + showVariables: false, mentionSearchKey: '', cannedSearchTerm: '', + variableSearchTerm: '', editorView: null, range: null, state: undefined, @@ -92,6 +101,9 @@ export default { defaultMarkdownSerializer ).serialize(this.editorView.state.doc); }, + shouldShowVariables() { + return this.enableVariables && this.showVariables && !this.isPrivate; + }, plugins() { if (!this.enableSuggestions) { return []; @@ -111,6 +123,7 @@ export default { this.range = args.range; this.mentionSearchKey = args.text.replace('@', ''); + return false; }, onExit: () => { @@ -150,6 +163,34 @@ export default { return event.keyCode === 13 && this.showCannedMenu; }, }), + suggestionsPlugin({ + matcher: triggerCharacters('{{'), + suggestionClass: '', + onEnter: args => { + if (this.isPrivate) { + return false; + } + this.showVariables = true; + this.range = args.range; + this.editorView = args.view; + return false; + }, + onChange: args => { + this.editorView = args.view; + this.range = args.range; + + this.variableSearchTerm = args.text.replace('{{', ''); + return false; + }, + onExit: () => { + this.variableSearchTerm = ''; + this.showVariables = false; + return false; + }, + onKeyDown: ({ event }) => { + return event.keyCode === 13 && this.showVariables; + }, + }), ]; }, }, @@ -304,6 +345,33 @@ export default { AnalyticsHelper.track(ANALYTICS_EVENTS.INSERTED_A_CANNED_RESPONSE); return false; }, + insertVariable(variable) { + if (!this.editorView) { + return null; + } + + let from = this.range.from - 1; + let node = addMentionsToMarkdownParser(defaultMarkdownParser).parse( + variable + ); + + if (node.childCount === 1) { + node = this.editorView.state.schema.text(`{{ ${variable} }}`); + from = this.range.from; + } + + const tr = this.editorView.state.tr.replaceWith( + from, + this.range.to, + node + ); + + this.state = this.editorView.state.apply(tr); + this.emitOnChange(); + + tr.scrollIntoView(); + return false; + }, emitOnChange() { this.editorView.updateState(this.state); diff --git a/app/javascript/dashboard/components/widgets/conversation/VariableList.vue b/app/javascript/dashboard/components/widgets/conversation/VariableList.vue new file mode 100644 index 000000000..2af66f53c --- /dev/null +++ b/app/javascript/dashboard/components/widgets/conversation/VariableList.vue @@ -0,0 +1,62 @@ + + + diff --git a/app/javascript/dashboard/components/widgets/variable/Variable.vue b/app/javascript/dashboard/components/widgets/variable/Variable.vue new file mode 100644 index 000000000..f256ba361 --- /dev/null +++ b/app/javascript/dashboard/components/widgets/variable/Variable.vue @@ -0,0 +1,86 @@ + + + + +