diff --git a/heureka/ui/package-lock.json b/heureka/ui/package-lock.json
index 84a06667..005729cf 100644
--- a/heureka/ui/package-lock.json
+++ b/heureka/ui/package-lock.json
@@ -8,6 +8,15 @@
"name": "heureka",
"version": "2.3.0",
"license": "Apache-2.0",
+<<<<<<< HEAD
+=======
+ "dependencies": {
+ "@cloudoperators/juno-communicator": "^2.2.11",
+ "@cloudoperators/juno-messages-provider": "^0.1.17",
+ "@cloudoperators/juno-ui-components": "^2.15.4",
+ "@cloudoperators/juno-url-state-provider-v1": "^1.3.2"
+ },
+>>>>>>> 01cf4521 (feat(heureka) : Add components view (#263))
"devDependencies": {
"@babel/core": "^7.20.2",
"@babel/preset-env": "^7.20.2",
@@ -29,9 +38,13 @@
"immer": "^10.0.0",
"jest": "^29.3.1",
"jest-environment-jsdom": "^29.3.1",
+<<<<<<< HEAD
"juno-ui-components": "https://assets.juno.global.cloud.sap/libs/juno-ui-components@2.13.8/package.tgz",
"luxon": "^3.0.0",
"messages-provider": "https://assets.juno.global.cloud.sap/libs/messages-provider@0.1.12/package.tgz",
+=======
+ "luxon": "^3.4.4",
+>>>>>>> 01cf4521 (feat(heureka) : Add components view (#263))
"postcss": "^8.4.21",
"postcss-url": "^10.1.3",
"prop-types": "^15.8.1",
@@ -1899,6 +1912,57 @@
"integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==",
"dev": true
},
+<<<<<<< HEAD
+=======
+ "node_modules/@cloudoperators/juno-communicator": {
+ "version": "2.2.11",
+ "resolved": "https://registry.npmjs.org/@cloudoperators/juno-communicator/-/juno-communicator-2.2.11.tgz",
+ "integrity": "sha512-dDoqKw3nZuuNMkdmwYDG/l7Uw7a4rDF3RtteuEW9yUhMypocsGmbcgRhaZjUWpL21OPbFDVNi58r3+KO7IN2Ug==",
+ "engines": {
+ "node": ">=20.0.0 <21.0.0",
+ "npm": ">=10.0.0 <11.0.0"
+ }
+ },
+ "node_modules/@cloudoperators/juno-messages-provider": {
+ "version": "0.1.17",
+ "resolved": "https://registry.npmjs.org/@cloudoperators/juno-messages-provider/-/juno-messages-provider-0.1.17.tgz",
+ "integrity": "sha512-ZECrpMVr3jx25YdcyayFUSXMHDRp9hjDLLbUSvQqcJLxtscpE14WEqGffelAMfr0Q6AqOi0DlEoSMVFlh7fYZw==",
+ "dependencies": {
+ "@cloudoperators/juno-ui-components": "*"
+ },
+ "engines": {
+ "node": ">=20.0.0 <21.0.0",
+ "npm": ">=10.0.0 <11.0.0"
+ },
+ "peerDependencies": {
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "zustand": "^4.5.2"
+ }
+ },
+ "node_modules/@cloudoperators/juno-ui-components": {
+ "version": "2.15.4",
+ "resolved": "https://registry.npmjs.org/@cloudoperators/juno-ui-components/-/juno-ui-components-2.15.4.tgz",
+ "integrity": "sha512-lyziFGjtasxqiiZ86Yfn9EtJFtZ/72So1GmCsMdZCOt3WQnv/TcvQMnXCHe5Zg1fXZ/qNQWIac5rH6YbVS75yg==",
+ "engines": {
+ "node": ">=20.0.0 <21.0.0",
+ "npm": ">=10.0.0 <11.0.0"
+ },
+ "peerDependencies": {
+ "prop-types": "15.8.1",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0"
+ }
+ },
+ "node_modules/@cloudoperators/juno-url-state-provider-v1": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/@cloudoperators/juno-url-state-provider-v1/-/juno-url-state-provider-v1-1.3.2.tgz",
+ "integrity": "sha512-DVFzP/5actNs6fkfA93U7jUm9rY0/kPzFWrfGof6SGvhNx+WffQ9BBGQA/p9S7M3brgwxtxgHBnRvTDyA7fMDA==",
+ "dependencies": {
+ "juri": "^1.0.3"
+ }
+ },
+>>>>>>> 01cf4521 (feat(heureka) : Add components view (#263))
"node_modules/@esbuild/aix-ppc64": {
"version": "0.19.12",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.19.12.tgz",
diff --git a/heureka/ui/package.json b/heureka/ui/package.json
index a55c2efa..b2406d40 100644
--- a/heureka/ui/package.json
+++ b/heureka/ui/package.json
@@ -31,9 +31,13 @@
"immer": "^10.0.0",
"jest": "^29.3.1",
"jest-environment-jsdom": "^29.3.1",
+<<<<<<< HEAD
"juno-ui-components": "https://assets.juno.global.cloud.sap/libs/juno-ui-components@2.13.8/package.tgz",
"luxon": "^3.0.0",
"messages-provider": "https://assets.juno.global.cloud.sap/libs/messages-provider@0.1.12/package.tgz",
+=======
+ "luxon": "^3.4.4",
+>>>>>>> 01cf4521 (feat(heureka) : Add components view (#263))
"postcss": "^8.4.21",
"postcss-url": "^10.1.3",
"prop-types": "^15.8.1",
diff --git a/heureka/ui/src/components/components/ComponentsList.jsx b/heureka/ui/src/components/components/ComponentsList.jsx
new file mode 100644
index 00000000..dffd5757
--- /dev/null
+++ b/heureka/ui/src/components/components/ComponentsList.jsx
@@ -0,0 +1,51 @@
+/*
+ * SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Greenhouse contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from "react"
+import {
+ DataGrid,
+ DataGridRow,
+ DataGridHeadCell,
+ DataGridCell,
+} from "@cloudoperators/juno-ui-components"
+import HintNotFound from "../shared/HintNotFound"
+import HintLoading from "../shared/HintLoading"
+import ComponentsListItem from "./ComponentsListItem"
+
+const ComponentsList = ({ components, isLoading }) => {
+ return (
+
+
+ Name
+ Type
+ Total Number of Versions
+
+ {isLoading && !components ? (
+
+ ) : (
+ <>
+ {components?.length > 0 ? (
+ <>
+ {components.map((item, index) => (
+
+ ))}
+ >
+ ) : (
+
+
+
+
+
+ )}
+ >
+ )}
+
+ )
+}
+
+export default ComponentsList
diff --git a/heureka/ui/src/components/components/ComponentsListController.jsx b/heureka/ui/src/components/components/ComponentsListController.jsx
new file mode 100644
index 00000000..445c5ddd
--- /dev/null
+++ b/heureka/ui/src/components/components/ComponentsListController.jsx
@@ -0,0 +1,96 @@
+/*
+ * SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Greenhouse contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React, { useMemo, useState } from "react"
+import { useQuery } from "@tanstack/react-query"
+import {
+ useQueryClientFnReady,
+ useQueryOptions,
+ useActions,
+} from "../StoreProvider"
+import ComponentsList from "./ComponentsList"
+import {
+ Pagination,
+ Container,
+ Stack,
+} from "@cloudoperators/juno-ui-components"
+
+const ComponentsListController = () => {
+ const queryClientFnReady = useQueryClientFnReady()
+ const queryOptions = useQueryOptions("components")
+ const { setQueryOptions } = useActions()
+
+ const { isLoading, isFetching, isError, data, error } = useQuery({
+ queryKey: [`components`, queryOptions],
+ enabled: !!queryClientFnReady,
+ })
+
+ const [currentPage, setCurrentPage] = useState(1) // State for current page
+
+ const components = useMemo(() => {
+ if (!data) return null
+ return data?.Components?.edges
+ }, [data])
+
+ const pageInfo = useMemo(() => {
+ if (!data) return null
+ return data?.Components?.pageInfo
+ }, [data])
+
+ const totalPages = useMemo(() => {
+ if (!data?.Components?.pageInfo?.pages) return 0
+ return data?.Components?.pageInfo?.pages.length
+ }, [data?.Components?.pageInfo])
+ const onPaginationChanged = (newPage) => {
+ setCurrentPage(newPage) // Update currentPage
+ if (!data?.Components?.pageInfo?.pages) return
+ const pages = data?.Components?.pageInfo?.pages
+ const currentPageIndex = pages?.findIndex(
+ (page) => page?.pageNumber === parseInt(newPage)
+ )
+ if (currentPageIndex > -1) {
+ const after = pages[currentPageIndex]?.after
+ setQueryOptions("components", {
+ ...queryOptions,
+ after: `${after}`,
+ })
+ }
+ }
+
+ const onPressNext = () => {
+ onPaginationChanged(parseInt(currentPage) + 1)
+ }
+ const onPressPrevious = () => {
+ onPaginationChanged(parseInt(currentPage) - 1)
+ }
+ const onKeyPress = (oKey) => {
+ if (oKey.code === "Enter") {
+ onPaginationChanged(parseInt(oKey.currentTarget.value))
+ }
+ }
+
+ return (
+ <>
+
+
+
+
+
+
+ >
+ )
+}
+
+export default ComponentsListController
diff --git a/heureka/ui/src/components/components/ComponentsListItem.jsx b/heureka/ui/src/components/components/ComponentsListItem.jsx
new file mode 100644
index 00000000..da4ed811
--- /dev/null
+++ b/heureka/ui/src/components/components/ComponentsListItem.jsx
@@ -0,0 +1,19 @@
+/*
+ * SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Greenhouse contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from "react"
+import { DataGridRow, DataGridCell } from "@cloudoperators/juno-ui-components"
+
+const ComponentsListItem = ({ item }) => {
+ return (
+
+ {item?.node?.name}
+ {item?.node?.type}
+ {item?.node?.componentVersions?.totalCount}
+
+ )
+}
+
+export default ComponentsListItem
diff --git a/heureka/ui/src/components/components/ComponentsTab.jsx b/heureka/ui/src/components/components/ComponentsTab.jsx
new file mode 100644
index 00000000..581a4caf
--- /dev/null
+++ b/heureka/ui/src/components/components/ComponentsTab.jsx
@@ -0,0 +1,19 @@
+/*
+ * SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Greenhouse contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import React from "react"
+import ComponentsListController from "./ComponentsListController"
+import Filters from "../filters/Filters"
+
+const ComponentsTab = () => {
+ return (
+ <>
+
+
+ >
+ )
+}
+
+export default ComponentsTab
diff --git a/heureka/ui/src/components/issues/IssuesList.jsx b/heureka/ui/src/components/issues/IssuesList.jsx
index 5a7d62a4..0a1709ae 100644
--- a/heureka/ui/src/components/issues/IssuesList.jsx
+++ b/heureka/ui/src/components/issues/IssuesList.jsx
@@ -16,10 +16,12 @@ import IssuesListItem from "./IssuesListItem"
const IssuesList = ({ issues, isLoading }) => {
return (
-
+
Primary Name
- Secondary Name
+ Type
+ {/* Secondary Name */}
+ Remediation Date
Status
Severity
Component Name
@@ -40,7 +42,7 @@ const IssuesList = ({ issues, isLoading }) => {
>
) : (
-
+
diff --git a/heureka/ui/src/components/issues/IssuesListController.jsx b/heureka/ui/src/components/issues/IssuesListController.jsx
index ada0c09f..0ce51aca 100644
--- a/heureka/ui/src/components/issues/IssuesListController.jsx
+++ b/heureka/ui/src/components/issues/IssuesListController.jsx
@@ -11,7 +11,11 @@ import {
useActions,
} from "../StoreProvider"
import IssuesList from "./IssuesList"
-import { Pagination } from "juno-ui-components"
+import {
+ Container,
+ Pagination,
+ Stack,
+} from "@cloudoperators/juno-ui-components"
const IssuesListController = () => {
const queryClientFnReady = useQueryClientFnReady()
@@ -69,18 +73,22 @@ const IssuesListController = () => {
return (
<>
-
-
+
+
+
+
+
+
>
)
}
diff --git a/heureka/ui/src/components/issues/IssuesListItem.jsx b/heureka/ui/src/components/issues/IssuesListItem.jsx
index 1b92eb5d..0fad95d8 100644
--- a/heureka/ui/src/components/issues/IssuesListItem.jsx
+++ b/heureka/ui/src/components/issues/IssuesListItem.jsx
@@ -6,17 +6,24 @@
import React from "react"
import { DataGridRow, DataGridCell } from "juno-ui-components"
import { listOfCommaSeparatedObjs } from "../shared/Helper"
+import { DateTime } from "luxon"
const IssuesListItem = ({ item }) => {
+ const formatDate = (dateStr) => {
+ const dateObj = DateTime.fromISO(dateStr)
+ return dateObj.toFormat("yyyy.MM.dd.HH:mm:ss")
+ }
return (
{item?.node?.issue?.primaryName}
-
+ {item?.node?.issue?.type}
+ {/*
{listOfCommaSeparatedObjs(
item?.node?.effectiveIssueVariants,
"secondaryName"
- )}
-
+ )}
+ */}
+ {formatDate(item?.node?.remediationDate)}
{item?.node?.status}
{item?.node?.severity?.value}
diff --git a/heureka/ui/src/components/services/ServicesListController.jsx b/heureka/ui/src/components/services/ServicesListController.jsx
index aa506c00..5d1c70e3 100644
--- a/heureka/ui/src/components/services/ServicesListController.jsx
+++ b/heureka/ui/src/components/services/ServicesListController.jsx
@@ -13,7 +13,11 @@ import {
useFilteredServices,
useEndpoint,
} from "../StoreProvider"
-import { Pagination } from "@cloudoperators/juno-ui-components"
+import {
+ Pagination,
+ Container,
+ Stack,
+} from "@cloudoperators/juno-ui-components"
import ServicesList from "./ServicesList"
import {
Messages,
@@ -93,18 +97,22 @@ const ServicesListController = () => {
return (
<>
-
-
+
+
+
+
+
+
>
)
}
diff --git a/heureka/ui/src/components/tabs/TabContext.jsx b/heureka/ui/src/components/tabs/TabContext.jsx
index b50c95d4..a21d18c2 100644
--- a/heureka/ui/src/components/tabs/TabContext.jsx
+++ b/heureka/ui/src/components/tabs/TabContext.jsx
@@ -10,6 +10,7 @@ import { useActions, useActiveTab } from "../StoreProvider"
import ServicesTab from "../services/ServicesTab"
import IssuesTab from "../issues/IssuesTab"
+import ComponentsTab from "../components/ComponentsTab"
const TAB_CONFIG = [
{
@@ -24,6 +25,12 @@ const TAB_CONFIG = [
icon: "autoAwesomeMotion",
component: IssuesTab,
},
+ {
+ label: "Components",
+ value: "components",
+ icon: "autoAwesomeMotion",
+ component: ComponentsTab,
+ },
]
const TabContext = () => {
diff --git a/heureka/ui/src/hooks/useQueryClientFn.js b/heureka/ui/src/hooks/useQueryClientFn.js
index 3cc7ebad..0e95699e 100644
--- a/heureka/ui/src/hooks/useQueryClientFn.js
+++ b/heureka/ui/src/hooks/useQueryClientFn.js
@@ -10,6 +10,7 @@ import { request } from "graphql-request"
import sevicesQuery from "../lib/queries/services"
import issueMatchesQuery from "../lib/queries/issueMatches"
import ServiceFilterQuery from "../lib/queries/serviceFilters"
+import componentsQuery from "../lib/queries/components"
// hook to register query defaults that depends on the queryClient and options
const useQueryClientFn = () => {
@@ -40,6 +41,14 @@ const useQueryClientFn = () => {
},
})
+ queryClient.setQueryDefaults(["components"], {
+ queryFn: async ({ queryKey }) => {
+ const [_key, options] = queryKey
+ console.log("useQueryClientFn::: queryKey: ", queryKey)
+ return await request(endpoint, componentsQuery(), options)
+ },
+ })
+
queryClient.setQueryDefaults(["serviceFilters"], {
queryFn: async ({ queryKey }) => {
console.log("useQueryClientFn::: queryKey: ", queryKey)
diff --git a/heureka/ui/src/lib/queries/components.js b/heureka/ui/src/lib/queries/components.js
new file mode 100644
index 00000000..f39041f0
--- /dev/null
+++ b/heureka/ui/src/lib/queries/components.js
@@ -0,0 +1,60 @@
+/*
+ * SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Greenhouse contributors
+ * SPDX-License-Identifier: Apache-2.0
+ */
+
+import { gql } from "graphql-request"
+
+// gql
+// It is there for convenience so that you can get the tooling support
+// like prettier formatting and IDE syntax highlighting.
+// You can use gql from graphql-tag if you need it for some reason too.
+export default () => gql`
+ query ($filter: ComponentFilter, $first: Int, $after: String) {
+ Components(filter: $filter, first: $first, after: $after) {
+ totalCount
+ edges {
+ node {
+ id
+ name
+ type
+ componentVersions {
+ totalCount
+ edges {
+ node {
+ id
+ version
+ issues {
+ totalCount
+ }
+ componentInstances {
+ totalCount
+ edges {
+ node {
+ id
+ }
+ }
+ }
+ }
+ cursor
+ }
+ }
+ }
+ cursor
+ }
+ pageInfo {
+ hasNextPage
+ hasPreviousPage
+ isValidPage
+ pageNumber
+ nextPageAfter
+ pages {
+ after
+ isCurrent
+ pageNumber
+ pageCount
+ }
+ }
+ }
+ }
+`
diff --git a/heureka/ui/src/lib/store.js b/heureka/ui/src/lib/store.js
index 60c94a55..6188797e 100644
--- a/heureka/ui/src/lib/store.js
+++ b/heureka/ui/src/lib/store.js
@@ -37,6 +37,11 @@ export default (options) =>
first: 20,
},
},
+ components: {
+ queryOptions: {
+ first: 20,
+ },
+ },
},
filters: {
...initialFiltersState,