@@ -9,6 +9,7 @@ import CodeEditor from "@/components/CodeEditor.vue";
9
9
import { useMessageStore } from " @/stores/MessageStore" ;
10
10
import { storeToRefs } from " pinia" ;
11
11
import LoadingSpinner from " @/components/LoadingSpinner.vue" ;
12
+ import debounce from " lodash/debounce" ;
12
13
13
14
interface HeaderWithEditing extends Header {
14
15
isLocked: boolean ;
@@ -41,28 +42,31 @@ const localMessage = ref<LocalMessageState>({
41
42
isBodyEmpty: false ,
42
43
isContentTypeSupported: false ,
43
44
bodyContentType: undefined ,
44
- bodyUnavailable: true ,
45
+ bodyUnavailable: false ,
45
46
isEvent: false ,
46
47
retried: false ,
47
48
headers: [],
48
49
messageBody: " " ,
49
50
});
50
- let origMessageBody: string ;
51
-
52
51
const showEditAndRetryConfirmation = ref (false );
53
52
const showCancelConfirmation = ref (false );
54
53
const showEditRetryGenericError = ref (false );
55
54
const store = useMessageStore ();
56
55
const { state, headers, body, edit_and_retry_config } = storeToRefs (store );
57
56
const id = computed (() => state .value .data .id ?? " " );
58
- const messageBody = computed (() => body .value .data .value );
59
-
60
- watch (messageBody , (newValue ) => {
61
- if (newValue !== origMessageBody ) {
62
- localMessage .value .isBodyChanged = true ;
57
+ const uneditedMessageBody = computed (() => body .value .data .value ?? " " );
58
+ const regExToPruneLineEndings = new RegExp (/ [\n\r ] * / , " g" );
59
+ const debounceBodyUpdate = debounce ((value : string ) => {
60
+ localMessage .value .isBodyChanged = value .replaceAll (regExToPruneLineEndings , " " ) !== uneditedMessageBody .value .replaceAll (regExToPruneLineEndings , " " );
61
+ localMessage .value .isBodyEmpty = value === " " ;
62
+ }, 1000 );
63
+
64
+ watch (
65
+ () => localMessage .value .messageBody ,
66
+ (newValue ) => {
67
+ debounceBodyUpdate (newValue );
63
68
}
64
- localMessage .value .isBodyEmpty = newValue === " " ;
65
- });
69
+ );
66
70
67
71
function close() {
68
72
emit (" cancel" );
@@ -87,7 +91,7 @@ function confirmCancel() {
87
91
}
88
92
89
93
function resetBodyChanges() {
90
- localMessage .value .messageBody = origMessageBody ;
94
+ localMessage .value .messageBody = uneditedMessageBody . value ;
91
95
localMessage .value .isBodyChanged = false ;
92
96
}
93
97
@@ -113,7 +117,6 @@ function initializeMessageBodyAndHeaders() {
113
117
return header ?.value ;
114
118
}
115
119
116
- origMessageBody = body .value .data .value ?? " " ;
117
120
const local = <LocalMessageState >{
118
121
isBodyChanged: false ,
119
122
isBodyEmpty: false ,
@@ -211,15 +214,22 @@ onMounted(() => {
211
214
</tr >
212
215
</tbody >
213
216
</table >
214
- <div role =" tabpanel" v-if =" panel === 2 && !localMessage.bodyUnavailable" style =" height : calc (100% - 260px )" >
215
- <div style =" margin-top : 1.25rem " >
216
- <LoadingSpinner v-if =" body.loading" />
217
- <CodeEditor v-else aria-label =" message body" :read-only =" !localMessage.isContentTypeSupported" v-model =" localMessage.messageBody" :language =" localMessage.language" :show-gutter =" true" ></CodeEditor >
217
+ <template v-if =" panel === 2 " >
218
+ <div role =" tabpanel" v-if =" !localMessage.bodyUnavailable" >
219
+ <div style =" margin-top : 1.25rem " >
220
+ <LoadingSpinner v-if =" body.loading" />
221
+ <CodeEditor v-else aria-label =" message body" :read-only =" !localMessage.isContentTypeSupported" v-model =" localMessage.messageBody" :language =" localMessage.language" :show-gutter =" true" >
222
+ <template #toolbarLeft >
223
+ <span class =" empty-error" v-if =" localMessage.isBodyEmpty" ><i class =" fa fa-exclamation-triangle" ></i > Message body cannot be empty</span >
224
+ </template >
225
+ <template #toolbarRight >
226
+ <button v-if =" localMessage.isBodyChanged" type =" button" class =" btn btn-secondary btn-sm" @click =" resetBodyChanges" ><i class =" fa fa-undo" ></i > Reset changes</button >
227
+ </template >
228
+ </CodeEditor >
229
+ </div >
218
230
</div >
219
- <span class =" empty-error" v-if =" localMessage.isBodyEmpty" ><i class =" fa fa-exclamation-triangle" ></i > Message body cannot be empty</span >
220
- <span class =" reset-body" v-if =" localMessage.isBodyChanged" ><i class =" fa fa-undo" v-tippy =" `Reset changes`" ></i > <a @click =" resetBodyChanges()" href =" javascript:void(0)" >Reset changes</a ></span >
221
- <div class =" alert alert-info" v-if =" panel === 2 && localMessage.bodyUnavailable" >{{ localMessage.bodyUnavailable }}</div >
222
- </div >
231
+ <div role =" tabpanel" class =" alert alert-info" v-else >{{ localMessage.bodyUnavailable }}</div >
232
+ </template >
223
233
</div >
224
234
</div >
225
235
</div >
@@ -267,14 +277,6 @@ onMounted(() => {
267
277
margin-right : 20px ;
268
278
}
269
279
270
- .modal-msg-editor .reset-body {
271
- color : #00a3c4 ;
272
- font-weight : bold ;
273
- text-align : left ;
274
- margin-top : 15px ;
275
- display : inline-block ;
276
- }
277
-
278
280
.modal-msg-editor .reset-body a :hover {
279
281
cursor : pointer ;
280
282
}
@@ -284,8 +286,6 @@ onMounted(() => {
284
286
}
285
287
286
288
.modal-msg-editor .empty-error {
287
- float : right ;
288
- margin-top : 15px ;
289
289
color : #ce4844 ;
290
290
font-weight : bold ;
291
291
}
0 commit comments