Skip to content

Commit eb5ffa5

Browse files
committed
handlers
1 parent 90a0052 commit eb5ffa5

File tree

4 files changed

+112
-19
lines changed

4 files changed

+112
-19
lines changed

src/Frontend/src/components/messages/SequenceDiagram.vue

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ import { ModelCreator } from "@/resources/SequenceDiagram/SequenceModel";
88
import { ref } from "vue";
99
import Endpoints, { EndpointCentrePoint } from "./SequenceDiagram/EndpointsComponent.vue";
1010
import Timeline from "./SequenceDiagram/TimelineComponent.vue";
11+
import Handlers from "./SequenceDiagram/HandlersComponent.vue";
1112
1213
const endpoints = ref<Endpoint[]>([]);
1314
const handlers = ref<Handler[]>([]);
1415
const routes = ref<MessageProcessingRoute[]>([]);
15-
const timelines = ref<EndpointCentrePoint[]>([]);
16+
const endpointCentrePoints = ref<EndpointCentrePoint[]>([]);
17+
const maxHeight = ref(150);
1618
1719
async function fetchConversation() {
1820
const response = await useFetchFromServiceControl(`conversations/${"b4dac7d7-4571-4f26-aa32-b29c0030c95f"}`); //${"9d91504c-d8b7-488c-b525-b2a300109653"}`);
@@ -29,14 +31,18 @@ async function fetchConversation() {
2931
fetchConversation();
3032
3133
function setTimelines(centrePoints: EndpointCentrePoint[]) {
32-
timelines.value = centrePoints;
34+
endpointCentrePoints.value = centrePoints;
35+
}
36+
function setMaxHeight(height: number) {
37+
maxHeight.value = height;
3338
}
3439
</script>
3540

3641
<template>
37-
<svg class="sequence-diagram" width="100%" height="100%">
42+
<svg class="sequence-diagram" width="100%" :height="maxHeight + 20">
3843
<Endpoints :endpoints="endpoints" v-on:centre-points="setTimelines" />
39-
<Timeline :centre-points="timelines" :height="150" />
44+
<Timeline :centre-points="endpointCentrePoints" :height="maxHeight" />
45+
<Handlers :handlers="handlers" :endpoint-centre-points="endpointCentrePoints" v-on:max-height="setMaxHeight" />
4046
</svg>
4147
</template>
4248

src/Frontend/src/components/messages/SequenceDiagram/EndpointsComponent.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ function setEndpointRef(el: SVGTextElement, index: number) {
9999
></rect>
100100
<g :transform="`translate(${(endpoint.x ?? Endpoint_Width / 2) - ((endpoint.textWidth ?? 0) + Endpoint_Image_Width) / 2},0)`">
101101
<path fill="var(--gray40)" d="M 0,0 M 18,18 M 0,2 v 14 h 14 v -4 h -6 v -6 h 6 v -4 h -14 M 9,7 v 4 h 9 v -4"></path>
102-
<text :x="Endpoint_Image_Width" y="10" alignment-baseline="middle" text-anchor="left" :ref="(el) => setEndpointRef(el as SVGTextElement, i)">{{ endpoint.name }}</text>
102+
<text :x="Endpoint_Image_Width" y="10" alignment-baseline="middle" text-anchor="start" :ref="(el) => setEndpointRef(el as SVGTextElement, i)">{{ endpoint.name }}</text>
103103
</g>
104104
</g>
105105
</template>
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
<script setup lang="ts">
2+
import { Handler, HandlerState } from "@/resources/SequenceDiagram/Handler";
3+
import { EndpointCentrePoint } from "./EndpointsComponent.vue";
4+
import { computed, ref } from "vue";
5+
import { Direction } from "@/resources/SequenceDiagram/RoutedMessage";
6+
7+
const Height_Per_Out = 40;
8+
const Handler_Gap = 20;
9+
const Handler_Width = 14;
10+
11+
const props = defineProps<{
12+
handlers: Handler[];
13+
endpointCentrePoints: EndpointCentrePoint[];
14+
}>();
15+
const emit = defineEmits<{
16+
maxHeight: [height: number];
17+
}>();
18+
19+
const messageTypeRefs = ref<SVGTextElement[]>([]);
20+
21+
const handlers = computed(() => {
22+
let nextY = 0;
23+
const result = props.handlers.map((handler, index) => {
24+
const endpoint = props.endpointCentrePoints.find((cp) => cp.name === handler.endpoint.name)!;
25+
const messageTypeElement = messageTypeRefs.value[index];
26+
const count = handler.outMessages.length;
27+
const height = (count === 0 ? 1 : count) * Height_Per_Out;
28+
if (nextY === 0) nextY += Handler_Gap + (endpoint?.top ?? 0);
29+
const y = nextY;
30+
nextY += height + Handler_Gap;
31+
const fill = (() => {
32+
if (handler.id === "First") return "black";
33+
if (handler.state === HandlerState.Fail) return "var(--error)";
34+
return "var(--gray60)";
35+
})();
36+
const icon = (() => {
37+
if (handler.id === "First") return "M0,0L8,4 0,8z";
38+
if (handler.state === HandlerState.Fail) return "M6,0L0,6 6,12 12,6 6,0z M7,9L5,9 5,8 7,8 7,9z M5,7L5,3 7,3 7,7 5,7z";
39+
return null;
40+
})();
41+
const iconSize = (() => {
42+
if (handler.id === "First") return 8;
43+
if (handler.state === HandlerState.Fail) return 12;
44+
return 0;
45+
})();
46+
47+
return {
48+
key: handler.id,
49+
x: (endpoint?.centre ?? 0) - Handler_Width / 2,
50+
y,
51+
height,
52+
fill,
53+
icon,
54+
iconSize,
55+
messageType: handler.name,
56+
messageTypeOffset: handler.direction === Direction.Left ? ((messageTypeElement?.getBBox().width ?? 0) + 24) * -1 : 10,
57+
};
58+
});
59+
60+
emit("maxHeight", nextY);
61+
return result;
62+
});
63+
64+
function setMessageTypeRef(el: SVGTextElement, index: number) {
65+
if (el) messageTypeRefs.value[index] = el;
66+
}
67+
</script>
68+
69+
<template>
70+
<g>
71+
<g v-for="(handler, i) in handlers" :key="handler.key" :transform="`translate(${handler.x}, ${handler.y})`">
72+
<!--Handler Activation Box-->
73+
<rect :width="Handler_Width" :height="handler.height" :fill="handler.fill" />
74+
<path v-if="handler.icon" :d="handler.icon" fill="white" :transform="`translate(${Handler_Width / 2 - handler.iconSize / 2}, ${handler.height / 2 - handler.iconSize / 2})`" />
75+
<!--Message Type and Icon-->
76+
<g v-if="handler.messageType" :transform="`translate(${handler.messageTypeOffset}, 4)`" fill="var(--gray40)">
77+
<path d="M9,3L9,3 9,0 0,0 0,3 4,3 4,6 0,6 0,9 4,9 4,12 0,12 0,15 9,15 9,12 5,12 5,9 9,9 9,6 5,6 5,3z" />
78+
<text x="14" y="10" alignment-baseline="middle" :ref="(el) => setMessageTypeRef(el as SVGTextElement, i)">{{ handler.messageType }}</text>
79+
</g>
80+
</g>
81+
</g>
82+
</template>

src/Frontend/src/resources/SequenceDiagram/Handler.ts

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { NServiceBusHeaders } from "../Header";
22
import Message, { MessageStatus } from "../Message";
3-
import { MessageProcessingRoute, RoutedMessage } from "./RoutedMessage";
3+
import { Direction, MessageProcessingRoute, RoutedMessage } from "./RoutedMessage";
44
import { Endpoint } from "./Endpoint";
55
import { friendlyTypeName } from "./SequenceModel";
66

@@ -16,6 +16,7 @@ export interface Handler {
1616
processedAt?: Date;
1717
readonly handledAt?: Date;
1818
processingTime?: number;
19+
readonly direction: Direction;
1920
route?: MessageProcessingRoute;
2021
readonly selectedMessage?: Message;
2122
updateProcessedAt(timeSent: Date): void;
@@ -75,10 +76,10 @@ export function updateProcessingHandler(handler: Handler, message: Message) {
7576
}
7677

7778
class HandlerItem implements Handler {
78-
#id: string;
79-
#endpoint: Endpoint;
80-
#processedAtGuess?: Date;
81-
#outMessages: RoutedMessage[];
79+
private _id: string;
80+
private _endpoint: Endpoint;
81+
private _processedAtGuess?: Date;
82+
private _outMessages: RoutedMessage[];
8283
name?: string;
8384
partOfSaga?: string;
8485
inMessage?: RoutedMessage;
@@ -88,40 +89,44 @@ class HandlerItem implements Handler {
8889
route?: MessageProcessingRoute;
8990

9091
constructor(id: string, endpoint: Endpoint) {
91-
this.#id = id;
92-
this.#endpoint = endpoint;
93-
this.#outMessages = [];
92+
this._id = id;
93+
this._endpoint = endpoint;
94+
this._outMessages = [];
9495
}
9596

9697
get id() {
97-
return this.#id;
98+
return this._id;
9899
}
99100

100101
get endpoint() {
101-
return this.#endpoint;
102+
return this._endpoint;
102103
}
103104

104105
get isPartOfSaga() {
105106
return this.partOfSaga != null;
106107
}
107108

108109
get handledAt() {
109-
return this.processedAt ?? this.#processedAtGuess;
110+
return this.processedAt ?? this._processedAtGuess;
110111
}
111112

112113
get selectedMessage() {
113114
return this.route?.fromRoutedMessage?.selectedMessage;
114115
}
115116

116117
get outMessages() {
117-
return [...this.#outMessages];
118+
return [...this._outMessages];
119+
}
120+
121+
get direction() {
122+
return this.outMessages[0]?.direction === Direction.Left ? Direction.Right : Direction.Left;
118123
}
119124

120125
updateProcessedAt(timeSent: Date) {
121-
if (!this.#processedAtGuess || this.#processedAtGuess.getTime() > timeSent.getTime()) this.#processedAtGuess = timeSent;
126+
if (!this._processedAtGuess || this._processedAtGuess.getTime() > timeSent.getTime()) this._processedAtGuess = timeSent;
122127
}
123128

124129
addOutMessage(routedMessage: RoutedMessage) {
125-
this.#outMessages = [routedMessage, ...this.#outMessages].sort((a, b) => (a.sentTime?.getTime() ?? 0) - (b.sentTime?.getTime() ?? 0));
130+
this._outMessages = [routedMessage, ...this._outMessages].sort((a, b) => (a.sentTime?.getTime() ?? 0) - (b.sentTime?.getTime() ?? 0));
126131
}
127132
}

0 commit comments

Comments
 (0)