Skip to content

Commit 435bc3d

Browse files
authored
Merge pull request #2892 from Particular/john/refresh-bug
Consolidate platform capability status checks into PlatformCapabilitiesStore
2 parents a7c8f8f + bf27b26 commit 435bc3d

9 files changed

Lines changed: 87 additions & 66 deletions

File tree

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import Message, { MessageStatus } from "@/resources/Message";
2+
import type { SortInfo } from "@/components/SortInfo";
3+
import type { DateRange } from "@/types/date";
4+
import serviceControlClient from "@/components/serviceControlClient";
5+
6+
export interface AuditQuery {
7+
endpointName?: string;
8+
dateRange?: DateRange;
9+
messageFilterString?: string;
10+
itemsPerPage?: number;
11+
sort?: SortInfo;
12+
}
13+
14+
class AuditClient {
15+
public async getMessages(query: AuditQuery): Promise<[Response, Message[]]> {
16+
const [fromDate, toDate] = query.dateRange ?? [];
17+
const from = fromDate?.toISOString() ?? "";
18+
const to = toDate?.toISOString() ?? "";
19+
return await serviceControlClient.fetchTypedFromServiceControl<Message[]>(
20+
`messages2/?endpoint_name=${query.endpointName ?? ""}&from=${from}&to=${to}&q=${query.messageFilterString ?? ""}&page_size=${query.itemsPerPage ?? 100}&sort=${query.sort?.property ?? "time_sent"}&direction=${query.sort?.isAscending ? "asc" : "desc"}`
21+
);
22+
}
23+
24+
public async hasSuccessfulMessages(): Promise<boolean> {
25+
// Fetch the latest 10 messages and check if any are successful
26+
// ideally we would want to filter successful messages server-side, but the API doesn't currently support that
27+
const [, data] = await serviceControlClient.fetchTypedFromServiceControl<Message[]>(`messages2/?page_size=10&sort=time_sent&direction=desc`);
28+
return data?.some((msg) => msg.status === MessageStatus.Successful) ?? false;
29+
}
30+
}
31+
32+
export default new AuditClient();

src/Frontend/src/components/platformcapabilities/capabilities/AuditingCapability.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import useIsAllMessagesSupported, { minimumSCVersionForAllMessages } from "@/com
55
import { storeToRefs } from "pinia";
66
import { type CapabilityComposable, type CapabilityStatusToStringMap, useCapabilityBase } from "./BaseCapability";
77
import useRemoteInstancesAutoRefresh from "@/composables/useRemoteInstancesAutoRefresh";
8-
import useAuditStoreAutoRefresh from "@/composables/useAuditStoreAutoRefresh";
8+
import usePlatformCapabilitiesRefresh from "@/composables/usePlatformCapabilitiesRefresh";
99
import { RemoteInstanceStatus, RemoteInstanceType, type RemoteInstance } from "@/resources/RemoteInstance";
1010
import routeLinks from "@/router/routeLinks";
1111

@@ -110,8 +110,8 @@ export function useAuditingCapability(): CapabilityComposable {
110110

111111
// This gives us the hasSuccessfulMessages flag which indicates if any successful messages exist.
112112
// Uses auto-refresh (minimal) to periodically check for at least 1 successful message (every 5 seconds)
113-
const { store: auditStore } = useAuditStoreAutoRefresh();
114-
const { hasSuccessfulMessages } = storeToRefs(auditStore);
113+
const { store: platformCapabilitiesStore } = usePlatformCapabilitiesRefresh();
114+
const { hasSuccessfulMessages } = storeToRefs(platformCapabilitiesStore);
115115

116116
// This tells us if the "All Messages" feature is supported by checking the SC version
117117
const isAllMessagesSupported = useIsAllMessagesSupported();

src/Frontend/src/components/platformcapabilities/capabilities/MonitoringCapability.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@ import { StatusIndicator } from "@/components/platformcapabilities/types";
33
import { CapabilityStatus } from "@/components/platformcapabilities/constants";
44
import { storeToRefs } from "pinia";
55
import { useConnectionsAndStatsStore } from "@/stores/ConnectionsAndStatsStore";
6-
import useMonitoringStoreAutoRefresh from "@/composables/useMonitoringStoreAutoRefresh";
76
import { type CapabilityComposable, type CapabilityStatusToStringMap, useCapabilityBase } from "./BaseCapability";
87
import monitoringClient from "@/components/monitoring/monitoringClient";
98
import { useEnvironmentAndVersionsStore } from "@/stores/EnvironmentAndVersionsStore";
9+
import usePlatformCapabilitiesRefresh from "@/composables/usePlatformCapabilitiesRefresh";
1010
import routeLinks from "@/router/routeLinks";
1111

1212
const MonitoringDescriptions: CapabilityStatusToStringMap = {
@@ -46,8 +46,8 @@ export function useMonitoringCapability(): CapabilityComposable {
4646

4747
// this tells us if there are any endpoints sending data
4848
// Uses auto-refresh to periodically check for monitored endpoints (every 5 seconds)
49-
const { store: monitoringStore } = useMonitoringStoreAutoRefresh();
50-
const { hasMonitoredEndpoints } = storeToRefs(monitoringStore);
49+
const { store: platformCapabilitiesStore } = usePlatformCapabilitiesRefresh();
50+
const { hasMonitoredEndpoints } = storeToRefs(platformCapabilitiesStore);
5151

5252
// this tells us the connection state to the monitoring instance
5353
// this is auto refreshed in the ConnectionsAndStatsStore (every 5 seconds)

src/Frontend/src/composables/useAuditStoreAutoRefresh.ts

Lines changed: 0 additions & 10 deletions
This file was deleted.

src/Frontend/src/composables/useMonitoringStoreAutoRefresh.ts

Lines changed: 0 additions & 10 deletions
This file was deleted.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { usePlatformCapabilitiesStore } from "@/stores/PlatformCapabilitiesStore";
2+
import { useStoreAutoRefresh } from "./useAutoRefresh";
3+
4+
export default useStoreAutoRefresh("platformCapabilities", usePlatformCapabilitiesStore, 5000).autoRefresh;

src/Frontend/src/stores/AuditStore.ts

Lines changed: 9 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import { acceptHMRUpdate, defineStore } from "pinia";
22
import { ref } from "vue";
33
import type { SortInfo } from "@/components/SortInfo";
4-
import Message, { MessageStatus } from "@/resources/Message";
4+
import Message from "@/resources/Message";
55
import { EndpointsView } from "@/resources/EndpointView";
66
import type { DateRange } from "@/types/date";
77
import serviceControlClient from "@/components/serviceControlClient";
8+
import auditClient from "@/components/audit/auditClient";
89

910
export enum FieldNames {
1011
TimeSent = "time_sent",
@@ -27,19 +28,6 @@ export const useAuditStore = defineStore("AuditStore", () => {
2728
const selectedEndpointName = ref<string>("");
2829
const endpoints = ref<EndpointsView[]>([]);
2930

30-
const hasSuccessfulMessages = ref(false);
31-
32-
async function checkForSuccessfulMessages() {
33-
try {
34-
// Fetch the latest 10 messages and check if any are successful
35-
// ideally we would want to filter successful messages server-side, but the API doesn't currently support that
36-
const [, data] = await serviceControlClient.fetchTypedFromServiceControl<Message[]>(`messages2/?page_size=10&sort=time_sent&direction=desc`);
37-
hasSuccessfulMessages.value = data?.some((msg) => msg.status === MessageStatus.Successful) ?? false;
38-
} catch {
39-
hasSuccessfulMessages.value = false;
40-
}
41-
}
42-
4331
async function loadEndpoints() {
4432
try {
4533
const [, data] = await serviceControlClient.fetchTypedFromServiceControl<EndpointsView[]>(`endpoints`);
@@ -52,12 +40,13 @@ export const useAuditStore = defineStore("AuditStore", () => {
5240

5341
async function refresh() {
5442
try {
55-
const [fromDate, toDate] = dateRange.value;
56-
const from = fromDate?.toISOString() ?? "";
57-
const to = toDate?.toISOString() ?? "";
58-
const [response, data] = await serviceControlClient.fetchTypedFromServiceControl<Message[]>(
59-
`messages2/?endpoint_name=${selectedEndpointName.value}&from=${from}&to=${to}&q=${messageFilterString.value}&page_size=${itemsPerPage.value}&sort=${sortByInstances.value.property}&direction=${sortByInstances.value.isAscending ? "asc" : "desc"}`
60-
);
43+
const [response, data] = await auditClient.getMessages({
44+
endpointName: selectedEndpointName.value,
45+
dateRange: dateRange.value,
46+
messageFilterString: messageFilterString.value,
47+
itemsPerPage: itemsPerPage.value,
48+
sort: sortByInstances.value,
49+
});
6150
totalCount.value = parseInt(response.headers.get("total-count") ?? "0");
6251
messages.value = data;
6352
} catch (e) {
@@ -69,10 +58,8 @@ export const useAuditStore = defineStore("AuditStore", () => {
6958
return {
7059
refresh,
7160
loadEndpoints,
72-
checkForSuccessfulMessages,
7361
sortBy: sortByInstances,
7462
messages,
75-
hasSuccessfulMessages,
7663
messageFilterString,
7764
selectedEndpointName,
7865
itemsPerPage,

src/Frontend/src/stores/MonitoringStore.ts

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ export const useMonitoringStore = defineStore("MonitoringStore", () => {
2929

3030
const endpointList = ref<Endpoint[]>([]);
3131
const filterString = ref("");
32-
const hasMonitoredEndpoints = ref(false);
3332
const endpointListCount = computed<number>(() => endpointList.value.length);
3433
const endpointListIsEmpty = computed<boolean>(() => endpointListCount.value === 0);
3534
const endpointListIsGrouped = computed<boolean>(() => grouping.value.selectedGrouping !== 0);
@@ -70,20 +69,6 @@ export const useMonitoringStore = defineStore("MonitoringStore", () => {
7069
}
7170
}
7271

73-
async function checkForMonitoredEndpoints() {
74-
try {
75-
if (!monitoringClient.isMonitoringEnabled || connectionStore.monitoringConnectionState.unableToConnect) {
76-
hasMonitoredEndpoints.value = false;
77-
return;
78-
}
79-
// Minimal query: just need to check if any endpoints exist
80-
const data = await monitoringClient.getMonitoredEndpoints(1);
81-
hasMonitoredEndpoints.value = (data?.length ?? 0) > 0;
82-
} catch {
83-
hasMonitoredEndpoints.value = false;
84-
}
85-
}
86-
8772
async function getAllMonitoredEndpoints() {
8873
let endpoints: Endpoint[] = [];
8974
if (monitoringClient.isMonitoringEnabled) {
@@ -217,7 +202,6 @@ export const useMonitoringStore = defineStore("MonitoringStore", () => {
217202
grouping,
218203
filterString,
219204
sortBy,
220-
hasMonitoredEndpoints,
221205

222206
//getters
223207
endpointListIsEmpty,
@@ -228,7 +212,6 @@ export const useMonitoringStore = defineStore("MonitoringStore", () => {
228212
updateSelectedGrouping,
229213
updateEndpointList,
230214
updateFilterString,
231-
checkForMonitoredEndpoints,
232215
};
233216
});
234217

src/Frontend/src/stores/PlatformCapabilitiesStore.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { acceptHMRUpdate, defineStore } from "pinia";
22
import { ref, watch } from "vue";
33
import serviceControlClient from "@/components/serviceControlClient";
4+
import auditClient from "@/components/audit/auditClient";
5+
import monitoringClient from "@/components/monitoring/monitoringClient";
6+
import useConnectionsAndStatsAutoRefresh from "@/composables/useConnectionsAndStatsAutoRefresh";
47

58
const STORAGE_KEY_PREFIX = "servicepulse-capabilities-vis";
69

@@ -16,7 +19,7 @@ function getStorageKey(): string {
1619
return STORAGE_KEY_PREFIX;
1720
}
1821

19-
interface PlatformCapabilitiesVisibility {
22+
export interface PlatformCapabilitiesVisibility {
2023
showSection: boolean;
2124
showAuditingCard: boolean;
2225
showMonitoringCard: boolean;
@@ -52,7 +55,36 @@ function saveVisibility(visibility: PlatformCapabilitiesVisibility): void {
5255
}
5356

5457
export const usePlatformCapabilitiesStore = defineStore("PlatformCapabilitiesStore", () => {
58+
const { store: connectionStore } = useConnectionsAndStatsAutoRefresh();
5559
const visibility = ref<PlatformCapabilitiesVisibility>(loadVisibility());
60+
const hasSuccessfulMessages = ref(false);
61+
const hasMonitoredEndpoints = ref(false);
62+
63+
async function checkForSuccessfulMessages() {
64+
try {
65+
hasSuccessfulMessages.value = await auditClient.hasSuccessfulMessages();
66+
} catch {
67+
hasSuccessfulMessages.value = false;
68+
}
69+
}
70+
71+
async function checkForMonitoredEndpoints() {
72+
try {
73+
if (!monitoringClient.isMonitoringEnabled || connectionStore.monitoringConnectionState.unableToConnect) {
74+
hasMonitoredEndpoints.value = false;
75+
return;
76+
}
77+
// Minimal query: just need to check if any endpoints exist
78+
const data = await monitoringClient.getMonitoredEndpoints(1);
79+
hasMonitoredEndpoints.value = (data?.length ?? 0) > 0;
80+
} catch {
81+
hasMonitoredEndpoints.value = false;
82+
}
83+
}
84+
85+
async function refresh() {
86+
await Promise.all([checkForSuccessfulMessages(), checkForMonitoredEndpoints()]);
87+
}
5688

5789
// Watch for changes and persist to localStorage
5890
watch(
@@ -93,6 +125,9 @@ export const usePlatformCapabilitiesStore = defineStore("PlatformCapabilitiesSto
93125
toggleMonitoringCard,
94126
toggleErrorCard,
95127
showAll,
128+
hasSuccessfulMessages,
129+
hasMonitoredEndpoints,
130+
refresh,
96131
};
97132
});
98133

0 commit comments

Comments
 (0)