2
2
import { computed , onMounted , ref , watch } from " vue" ;
3
3
import { useRetryEditedMessage } from " @/composables/serviceFailedMessage" ;
4
4
import MessageHeader from " ./EditMessageHeader.vue" ;
5
- import { EditAndRetryConfig } from " @/resources/Configuration" ;
6
5
import type Header from " @/resources/Header" ;
7
- import { ExtendedFailedMessage } from " @/resources/FailedMessage" ;
8
6
import parseContentType from " @/composables/contentTypeParser" ;
9
7
import { CodeLanguage } from " @/components/codeEditorTypes" ;
10
8
import CodeEditor from " @/components/CodeEditor.vue" ;
9
+ import { useMessageStore } from " @/stores/MessageStore" ;
10
+ import { storeToRefs } from " pinia" ;
11
+ import LoadingSpinner from " @/components/LoadingSpinner.vue" ;
12
+ import debounce from " lodash/debounce" ;
11
13
12
14
interface HeaderWithEditing extends Header {
13
15
isLocked: boolean ;
@@ -18,13 +20,7 @@ interface HeaderWithEditing extends Header {
18
20
19
21
const emit = defineEmits <{
20
22
cancel: [];
21
- retried: [];
22
- }>();
23
-
24
- const props = defineProps <{
25
- id: string ;
26
- message: ExtendedFailedMessage ;
27
- configuration: EditAndRetryConfig ;
23
+ confirm: [];
28
24
}>();
29
25
30
26
interface LocalMessageState {
@@ -46,27 +42,32 @@ const localMessage = ref<LocalMessageState>({
46
42
isBodyEmpty: false ,
47
43
isContentTypeSupported: false ,
48
44
bodyContentType: undefined ,
49
- bodyUnavailable: true ,
45
+ bodyUnavailable: false ,
50
46
isEvent: false ,
51
47
retried: false ,
52
48
headers: [],
53
49
messageBody: " " ,
54
50
});
55
- let origMessageBody: string ;
56
-
57
51
const showEditAndRetryConfirmation = ref (false );
58
52
const showCancelConfirmation = ref (false );
59
53
const showEditRetryGenericError = ref (false );
54
+ const store = useMessageStore ();
55
+ const { state, headers, body, edit_and_retry_config } = storeToRefs (store );
56
+ const id = computed (() => state .value .data .id ?? " " );
57
+ const uneditedMessageBody = computed (() => body .value .data .value ?? " " );
58
+ const regExToPruneLineEndings = new RegExp (/ [\n\r ] * / , " g" );
59
+ const debounceBodyUpdate = debounce ((value : string ) => {
60
+ const newValue = value .replaceAll (regExToPruneLineEndings , " " );
61
+ localMessage .value .isBodyChanged = newValue !== uneditedMessageBody .value .replaceAll (regExToPruneLineEndings , " " );
62
+ localMessage .value .isBodyEmpty = newValue === " " ;
63
+ }, 100 );
60
64
61
- const id = computed (() => props .id );
62
- const messageBody = computed (() => props .message .messageBody );
63
-
64
- watch (messageBody , (newValue ) => {
65
- if (newValue !== origMessageBody ) {
66
- localMessage .value .isBodyChanged = true ;
65
+ watch (
66
+ () => localMessage .value .messageBody ,
67
+ (newValue ) => {
68
+ debounceBodyUpdate (newValue );
67
69
}
68
- localMessage .value .isBodyEmpty = newValue === " " ;
69
- });
70
+ );
70
71
71
72
function close() {
72
73
emit (" cancel" );
@@ -91,24 +92,10 @@ function confirmCancel() {
91
92
}
92
93
93
94
function resetBodyChanges() {
94
- localMessage .value .messageBody = origMessageBody ;
95
+ localMessage .value .messageBody = uneditedMessageBody . value ;
95
96
localMessage .value .isBodyChanged = false ;
96
97
}
97
98
98
- function findHeadersByKey(key : string ) {
99
- return localMessage .value .headers .find ((header : HeaderWithEditing ) => header .key === key );
100
- }
101
-
102
- function getContentType() {
103
- const header = findHeadersByKey (" NServiceBus.ContentType" );
104
- return header ?.value ;
105
- }
106
-
107
- function getMessageIntent() {
108
- const intent = findHeadersByKey (" NServiceBus.MessageIntent" );
109
- return intent ?.value ;
110
- }
111
-
112
99
function removeHeadersMarkedAsRemoved() {
113
100
localMessage .value .headers = localMessage .value .headers .filter ((header : HeaderWithEditing ) => ! header .isMarkedAsRemoved );
114
101
}
@@ -118,59 +105,62 @@ async function retryEditedMessage() {
118
105
try {
119
106
await useRetryEditedMessage (id .value , localMessage );
120
107
localMessage .value .retried = true ;
121
- return emit (" retried " );
108
+ return emit (" confirm " );
122
109
} catch {
123
110
showEditAndRetryConfirmation .value = false ;
124
111
showEditRetryGenericError .value = true ;
125
112
}
126
113
}
127
114
128
115
function initializeMessageBodyAndHeaders() {
129
- origMessageBody = props .message .messageBody ;
130
- localMessage .value = {
116
+ function getHeaderValue(key : string ) {
117
+ const header = local .headers .find ((header : HeaderWithEditing ) => header .key === key );
118
+ return header ?.value ;
119
+ }
120
+
121
+ const local = <LocalMessageState >{
131
122
isBodyChanged: false ,
132
123
isBodyEmpty: false ,
133
124
isContentTypeSupported: false ,
134
125
bodyContentType: undefined ,
135
- bodyUnavailable: props . message . bodyUnavailable ,
126
+ bodyUnavailable: body . value . not_found ?? false ,
136
127
isEvent: false ,
137
- retried: props . message . retried ,
138
- headers: props . message . headers .map ((header : Header ) => ({ ... header })) as HeaderWithEditing [],
139
- messageBody: props . message . messageBody ,
128
+ retried: state . value . data . failure_status . retried ?? false ,
129
+ headers: headers . value . data .map ((header : Header ) => ({ ... header })) as HeaderWithEditing [],
130
+ messageBody: body . value . data . value ?? " " ,
140
131
};
141
- localMessage .value .isBodyEmpty = false ;
142
- localMessage .value .isBodyChanged = false ;
143
132
144
- const contentType = getContentType ( );
145
- localMessage . value .bodyContentType = contentType ;
133
+ const contentType = getHeaderValue ( " NServiceBus.ContentType " );
134
+ local .bodyContentType = contentType ;
146
135
const parsedContentType = parseContentType (contentType );
147
- localMessage . value .isContentTypeSupported = parsedContentType .isSupported ;
148
- localMessage . value .language = parsedContentType .language ;
136
+ local .isContentTypeSupported = parsedContentType .isSupported ;
137
+ local .language = parsedContentType .language ;
149
138
150
- const messageIntent = getMessageIntent ( );
151
- localMessage . value .isEvent = messageIntent === " Publish" ;
139
+ const messageIntent = getHeaderValue ( " NServiceBus.MessageIntent " );
140
+ local .isEvent = messageIntent === " Publish" ;
152
141
153
- for (let index = 0 ; index < props . message . headers .length ; index ++ ) {
154
- const header: HeaderWithEditing = props . message . headers [index ] as HeaderWithEditing ;
142
+ for (let index = 0 ; index < headers . value . data .length ; index ++ ) {
143
+ const header: HeaderWithEditing = headers . value . data [index ] as HeaderWithEditing ;
155
144
156
145
header .isLocked = false ;
157
146
header .isSensitive = false ;
158
147
header .isMarkedAsRemoved = false ;
159
148
header .isChanged = false ;
160
149
161
- if (props . configuration .locked_headers .includes (header .key )) {
150
+ if (edit_and_retry_config . value .locked_headers .includes (header .key )) {
162
151
header .isLocked = true ;
163
- } else if (props . configuration .sensitive_headers .includes (header .key )) {
152
+ } else if (edit_and_retry_config . value .sensitive_headers .includes (header .key )) {
164
153
header .isSensitive = true ;
165
154
}
166
155
167
- localMessage . value .headers [index ] = header ;
156
+ local .headers [index ] = header ;
168
157
}
158
+
159
+ localMessage .value = local ;
169
160
}
170
161
171
162
function togglePanel(panelNum : number ) {
172
163
panel .value = panelNum ;
173
- return false ;
174
164
}
175
165
176
166
onMounted (() => {
@@ -225,14 +215,22 @@ onMounted(() => {
225
215
</tr >
226
216
</tbody >
227
217
</table >
228
- <div role =" tabpanel" v-if =" panel === 2 && !localMessage.bodyUnavailable" style =" height : calc (100% - 260px )" >
229
- <div style =" margin-top : 1.25rem " >
230
- <CodeEditor aria-label =" message body" :read-only =" !localMessage.isContentTypeSupported" v-model =" localMessage.messageBody" :language =" localMessage.language" :show-gutter =" true" ></CodeEditor >
218
+ <template v-if =" panel === 2 " >
219
+ <div role =" tabpanel" v-if =" !localMessage.bodyUnavailable" >
220
+ <div style =" margin-top : 1.25rem " >
221
+ <LoadingSpinner v-if =" body.loading" />
222
+ <CodeEditor v-else aria-label =" message body" :read-only =" !localMessage.isContentTypeSupported" v-model =" localMessage.messageBody" :language =" localMessage.language" :show-gutter =" true" >
223
+ <template #toolbarLeft >
224
+ <span class =" empty-error" v-if =" localMessage.isBodyEmpty" ><i class =" fa fa-exclamation-triangle" ></i > Message body cannot be empty</span >
225
+ </template >
226
+ <template #toolbarRight >
227
+ <button v-if =" localMessage.isBodyChanged" type =" button" class =" btn btn-secondary btn-sm" @click =" resetBodyChanges" ><i class =" fa fa-undo" ></i > Reset changes</button >
228
+ </template >
229
+ </CodeEditor >
230
+ </div >
231
231
</div >
232
- <span class =" empty-error" v-if =" localMessage.isBodyEmpty" ><i class =" fa fa-exclamation-triangle" ></i > Message body cannot be empty</span >
233
- <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 >
234
- <div class =" alert alert-info" v-if =" panel === 2 && localMessage.bodyUnavailable" >{{ localMessage.bodyUnavailable }}</div >
235
- </div >
232
+ <div role =" tabpanel" class =" alert alert-info" v-else >{{ localMessage.bodyUnavailable }}</div >
233
+ </template >
236
234
</div >
237
235
</div >
238
236
</div >
@@ -280,14 +278,6 @@ onMounted(() => {
280
278
margin-right : 20px ;
281
279
}
282
280
283
- .modal-msg-editor .reset-body {
284
- color : #00a3c4 ;
285
- font-weight : bold ;
286
- text-align : left ;
287
- margin-top : 15px ;
288
- display : inline-block ;
289
- }
290
-
291
281
.modal-msg-editor .reset-body a :hover {
292
282
cursor : pointer ;
293
283
}
@@ -297,8 +287,6 @@ onMounted(() => {
297
287
}
298
288
299
289
.modal-msg-editor .empty-error {
300
- float : right ;
301
- margin-top : 15px ;
302
290
color : #ce4844 ;
303
291
font-weight : bold ;
304
292
}
0 commit comments