Skip to content

Commit

Permalink
fix(supernova-ui): fix preselected support group (#371)
Browse files Browse the repository at this point in the history
  • Loading branch information
andypf committed Sep 4, 2024
1 parent 4f98850 commit cda336a
Show file tree
Hide file tree
Showing 10 changed files with 76 additions and 60 deletions.
19 changes: 11 additions & 8 deletions alerts/ui/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8"/>
<link rel="icon" href="favicon.ico" sizes="any"/>
<meta charset="UTF-8" />
<link rel="icon" href="favicon.ico" sizes="any" />
<title>Supernova Dev</title>
<style>
html {
Expand All @@ -28,25 +28,28 @@
</style>
<script>
// automatically reload on build changes
new EventSource("/esbuild").addEventListener("change", () => location.reload())
new EventSource("/esbuild").addEventListener("change", () =>
location.reload()
)
</script>
</head>
<body>
<script
<!-- <script
defer
src="https://assets.juno.global.cloud.sap/apps/widget-loader@latest/build/app.js"
data-name="auth"
data-version="latest"
data-props-initial-login="true"
data-props-mock='{"groups":["organization:test-org", "team:containers","support-group:containers","role:ccloud:admin"]}'
></script>
data-props-debug="true"
></script> -->
<script type="module">
// appProps are generated in development env and added to the build
import allProps from "./build/appProps.js"
import ("./build/index.js").then((app) => {
app.mount(document.getElementById("root"), {props: allProps.appProps})
import("./build/index.js").then((app) => {
app.mount(document.getElementById("root"), { props: allProps.appProps })
})
</script>
<div id="root"></div>
</body>
</html>
</html>
1 change: 0 additions & 1 deletion alerts/ui/src/AppContent.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ const AppContent = () => {
const { addMessage } = useActions()

// alerts
const alertsError = useAlertsError()
const isAlertsLoading = useAlertsIsLoading()
const totalCounts = useAlertsTotalCounts()
const isAlertsUpdating = useAlertsIsUpdating()
Expand Down
2 changes: 1 addition & 1 deletion alerts/ui/src/api/apiService.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ function ApiService(initialConfig) {
)

if (config?.debug)
console.log(
console.debug(
`ApiService::${config.serviceName || ""}: new config: `,
config
)
Expand Down
1 change: 0 additions & 1 deletion alerts/ui/src/components/AsyncWorker.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
* SPDX-License-Identifier: Apache-2.0
*/

import React from "react"
import useCommunication from "../hooks/useCommunication"
import useAlertmanagerAPI from "../hooks/useAlertmanagerAPI"
import useUrlState from "../hooks/useUrlState"
Expand Down
2 changes: 1 addition & 1 deletion alerts/ui/src/components/alerts/AlertsList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const AlertsList = () => {
if (alertsIsLoading || isAddingItems) return
if (observer.current) observer.current.disconnect()
observer.current = new IntersectionObserver((entries) => {
console.log("IntersectionObserver: callback")
console.debug("IntersectionObserver: callback")
if (entries[0].isIntersecting && visibleAmount <= alertsSorted.length) {
// setVisibleAmount((prev) => prev + 10)
clearTimeout(timeoutRef.current)
Expand Down
2 changes: 1 addition & 1 deletion alerts/ui/src/components/silences/SilenceScheduled.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ const SilenceScheduled = (props) => {
.then((data) => {
setSuccess(data)

console.log("data", data)
console.debug("data", data)

let newSilence = {
...silence,
Expand Down
2 changes: 1 addition & 1 deletion alerts/ui/src/helpers.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const parseError = (error) => {

// check if the error is a object containing message
if (typeof error === "object") {
console.log("Error parsing error message::object")
console.debug("Error parsing error message::object")
if (error?.message) {
errMsg = parseMessage(error?.message)
}
Expand Down
28 changes: 14 additions & 14 deletions alerts/ui/src/hooks/useAlertmanagerAPI.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,26 +59,26 @@ const useAlertmanagerAPI = (apiEndpoint) => {

alertsWorker.then(({ createWorker, stopWorker }) => {
const worker = createWorker()
console.log("Worker::Setting up ALERTS worker", worker)
console.debug("Worker::Setting up ALERTS worker", worker)

// receive messages from worker
worker.onmessage = (e) => {
const action = e.data.action
switch (action) {
case "ALERTS_UPDATE":
console.log("Worker::ALERT_UPDATE::", e.data)
console.debug("Worker::ALERT_UPDATE::", e.data)
setAlertsData({ items: e.data.alerts, counts: e.data.counts })
break
case "ALERTS_FETCH_START":
console.log("Worker::ALERTS_FETCH_START::")
console.debug("Worker::ALERTS_FETCH_START::")
setAlertsIsUpdating(true)
break
case "ALERTS_FETCH_END":
console.log("Worker::ALERTS_FETCH_END::")
console.debug("Worker::ALERTS_FETCH_END::")
setAlertsIsUpdating(false)
break
case "ALERTS_FETCH_ERROR":
console.log("Worker::ALERTS_FETCH_ERROR::", e.data.error)
console.debug("Worker::ALERTS_FETCH_ERROR::", e.data.error)
setAlertsIsUpdating(false)
// error comes as object string and have to be parsed
setAlertsError(e.data.error)
Expand All @@ -87,37 +87,37 @@ const useAlertmanagerAPI = (apiEndpoint) => {
}

cleanupAlertsWorker = () => {
console.log("Worker::Terminating Alerts Worker")
console.debug("Worker::Terminating Alerts Worker")
return stopWorker()
}
})

silencesWorker.then(({ createWorker, stopWorker }) => {
const worker = createWorker()
console.log("Worker::Setting up SILENCES worker")
console.debug("Worker::Setting up SILENCES worker")

// receive messages from worker
worker.onmessage = (e) => {
const action = e.data.action
switch (action) {
case "SILENCES_UPDATE":
console.log("Worker::SILENCES_UPDATE::", e.data)
console.debug("Worker::SILENCES_UPDATE::", e.data)
setSilences({
items: e.data?.silences,
itemsHash: e.data?.silencesHash,
itemsByState: e.data?.silencesBySate,
})
break
case "SILENCES_FETCH_START":
console.log("Worker::SILENCES_FETCH_START::")
console.debug("Worker::SILENCES_FETCH_START::")
setSilencesIsUpdating(true)
break
case "SILENCES_FETCH_END":
console.log("Worker::SILENCES_FETCH_END::")
console.debug("Worker::SILENCES_FETCH_END::")
setSilencesIsUpdating(false)
break
case "SILENCES_FETCH_ERROR":
console.log("Worker::SILENCES_FETCH_ERROR::", e.data.error)
console.debug("Worker::SILENCES_FETCH_ERROR::", e.data.error)
setSilencesIsUpdating(false)
// error comes as object string and have to be parsed
setSilencesError(e.data.error)
Expand All @@ -126,7 +126,7 @@ const useAlertmanagerAPI = (apiEndpoint) => {
}

cleanupSilencesWorker = () => {
console.log("Worker::Terminating Silences Worker")
console.debug("Worker::Terminating Silences Worker")
return stopWorker()
}
})
Expand Down Expand Up @@ -190,11 +190,11 @@ const useAlertmanagerAPI = (apiEndpoint) => {
const localItems = useSilencesLocalItems()
useEffect(() => {
if (!localItems) return
// if we have no silences locally we don't need to refetch them otherwise
// if we have no silences locally we don't need to refetch them otherwise
// we will end up in an infinite loop
if (Object.keys(localItems).length <= 0) return

// Use setTimeout to delay the worker call delayed by 10s
// Use setTimeout to delay the worker call delayed by 10s
setTimeout(() => {
silencesWorker.then(({ createWorker, stopWorker }) => {
const worker = createWorker()
Expand Down
57 changes: 43 additions & 14 deletions alerts/ui/src/hooks/useCommunication.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,55 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { useEffect } from "react"
import { useEffect, useCallback } from "react"
import { get, watch } from "@cloudoperators/juno-communicator"
import { useUserActivityActions, useAuthActions } from "./useAppStore"
import {
useUserActivityActions,
useAuthActions,
useActiveFilters,
useFilterActions,
useFilterLabels,
} from "./useAppStore"

const useCommunication = () => {
console.log("[supernova] useCommunication setup")
console.debug("[supernova] useCommunication setup")
const { setIsActive } = useUserActivityActions()
const { setData: authSetData, setAppLoaded: authSetAppLoaded } =
useAuthActions()
const { setData: authSetData } = useAuthActions()
const activeFilters = useActiveFilters()
const { setActiveFilters } = useFilterActions()
const filterLabels = useFilterLabels()

const setAuthData = useCallback(
(data) => {
if (!data) return

// set the auth data
authSetData(data)

// The following code exists of historical reasons and should be refactored
// We preset the support group filter based on auth data. This should be done
// with predefined filters prop

// check if support group filter is set in activeFilters
// activeFilters example: {support_group: Array(1)}
if (
!activeFilters?.support_group &&
data?.auth?.parsed?.supportGroups &&
filterLabels?.includes("support_group")
) {
setActiveFilters({ support_group: data.auth.parsed.supportGroups })
}
},
[authSetData, filterLabels]
)

useEffect(() => {
// watch for user activity updates messages
// with the watcher we get the user activity object when this app is loaded before the Auth app
const unwatch = watch(
"USER_ACTIVITY_UPDATE_DATA",
(data) => {
console.log("got message USER_ACTIVITY_UPDATE_DATA: ", data)
console.debug("got message USER_ACTIVITY_UPDATE_DATA: ", data)
setIsActive(data?.isActive)
},
{ debug: true }
Expand All @@ -28,19 +60,16 @@ const useCommunication = () => {
}, [setIsActive])

useEffect(() => {
if (!authSetData || !authSetAppLoaded) return

get("AUTH_APP_LOADED", authSetAppLoaded)
const unwatchLoaded = watch("AUTH_APP_LOADED", authSetAppLoaded)
authSetData({ auth: { parsed: { fullName: "anonymous" } } })
if (!setAuthData) return

get("AUTH_GET_DATA", authSetData)
const unwatchUpdate = watch("AUTH_UPDATE_DATA", authSetData)
get("AUTH_GET_DATA", setAuthData)
const unwatchUpdate = watch("AUTH_UPDATE_DATA", setAuthData)

return () => {
if (unwatchLoaded) unwatchLoaded()
if (unwatchUpdate) unwatchUpdate()
}
}, [authSetData, authSetAppLoaded])
}, [setAuthData])
}

export default useCommunication
22 changes: 4 additions & 18 deletions alerts/ui/src/hooks/useUrlState.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { useLayoutEffect, useEffect, useState } from "react"
import { registerConsumer } from "@cloudoperators/juno-url-state-provider-v1"
import {
useAuthLoggedIn,
useAuthData,
useFilterLabels,
useFilterActions,
useActiveFilters,
Expand Down Expand Up @@ -38,7 +37,6 @@ const SILENCE_DETAIL = "sd"
const useUrlState = () => {
const [isURLRead, setIsURLRead] = useState(false)
const loggedIn = useAuthLoggedIn()
const authData = useAuthData()
const {
setActiveFilters,
setPausedFilters,
Expand All @@ -63,9 +61,9 @@ const useUrlState = () => {
// useLayoutEffect so this is done before rendering anything
useLayoutEffect(() => {
// do not read the url state until the user is logged in and do it just once
if (!loggedIn || isURLRead) return
if (isURLRead) return

console.log(
console.debug(
"SUPERNOVA:: setting up state from url with state::",
urlStateManager.currentState()
)
Expand All @@ -77,18 +75,6 @@ const useUrlState = () => {
// check if there are active filters in the url state
if (activeFiltersFromURL && Object.keys(activeFiltersFromURL).length > 0) {
setActiveFilters(activeFiltersFromURL)
} else {
// otherwise set the support group filter
// we just add this default filter when no other filters are set via URL
const label = "support_group"
if (
authData?.parsed?.supportGroups?.length > 0 &&
filterLabels?.length > 0 &&
filterLabels.includes(label)
) {
// this will also trigger a filterItems() call from the store self
setActiveFilters({ [label]: authData.parsed.supportGroups })
}
}

// get paused filters from url state and set it in store
Expand Down Expand Up @@ -148,12 +134,12 @@ const useUrlState = () => {
}

setIsURLRead(true)
}, [loggedIn, isURLRead, authData, filterLabels])
}, [isURLRead, filterLabels])

// sync URL with the desired states
useEffect(() => {
// do not synchronize the states until the url state is read and user logged in
if (!loggedIn || !isURLRead) return
if (!isURLRead) return

// encode searchTerm before pushing it to the URL to avoid missinterpretation of special characters
const encodedSearchTerm = btoa(searchTerm)
Expand Down

0 comments on commit cda336a

Please sign in to comment.