Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 1 addition & 16 deletions src/Frontend/src/components/audit/AuditList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ import { storeToRefs } from "pinia";
import SortableColumn from "../SortableColumn.vue";
import { MessageStatus } from "@/resources/Message";
import moment from "moment";
import { useFormatTime } from "@/composables/formatter";
import RefreshConfig from "../RefreshConfig.vue";
import ItemsPerPage from "../ItemsPerPage.vue";
import PaginationStrip from "../PaginationStrip.vue";
import { useRoute } from "vue-router";
import { friendlyTypeName, formatDotNetTimespan } from "../messages2/utils";

const store = useAuditStore();
const { messages, sortByInstances, itemsPerPage, selectedPage, totalCount } = storeToRefs(store);
Expand Down Expand Up @@ -48,21 +48,6 @@ function statusToIcon(messageStatus: MessageStatus) {
return "fa retry-issued";
}
}

function friendlyTypeName(messageType: string) {
if (messageType == null) return null;

const typeClass = messageType.split(",")[0];
const typeName = typeClass.split(".").reverse()[0];
return typeName.replace(/\+/g, ".");
}

function formatDotNetTimespan(timespan: string) {
//assuming if we have days in the timespan then something is very, very wrong
const [hh, mm, ss] = timespan.split(":");
const time = useFormatTime(((parseInt(hh) * 60 + parseInt(mm)) * 60 + parseFloat(ss)) * 1000);
return `${time.value} ${time.unit}`;
}
</script>

<template>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import MessageList, { IMessageList } from "./MessageList.vue";
import ConfirmDialog from "../ConfirmDialog.vue";
import PaginationStrip from "../../components/PaginationStrip.vue";
import moment from "moment";
import { ExtendedFailedMessage } from "@/resources/FailedMessage";
import { ExtendedFailedMessage } from "../messages2/FailedMessage";
import { TYPE } from "vue-toastification";
import FailureGroup from "@/resources/FailureGroup";
import { useConfiguration } from "@/composables/configuration";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { useRetryEditedMessage } from "@/composables/serviceFailedMessage";
import MessageHeader from "./EditMessageHeader.vue";
import { EditAndRetryConfig } from "@/resources/Configuration";
import type Header from "@/resources/Header";
import { ExtendedFailedMessage } from "@/resources/FailedMessage";
import { ExtendedFailedMessage } from "../messages2/FailedMessage";
import parseContentType from "@/composables/contentTypeParser";
import { CodeLanguage } from "@/components/codeEditorTypes";
import CodeEditor from "@/components/CodeEditor.vue";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import ServiceControlNotAvailable from "../ServiceControlNotAvailable.vue";
import MessageList, { IMessageList } from "./MessageList.vue";
import ConfirmDialog from "../ConfirmDialog.vue";
import PaginationStrip from "../../components/PaginationStrip.vue";
import { ExtendedFailedMessage, FailedMessageStatus } from "@/resources/FailedMessage";
import { FailedMessageStatus } from "@/resources/FailedMessage";
import { ExtendedFailedMessage } from "../messages2/FailedMessage";
import SortOptions, { SortDirection } from "@/resources/SortOptions";
import { TYPE } from "vue-toastification";
import GroupOperation from "@/resources/GroupOperation";
Expand Down
3 changes: 2 additions & 1 deletion src/Frontend/src/components/failedmessages/MessageList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { useRouter } from "vue-router";
import TimeSince from "../TimeSince.vue";
import NoData from "../NoData.vue";
import routeLinks from "@/router/routeLinks";
import { FailedMessageStatus, ExtendedFailedMessage } from "@/resources/FailedMessage";
import { FailedMessageStatus } from "@/resources/FailedMessage";
import { ExtendedFailedMessage } from "../messages2/FailedMessage";
import { hexToCSSFilter } from "hex-to-css-filter";

export interface IMessageList {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import ServiceControlNotAvailable from "../ServiceControlNotAvailable.vue";
import MessageList, { IMessageList } from "./MessageList.vue";
import ConfirmDialog from "../ConfirmDialog.vue";
import PaginationStrip from "../../components/PaginationStrip.vue";
import { ExtendedFailedMessage, FailedMessageStatus } from "@/resources/FailedMessage";
import { FailedMessageStatus } from "@/resources/FailedMessage";
import { ExtendedFailedMessage } from "../messages2/FailedMessage";
import SortOptions, { SortDirection } from "@/resources/SortOptions";
import QueueAddress from "@/resources/QueueAddress";
import { TYPE } from "vue-toastification";
Expand Down
2 changes: 1 addition & 1 deletion src/Frontend/src/components/messages/BodyView.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { ExtendedFailedMessage } from "@/resources/FailedMessage";
import { ExtendedFailedMessage } from "../messages2/FailedMessage";
import { computed } from "vue";
import CodeEditor from "@/components/CodeEditor.vue";
import parseContentType from "@/composables/contentTypeParser";
Expand Down
2 changes: 1 addition & 1 deletion src/Frontend/src/components/messages/FlowDiagram.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import routeLinks from "@/router/routeLinks";
import Message from "@/resources/Message";
import { NServiceBusHeaders } from "@/resources/Header";
import { useRoute } from "vue-router";
import { ExtendedFailedMessage } from "@/resources/FailedMessage";
import { ExtendedFailedMessage } from "../messages2/FailedMessage";
import { Controls } from "@vue-flow/controls";

const props = defineProps<{
Expand Down
2 changes: 1 addition & 1 deletion src/Frontend/src/components/messages/HeadersView.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { ExtendedFailedMessage } from "@/resources/FailedMessage";
import { ExtendedFailedMessage } from "../messages2/FailedMessage";
import CopyToClipboard from "@/components/CopyToClipboard.vue";
import FilterInput from "@/components/FilterInput.vue";
import { computed, ref } from "vue";
Expand Down
3 changes: 2 additions & 1 deletion src/Frontend/src/components/messages/MessageView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ import EditRetryDialog from "../failedmessages/EditRetryDialog.vue";
import routeLinks from "@/router/routeLinks";
import { EditAndRetryConfig } from "@/resources/Configuration";
import { TYPE } from "vue-toastification";
import { ExtendedFailedMessage, FailedMessageError, FailedMessageStatus, isError } from "@/resources/FailedMessage";
import { FailedMessageError, FailedMessageStatus } from "@/resources/FailedMessage";
import { ExtendedFailedMessage, isError } from "../messages2/FailedMessage";
import Message from "@/resources/Message";
import { NServiceBusHeaders } from "@/resources/Header";
import { useConfiguration } from "@/composables/configuration";
Expand Down
2 changes: 1 addition & 1 deletion src/Frontend/src/components/messages/StacktraceView.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { ExtendedFailedMessage } from "@/resources/FailedMessage";
import CodeEditor from "@/components/CodeEditor.vue";
import { ExtendedFailedMessage } from "../messages2/FailedMessage";

const props = defineProps<{
message: ExtendedFailedMessage;
Expand Down
33 changes: 33 additions & 0 deletions src/Frontend/src/components/messages2/FailedMessage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import FailedMessage, { FailedMessageError } from "@/resources/FailedMessage";
import Header from "@/resources/Header";
import { ConversationModel } from "./SequenceDiagram/SequenceModel";

export interface ExtendedFailedMessage extends FailedMessage {
error_retention_period: number;
delete_soon: boolean;
deleted_in: string;
retryInProgress: boolean;
deleteInProgress: boolean;
restoreInProgress: boolean;
selected: boolean;
retried: boolean;
archiving: boolean;
restoring: boolean;
archived: boolean;
resolved: boolean;
headersNotFound: boolean;
messageBodyNotFound: boolean;
bodyUnavailable: boolean;
headers: Header[];
conversationId: string;
conversation?: ConversationModel;
messageBody: string;
contentType: string;
isEditAndRetryEnabled: boolean;
redirect: boolean;
submittedForRetrial: boolean;
}

export function isError(obj: ExtendedFailedMessage | FailedMessageError): obj is FailedMessageError {
return (obj as FailedMessageError).error !== undefined || (obj as FailedMessageError).notFound !== undefined;
}
8 changes: 8 additions & 0 deletions src/Frontend/src/components/messages2/SequenceDiagram.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ onMounted(() => store.refreshConversation());
</script>

<template>
<a class="help-link" target="_blank" href="https://docs.particular.net/servicepulse/sequence-diagram"><i class="fa fa-info-circle" /> Sequence Diagram Help</a>
<div class="outer" @scroll="(ev) => (endpointYOffset = (ev.target as Element).scrollTop)">
<svg class="sequence-diagram" :style="{ width: `max(100%, ${isNaN(maxWidth) ? 0 : maxWidth}px)` }" :height="maxHeight + 20">
<Timeline />
Expand Down Expand Up @@ -48,4 +49,11 @@ onMounted(() => store.refreshConversation());
--highlight-background: #c5dee9;
background: white;
}

.help-link {
display: flex;
align-items: center;
justify-content: end;
gap: 0.15rem;
}
</style>
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { NServiceBusHeaders } from "../Header";
import Message from "../Message";
import { NServiceBusHeaders } from "../../../resources/Header";
import Message from "../../../resources/Message";
import { Handler } from "./Handler";

export interface Endpoint {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { Endpoint } from "@/resources/SequenceDiagram/Endpoint";
import { Endpoint } from "@/components/messages2/SequenceDiagram/Endpoint";

defineProps<{ endpoint: Endpoint }>();
</script>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { Endpoint } from "@/resources/SequenceDiagram/Endpoint";
import { Endpoint } from "@/components/messages2/SequenceDiagram/Endpoint";
import { Endpoint_Width, EndpointCentrePoint, useSequenceDiagramStore } from "@/stores/SequenceDiagramStore";
import { storeToRefs } from "pinia";
import { computed, ref, watch } from "vue";
Expand Down Expand Up @@ -67,7 +67,7 @@ const endpointItems = computed(() =>
);

watch(endpointItems, () => {
store.setEndpointCentrePoints(endpointItems.value.map((endpoint) => ({ name: endpoint.name, centre: endpoint.x ?? 0, top: (endpoint.surround?.y ?? 0) + (endpoint.surround?.height ?? 0) + 15 }) as EndpointCentrePoint));
store.setEndpointCentrePoints(endpointItems.value.map((endpoint) => ({ name: endpoint.name, centre: endpoint.x, top: (endpoint.surround?.y ?? 0) + (endpoint.surround?.height ?? 0) + 15 }) as EndpointCentrePoint));
const lastEndpoint = endpointItems.value[endpointItems.value.length - 1];
store.setMaxWidth((lastEndpoint.x ?? 0) + lastEndpoint.width);
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { NServiceBusHeaders } from "../Header";
import Message, { MessageStatus } from "../Message";
import { NServiceBusHeaders } from "../../../resources/Header";
import Message, { MessageStatus } from "../../../resources/Message";
import { Direction, MessageProcessingRoute, RoutedMessage } from "./RoutedMessage";
import { Endpoint } from "./Endpoint";
import { friendlyTypeName } from "./SequenceModel";
import { formatDotNetTimespan, friendlyTypeName } from "../utils";

export interface Handler {
readonly id: string;
Expand All @@ -16,7 +16,7 @@ export interface Handler {
readonly outMessages: RoutedMessage[];
processedAt?: Date;
readonly handledAt?: Date;
processingTime?: number;
processingTime?: string;
readonly direction: Direction;
route?: MessageProcessingRoute;
readonly selectedMessage?: Message;
Expand Down Expand Up @@ -58,10 +58,7 @@ export class HandlerRegistry {

export function updateProcessingHandler(handler: Handler, message: Message) {
handler.processedAt = new Date(message.processed_at);
//assuming if we have days in the timespan then something is very, very wrong
//TODO: extract logic since it's also currently used in AuditList
const [hh, mm, ss] = message.processing_time.split(":");
handler.processingTime = ((parseInt(hh) * 60 + parseInt(mm)) * 60 + parseFloat(ss)) * 1000;
handler.processingTime = formatDotNetTimespan(message.processing_time);
handler.name = message.message_type;
handler.friendlyName = friendlyTypeName(message.message_type);

Expand Down Expand Up @@ -90,7 +87,7 @@ class HandlerItem implements Handler {
inMessage?: RoutedMessage;
state: HandlerState = HandlerState.Unknown;
processedAt?: Date;
processingTime?: number;
processingTime?: string;
route?: MessageProcessingRoute;
uiRef?: SVGElement;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
<script setup lang="ts">
import { useFormatTime } from "@/composables/formatter";
import { Handler } from "@/resources/SequenceDiagram/Handler";
import { Handler } from "@/components/messages2/SequenceDiagram/Handler";

defineProps<{ handler: Handler }>();

function formatTime(milliseconds: number) {
const time = useFormatTime(milliseconds);
return `${time.value} ${time.unit}`;
}
</script>

<template>
Expand All @@ -16,7 +10,7 @@ function formatTime(milliseconds: number) {
<div class="title">Processing of Message</div>
<div class="details">
<label>Processing Time:</label>
<span>{{ formatTime(handler.processingTime ?? 0) }}</span>
<span>{{ handler.processingTime }}</span>
<label>Processing Of:</label>
<span>{{ handler.friendlyName }}</span>
<label v-if="handler.partOfSaga">Sagas Invoked:</label>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script setup lang="ts">
import { HandlerState } from "@/resources/SequenceDiagram/Handler";
import { HandlerState } from "@/components/messages2/SequenceDiagram/Handler";
import { computed, onActivated, ref, watch } from "vue";
import { Direction } from "@/resources/SequenceDiagram/RoutedMessage";
import { Direction } from "@/components/messages2/SequenceDiagram/RoutedMessage";
import { useSequenceDiagramStore } from "@/stores/SequenceDiagramStore";
import { storeToRefs } from "pinia";

Expand Down Expand Up @@ -52,8 +52,8 @@ const handlerItems = computed(() => {

//determine which side of the handler to render the messageType on. If it's the left side (for a right arrow) then we apply a negative offset
const messageTypeOffset = handler.direction === Direction.Right ? ((messageTypeElement?.getBBox().width ?? 0) + 24) * -1 : 20;
const left = (endpoint?.centre ?? 0) - Handler_Width / 2;
const right = (endpoint?.centre ?? 0) + Handler_Width / 2;
const left = (endpoint?.centre ?? store.startX) - Handler_Width / 2;
const right = (endpoint?.centre ?? store.startX) + Handler_Width / 2;
if (left + messageTypeOffset < 0) {
store.setStartX(-1 * (left + messageTypeOffset) + 20);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { RoutedMessage, RoutedMessageType } from "@/resources/SequenceDiagram/RoutedMessage";
import { RoutedMessage, RoutedMessageType } from "@/components/messages2/SequenceDiagram/RoutedMessage";

defineProps<{ routedMessage: RoutedMessage }>();
</script>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import EndpointDetails from "../EndpointDetails";
import { NServiceBusHeaders } from "../Header";
import Message, { MessageIntent, MessageStatus } from "../Message";
import EndpointDetails from "../../../resources/EndpointDetails";
import { NServiceBusHeaders } from "../../../resources/Header";
import Message, { MessageIntent, MessageStatus } from "../../../resources/Message";
import { Handler } from "./Handler";
import { friendlyTypeName } from "./SequenceModel";
import { friendlyTypeName } from "../utils";

export interface RoutedMessage {
id: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<script setup lang="ts">
import { Direction, RoutedMessageType } from "@/resources/SequenceDiagram/RoutedMessage";
import { Direction, RoutedMessageType } from "@/components/messages2/SequenceDiagram/RoutedMessage";
import { computed, ref } from "vue";
import { useSequenceDiagramStore } from "@/stores/SequenceDiagramStore";
import { storeToRefs } from "pinia";
import { HandlerState } from "@/resources/SequenceDiagram/Handler";
import { HandlerState } from "@/components/messages2/SequenceDiagram/Handler";

const Arrow_Head_Width = 10;
const Message_Type_Margin = 4;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { NServiceBusHeaders } from "../Header";
import Message from "../Message";
import { NServiceBusHeaders } from "../../../resources/Header";
import Message from "../../../resources/Message";
import { createRoutedMessage, createRoute, MessageProcessingRoute } from "./RoutedMessage";
import { createProcessingEndpoint, createSendingEndpoint, Endpoint, EndpointRegistry } from "./Endpoint";
import { ConversationStartHandlerName, createProcessingHandler, createSendingHandler, Handler, HandlerRegistry, updateProcessingHandler } from "./Handler";
Expand All @@ -8,15 +8,6 @@ export interface ConversationModel {
endpoints: Endpoint[];
}

//TODO: extract to common area if this continues to be used in AuditList
export function friendlyTypeName(messageType: string) {
if (messageType == null) return undefined;

const typeClass = messageType.split(",")[0];
const typeName = typeClass.split(".").reverse()[0];
return typeName.replace(/\+/g, ".");
}

export class ModelCreator implements ConversationModel {
#endpoints: Endpoint[];
#handlers: Handler[];
Expand Down Expand Up @@ -136,7 +127,6 @@ class MessageTreeNode {
}

walk(): Message[] {
//TODO: check performance of this. We may need to pre-calculate the processed_at as a date on the message object
return [this.#message, ...this.children.sort((a, b) => new Date(a.message.processed_at).getTime() - new Date(b.message.processed_at).getTime()).flatMap((child) => child.walk())];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ const { endpointCentrePoints, maxHeight } = storeToRefs(store);

<template>
<g v-for="timeline in endpointCentrePoints" :key="timeline.name">
<path :d="`M${timeline.centre} ${timeline.top} v0 ${maxHeight - timeline.top}`" stroke="var(--gray90)" stroke-width="2" />
<path v-if="timeline.centre" :d="`M${timeline.centre} ${timeline.top} v0 ${maxHeight - timeline.top}`" stroke="var(--gray90)" stroke-width="2" />
</g>
</template>
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useTippy } from "vue-tippy";
import EndpointTooltip from "./EndpointTooltip.vue";
import HandlerTooltip from "./HandlerTooltip.vue";
import RouteTooltip from "./RouteTooltip.vue";
import { HandlerState } from "@/resources/SequenceDiagram/Handler";
import { HandlerState } from "@/components/messages2/SequenceDiagram/Handler";

export default function useTooltips() {
const store = useSequenceDiagramStore();
Expand Down
16 changes: 16 additions & 0 deletions src/Frontend/src/components/messages2/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { useFormatTime } from "@/composables/formatter";

export function friendlyTypeName(messageType: string) {
if (messageType == null) return undefined;

const typeClass = messageType.split(",")[0];
const typeName = typeClass.split(".").reverse()[0];
return typeName.replace(/\+/g, ".");
}

export function formatDotNetTimespan(timespan: string) {
//assuming if we have days in the timespan then something is very, very wrong
const [hh, mm, ss] = timespan.split(":");
const time = useFormatTime(((parseInt(hh) * 60 + parseInt(mm)) * 60 + parseFloat(ss)) * 1000);
return `${time.value} ${time.unit}`;
}
Loading