Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make Endpoint list default direction for name sorting ascending #1763

Merged
merged 1 commit into from
Mar 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions src/ServicePulse.Host/vue/src/components/SortInfo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export interface SortInfo {
property: string;
isAscending: boolean;
}
29 changes: 13 additions & 16 deletions src/ServicePulse.Host/vue/src/components/SortableColumn.vue
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
<script setup lang="ts">
import { ref, computed } from "vue";
import { computed } from "vue";
import type { SortInfo } from "./SortInfo";

const props = defineProps<{
sortBy: string;
}>();
const props = withDefaults(
defineProps<{
sortBy: string;
defaultAscending: boolean;
}>(),
{ defaultAscending: false }
);

const activeColumn = defineModel({
type: String,
required: true,
});
const activeColumn = defineModel<SortInfo>({ required: true });

const emit = defineEmits(["isAscending"]);

const isAscending = ref(false);
const isActive = computed(() => activeColumn.value === props.sortBy);
const sortIcon = computed(() => (isAscending.value ? "sort-up" : "sort-down"));
const isActive = computed(() => activeColumn.value?.property === props.sortBy);
const sortIcon = computed(() => (activeColumn.value.isAscending ? "sort-up" : "sort-down"));

function toggleSort() {
activeColumn.value = props.sortBy;
isAscending.value = isActive.value ? !isAscending.value : false;
emit("isAscending", isAscending.value);
activeColumn.value = { property: props.sortBy, isAscending: isActive.value ? !activeColumn.value.isAscending : props.defaultAscending };
}
</script>
<template>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
<script setup lang="ts">
import { ref } from "vue";
import SortableColumn from "../../components/SortableColumn.vue";
import EndpointListRow from "./EndpointListRow.vue";
import { useMonitoringStore } from "@/stores/MonitoringStore";
import { storeToRefs } from "pinia";

const monitoringStore = useMonitoringStore();
const activeColumn = ref("name");
const { sortBy: activeColumn } = storeToRefs(monitoringStore);

const sortByColumn = Object.freeze({
ENDPOINTNAME: "name",
Expand All @@ -15,64 +15,39 @@ const sortByColumn = Object.freeze({
PROCESSINGTIME: "processingTime",
CRITICALTIME: "criticalTime",
});

function updateSorting(isAscending: boolean) {
monitoringStore.updateSort(activeColumn.value, isAscending);
}
</script>

<template>
<section>
<!--Table headings-->
<div class="table-head-row">
<div class="table-first-col">
<SortableColumn :sort-by="sortByColumn.ENDPOINTNAME" v-model="activeColumn" @isAscending="updateSorting">Endpoint name</SortableColumn>
<SortableColumn :sort-by="sortByColumn.ENDPOINTNAME" v-model="activeColumn" :default-ascending="true">Endpoint name</SortableColumn>
</div>
<div class="table-col">
<SortableColumn
:sort-by="monitoringStore.endpointListIsGrouped ? '' : sortByColumn.QUEUELENGTH"
v-model="activeColumn"
@isAscending="updateSorting"
v-tooltip
title="Queue length: The number of messages waiting to be processed in the input queue(s) of the endpoint."
<SortableColumn :sort-by="monitoringStore.endpointListIsGrouped ? '' : sortByColumn.QUEUELENGTH" v-model="activeColumn" v-tooltip title="Queue length: The number of messages waiting to be processed in the input queue(s) of the endpoint."
>Queue Length<template #unit>(MSGS)</template>
</SortableColumn>
</div>
<div class="table-col">
<SortableColumn
:sort-by="monitoringStore.endpointListIsGrouped ? '' : sortByColumn.THROUGHPUT"
v-model="activeColumn"
@isAscending="updateSorting"
v-tooltip
title="Throughput: The number of messages per second successfully processed by a receiving endpoint."
<SortableColumn :sort-by="monitoringStore.endpointListIsGrouped ? '' : sortByColumn.THROUGHPUT" v-model="activeColumn" v-tooltip title="Throughput: The number of messages per second successfully processed by a receiving endpoint."
>Throughput<template #unit>(msgs/s)</template>
</SortableColumn>
</div>
<div class="table-col">
<SortableColumn
:sort-by="monitoringStore.endpointListIsGrouped ? '' : sortByColumn.SCHEDULEDRETRIES"
v-model="activeColumn"
@isAscending="updateSorting"
v-tooltip
title="Scheduled retries: The number of messages per second scheduled for retries (immediate or delayed)."
<SortableColumn :sort-by="monitoringStore.endpointListIsGrouped ? '' : sortByColumn.SCHEDULEDRETRIES" v-model="activeColumn" v-tooltip title="Scheduled retries: The number of messages per second scheduled for retries (immediate or delayed)."
>Scheduled retries <template #unit>(msgs/s)</template>
</SortableColumn>
</div>
<div class="table-col">
<SortableColumn
:sort-by="monitoringStore.endpointListIsGrouped ? '' : sortByColumn.PROCESSINGTIME"
v-model="activeColumn"
@isAscending="updateSorting"
v-tooltip
title="Processing time: The time taken for a receiving endpoint to successfully process a message."
<SortableColumn :sort-by="monitoringStore.endpointListIsGrouped ? '' : sortByColumn.PROCESSINGTIME" v-model="activeColumn" v-tooltip title="Processing time: The time taken for a receiving endpoint to successfully process a message."
>Processing Time <template #unit>(t)</template>
</SortableColumn>
</div>
<div class="table-col">
<SortableColumn
:sort-by="monitoringStore.endpointListIsGrouped ? '' : sortByColumn.CRITICALTIME"
v-model="activeColumn"
@isAscending="updateSorting"
v-tooltip
title="Critical time: The elapsed time from when a message was sent, until it was successfully processed by a receiving endpoint."
>Critical Time <template #unit>(t)</template>
Expand Down
38 changes: 17 additions & 21 deletions src/ServicePulse.Host/vue/src/stores/MonitoringStore.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { defineStore, acceptHMRUpdate } from "pinia";
import { computed, ref } from "vue";
import { computed, ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
import * as MonitoringEndpoints from "../composables/serviceMonitoringEndpoints";
import { useMonitoringHistoryPeriodStore } from "./MonitoringHistoryPeriodStore";
import type { EndpointGroup, Endpoint, GroupedEndpoint } from "@/resources/Endpoint";
import type { SortInfo } from "@/components/SortInfo";

export const useMonitoringStore = defineStore("MonitoringStore", () => {
const historyPeriodStore = useMonitoringHistoryPeriodStore();
Expand All @@ -18,18 +19,23 @@ export const useMonitoringStore = defineStore("MonitoringStore", () => {
selectedGrouping: 0,
});

const sortBy = ref<SortInfo>({
property: "name",
isAscending: true,
});

const endpointList = ref<Endpoint[]>([]);
const disconnectedEndpointCount = ref(0);
const negativeCriticalTimeIsPresent = ref(false);
const filterString = ref("");
const sortBy = ref("name");
const isSortAscending = ref(false);
const isInitialized = ref(false);
const endpointListCount = computed<number>(() => endpointList.value.length);
const endpointListIsEmpty = computed<boolean>(() => endpointListCount.value === 0);
const endpointListIsGrouped = computed<boolean>(() => grouping.value.selectedGrouping !== 0);
const getEndpointList = computed<Endpoint[]>(() => (filterString.value !== "" ? MonitoringEndpoints.useFilterAllMonitoredEndpointsByName(endpointList.value, filterString.value) : endpointList.value));

watch(sortBy, () => updateEndpointList(), { deep: true });

//STORE ACTIONS
async function initializeStore() {
await updateFilterString();
Expand Down Expand Up @@ -72,23 +78,16 @@ export const useMonitoringStore = defineStore("MonitoringStore", () => {
sortGroupedEndpointList();
}

async function updateSort(newSortBy = "name", newIsSortAscending = false) {
sortBy.value = newSortBy;
isSortAscending.value = newIsSortAscending;
await updateEndpointList();
}

function sortEndpointList() {
const sortByProperty = sortBy.value;
const comparator = (() => {
if (sortByProperty === "name") {
return (a: Endpoint, b: Endpoint) => (isSortAscending.value ? a.name.localeCompare(b.name) : b.name.localeCompare(a.name));
if (sortBy.value.property === "name") {
return (a: Endpoint, b: Endpoint) => (sortBy.value.isAscending ? a.name.localeCompare(b.name) : b.name.localeCompare(a.name));
} else {
return (a: Endpoint, b: Endpoint) => {
const propertyA = a.metrics[sortByProperty].average;
const propertyB = b.metrics[sortByProperty].average;
const propertyA = a.metrics[sortBy.value.property].average;
const propertyB = b.metrics[sortBy.value.property].average;

return isSortAscending.value ? propertyA - propertyB : propertyB - propertyA;
return sortBy.value.isAscending ? propertyA - propertyB : propertyB - propertyA;
};
}
})();
Expand All @@ -97,13 +96,12 @@ export const useMonitoringStore = defineStore("MonitoringStore", () => {
}

function sortGroupedEndpointList() {
const sortByProperty = sortBy.value;
let comparator;
const endpointShortNameComparator = (a: GroupedEndpoint, b: GroupedEndpoint) => {
return isSortAscending.value ? a.shortName.localeCompare(b.shortName) : b.shortName.localeCompare(a.shortName);
return sortBy.value.isAscending ? a.shortName.localeCompare(b.shortName) : b.shortName.localeCompare(a.shortName);
};

if (sortByProperty === "name") {
if (sortBy.value.property === "name") {
comparator = (a: EndpointGroup, b: EndpointGroup) => {
const groupNameA = a.group;
const groupNameB = b.group;
Expand All @@ -114,7 +112,7 @@ export const useMonitoringStore = defineStore("MonitoringStore", () => {
endpointListGroupA.sort(endpointShortNameComparator);
endpointListGroupB.sort(endpointShortNameComparator);

return isSortAscending.value ? groupNameA.localeCompare(groupNameB) : groupNameB.localeCompare(groupNameA);
return sortBy.value.isAscending ? groupNameA.localeCompare(groupNameB) : groupNameB.localeCompare(groupNameA);
};
}
// TODO: Determine how sorting should be handled for columns other than endpoint name
Expand All @@ -134,7 +132,6 @@ export const useMonitoringStore = defineStore("MonitoringStore", () => {
negativeCriticalTimeIsPresent,
filterString,
sortBy,
isSortAscending,
isInitialized,

//getters
Expand All @@ -146,7 +143,6 @@ export const useMonitoringStore = defineStore("MonitoringStore", () => {
//actions
initializeStore,
updateSelectedGrouping,
updateSort,
updateEndpointList,
updateFilterString,
};
Expand Down