Skip to content

Commit 334dc15

Browse files
committed
Merge branch 'deletedmessagegroups_store' into messages_store
2 parents e24e085 + 5a14215 commit 334dc15

File tree

9 files changed

+115
-37
lines changed

9 files changed

+115
-37
lines changed

src/Frontend/src/components/MetadataItem.vue

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,5 +25,6 @@ defineProps<Props>();
2525
2626
.icon {
2727
margin-right: 0.25rem;
28+
color: var(--reduced-emphasis);
2829
}
2930
</style>
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<script setup lang="ts">
2+
const emit = defineEmits<{
3+
close: [];
4+
}>();
5+
6+
function closeDialog() {
7+
emit("close");
8+
}
9+
</script>
10+
11+
<template>
12+
<section name="edit_ignored_dialog">
13+
<div class="modal" style="z-index: 1050; display: block" role="dialog" aria-label="edit ignored">
14+
<div class="modal-mask">
15+
<div class="modal-dialog">
16+
<div class="modal-content">
17+
<div class="modal-header">
18+
<div class="modal-title">
19+
<h3>Edit Ignored</h3>
20+
</div>
21+
</div>
22+
<div class="modal-body">
23+
<p>This retry was ignored because another edit had already been processed.</p>
24+
</div>
25+
<div class="modal-footer">
26+
<button class="btn btn-primary" @click="closeDialog()">Ok</button>
27+
</div>
28+
</div>
29+
</div>
30+
</div>
31+
</div>
32+
</section>
33+
</template>
34+
35+
<style scoped>
36+
@import "@/components/modal.css";
37+
</style>

src/Frontend/src/components/failedmessages/EditRetryDialog.vue

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,8 @@ import { storeToRefs } from "pinia";
1010
import LoadingSpinner from "@/components/LoadingSpinner.vue";
1111
import FAIcon from "@/components/FAIcon.vue";
1212
import { faExclamationCircle, faExclamationTriangle, faUndo } from "@fortawesome/free-solid-svg-icons";
13+
import { HeaderWithEditing } from "@/resources/EditMessage";
1314
import { useDebounceFn } from "@vueuse/core";
14-
import useEnvironmentAndVersionsAutoRefresh from "@/composables/useEnvironmentAndVersionsAutoRefresh";
15-
import { useServiceControlStore } from "@/stores/ServiceControlStore";
16-
17-
interface HeaderWithEditing extends Header {
18-
isLocked: boolean;
19-
isSensitive: boolean;
20-
isMarkedAsRemoved: boolean;
21-
isChanged: boolean;
22-
}
2315
2416
const emit = defineEmits<{
2517
cancel: [];
@@ -56,9 +48,6 @@ const showCancelConfirmation = ref(false);
5648
const showEditRetryGenericError = ref(false);
5749
const messageStore = useMessageStore();
5850
const { state, headers, body, edit_and_retry_config } = storeToRefs(messageStore);
59-
const { store: environmentStore } = useEnvironmentAndVersionsAutoRefresh();
60-
const areSimpleHeadersSupported = environmentStore.serviceControlIsGreaterThan("5.2.0");
61-
const serviceControlStore = useServiceControlStore();
6251
6352
const id = computed(() => state.value.data.id ?? "");
6453
const uneditedMessageBody = computed(() => body.value.data.value ?? "");
@@ -110,24 +99,7 @@ function removeHeadersMarkedAsRemoved() {
11099
async function retryEditedMessage() {
111100
removeHeadersMarkedAsRemoved();
112101
try {
113-
const payload = {
114-
message_body: localMessage.value.messageBody,
115-
message_headers: areSimpleHeadersSupported.value
116-
? localMessage.value.headers.reduce(
117-
(result, header) => {
118-
const { key, value } = header as { key: string; value: string };
119-
result[key] = value;
120-
return result;
121-
},
122-
{} as { [key: string]: string }
123-
)
124-
: localMessage.value.headers,
125-
};
126-
const response = await serviceControlStore.postToServiceControl(`edit/${id.value}`, payload);
127-
if (!response.ok) {
128-
throw new Error(response.statusText);
129-
}
130-
102+
await messageStore.retryEditedMessage(id.value, localMessage);
131103
localMessage.value.retried = true;
132104
return emit("confirm");
133105
} catch {

src/Frontend/src/components/messages/EditAndRetryButton.vue

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,36 @@ import { computed, ref } from "vue";
55
import { useShowToast } from "@/composables/toast";
66
import { TYPE } from "vue-toastification";
77
import EditRetryDialog from "@/components/failedmessages/EditRetryDialog.vue";
8+
import EditIgnoredDialog from "@/components/failedmessages/EditIgnoredDialog.vue";
89
import { MessageStatus } from "@/resources/Message";
910
import { storeToRefs } from "pinia";
1011
import { FailedMessageStatus } from "@/resources/FailedMessage";
1112
import { faPencil } from "@fortawesome/free-solid-svg-icons";
1213
1314
const store = useMessageStore();
14-
const { state, edit_and_retry_config } = storeToRefs(store);
15+
const { state, edit_and_retry_config, editRetryResponse } = storeToRefs(store);
1516
const isConfirmDialogVisible = ref(false);
17+
const isEditIgnoredDialogVisible = ref(false);
1618
1719
const failureStatus = computed(() => state.value.data.failure_status);
1820
const isDisabled = computed(() => failureStatus.value.retried || failureStatus.value.archived || failureStatus.value.resolved);
1921
const isVisible = computed(() => edit_and_retry_config.value.enabled && state.value.data.status !== MessageStatus.Successful && state.value.data.status !== MessageStatus.ResolvedSuccessfully);
22+
23+
const handleIgnoreClose = async () => {
24+
isEditIgnoredDialogVisible.value = false;
25+
await store.pollForNextUpdate(FailedMessageStatus.Resolved);
26+
};
27+
2028
const handleConfirm = async () => {
2129
isConfirmDialogVisible.value = false;
2230
23-
const message = `Retrying the edited message ${state.value.data.id} ...`;
24-
useShowToast(TYPE.INFO, "Info", message);
25-
await store.pollForNextUpdate(FailedMessageStatus.Resolved);
31+
if (editRetryResponse.value?.edit_ignored) {
32+
isEditIgnoredDialogVisible.value = true;
33+
} else {
34+
const message = `Retrying the edited message ${state.value.data.id} ...`;
35+
useShowToast(TYPE.INFO, "Info", message);
36+
await store.pollForNextUpdate(FailedMessageStatus.Resolved);
37+
}
2638
};
2739
2840
async function openDialog() {
@@ -36,6 +48,7 @@ async function openDialog() {
3648
<ActionButton :icon="faPencil" aria-label="Edit & retry" :disabled="isDisabled" @click="openDialog">Edit & retry</ActionButton>
3749
<Teleport to="#modalDisplay">
3850
<EditRetryDialog v-if="isConfirmDialogVisible" @cancel="isConfirmDialogVisible = false" @confirm="handleConfirm"></EditRetryDialog>
51+
<EditIgnoredDialog v-if="isEditIgnoredDialogVisible" @close="handleIgnoreClose"></EditIgnoredDialog>
3952
</Teleport>
4053
</template>
4154
</template>

src/Frontend/src/components/messages/MessageView.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ watch(
9393
},
9494
{ immediate: true }
9595
);
96-
const endpointColor = hexToCSSFilter("#777F7F").filter;
96+
const endpointColor = hexToCSSFilter("#929E9E").filter;
9797
9898
onMounted(() => {
9999
const { back, ...otherArgs } = route.query;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import type Header from "./Header";
2+
3+
export interface HeaderWithEditing extends Header {
4+
isLocked: boolean;
5+
isSensitive: boolean;
6+
isMarkedAsRemoved: boolean;
7+
isChanged: boolean;
8+
}
9+
10+
export interface EditedMessage {
11+
messageBody: string;
12+
headers: HeaderWithEditing[];
13+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default interface EditRetryResponse {
2+
edit_ignored: boolean;
3+
}

src/Frontend/src/stores/MessageStore.ts

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { acceptHMRUpdate, defineStore, storeToRefs } from "pinia";
2-
import { computed, reactive, ref, watch } from "vue";
2+
import { computed, reactive, Ref, ref, watch } from "vue";
33
import Header from "@/resources/Header";
44
import type EndpointDetails from "@/resources/EndpointDetails";
55
import { FailedMessage, ExceptionDetails, FailedMessageStatus } from "@/resources/FailedMessage";
@@ -11,6 +11,9 @@ import xmlFormat from "xml-formatter";
1111
import { DataContainer } from "./DataContainer";
1212
import { useServiceControlStore } from "./ServiceControlStore";
1313
import { EditAndRetryConfig } from "@/resources/Configuration";
14+
import EditRetryResponse from "@/resources/EditRetryResponse";
15+
import { EditedMessage } from "@/resources/EditMessage";
16+
import useEnvironmentAndVersionsAutoRefresh from "@/composables/useEnvironmentAndVersionsAutoRefresh";
1417

1518
interface Model {
1619
id?: string;
@@ -65,12 +68,15 @@ export const useMessageStore = defineStore("MessageStore", () => {
6568
const edit_and_retry_config = ref<EditAndRetryConfig>({ enabled: false, locked_headers: [], sensitive_headers: [] });
6669
const conversationData = ref<DataContainer<Message[]>>({ data: [] });
6770

71+
const editRetryResponse = ref<EditRetryResponse | null>(null);
6872
let bodyLoadedId = "";
6973
let conversationLoadedId = "";
7074

7175
const configStore = useConfigurationStore();
7276
const serviceControlStore = useServiceControlStore();
7377
const { serviceControlUrl } = storeToRefs(serviceControlStore);
78+
const { store: environmentStore } = useEnvironmentAndVersionsAutoRefresh();
79+
const areSimpleHeadersSupported = environmentStore.serviceControlIsGreaterThan("5.2.0");
7480

7581
const { configuration } = storeToRefs(configStore);
7682
const error_retention_period = computed(() => moment.duration(configuration.value?.data_retention?.error_retention_period).asHours());
@@ -89,6 +95,7 @@ export const useMessageStore = defineStore("MessageStore", () => {
8995
bodyLoadedId = "";
9096
conversationLoadedId = "";
9197
conversationData.value.data = [];
98+
editRetryResponse.value = null;
9299
}
93100

94101
async function loadFailedMessage(id: string) {
@@ -267,6 +274,36 @@ export const useMessageStore = defineStore("MessageStore", () => {
267274
}
268275
}
269276

277+
async function retryEditedMessage(id: string, editedMessage: Ref<EditedMessage>) {
278+
const payload = {
279+
message_body: editedMessage.value.messageBody,
280+
message_headers: areSimpleHeadersSupported.value
281+
? editedMessage.value.headers.reduce(
282+
(result, header) => {
283+
const { key, value } = header as { key: string; value: string };
284+
result[key] = value;
285+
return result;
286+
},
287+
{} as { [key: string]: string }
288+
)
289+
: editedMessage.value.headers,
290+
};
291+
const response = await serviceControlStore.postToServiceControl(`edit/${id}`, payload);
292+
if (!response.ok) {
293+
throw new Error(response.statusText);
294+
}
295+
296+
//older versions of SC return no payload about the edit result
297+
const bodyText = await response.text();
298+
if (bodyText === "") {
299+
editRetryResponse.value = {
300+
edit_ignored: false,
301+
};
302+
} else {
303+
editRetryResponse.value = parse(bodyText) as EditRetryResponse;
304+
}
305+
}
306+
270307
async function pollForNextUpdate(status: FailedMessageStatus) {
271308
if (!state.data.id) {
272309
return;
@@ -326,6 +363,7 @@ export const useMessageStore = defineStore("MessageStore", () => {
326363
body,
327364
state,
328365
edit_and_retry_config,
366+
editRetryResponse,
329367
reset,
330368
loadMessage,
331369
loadFailedMessage,
@@ -338,6 +376,7 @@ export const useMessageStore = defineStore("MessageStore", () => {
338376
retryMessages,
339377
conversationData,
340378
pollForNextUpdate,
379+
retryEditedMessage,
341380
};
342381
});
343382

src/ServicePulse.Host.Tests/ServicePulse.Host.Tests.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
<ItemGroup>
1212
<PackageReference Include="GitHubActionsTestLogger" Version="2.4.1" />
13-
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.0" />
13+
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.0.1" />
1414
<PackageReference Include="NUnit" Version="4.4.0" />
1515
<PackageReference Include="NUnit3TestAdapter" Version="5.2.0" />
1616
<PackageReference Include="Particular.Approvals" Version="1.1.1" />

0 commit comments

Comments
 (0)