Skip to content

Commit

Permalink
feat(heureka): list services
Browse files Browse the repository at this point in the history
  • Loading branch information
taymoor89 committed Feb 14, 2025
1 parent c770519 commit 0d81285
Show file tree
Hide file tree
Showing 15 changed files with 151 additions and 102 deletions.
5 changes: 5 additions & 0 deletions .changeset/many-jars-obey.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"heureka-next": minor
---

The app is now able to communicate with the GraphQL backend.
1 change: 1 addition & 0 deletions apps/heureka-next/.env.template
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
API_ENDPOINT=SOME_URL
46 changes: 46 additions & 0 deletions apps/heureka-next/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,52 @@

This app will eventually become a successor to the existing Heureka app.

## How to run locally?

1. Go to app directory:
```bash
cd apps/heureka-next
```
2. If you are running the app for the first time, follow these steps. Otherwise, skip to step 3:
1. Create `appProps.json` and change the configurations accordingly:
```bash
cp appProps.template.json appProps.json
```
2. Create `.env` file and change configurations accordingly:
```bash
cp .env.template .env
```
3. Install dependencies:
```bash
npm i
```
4. Run the development server:
```bash
npm run dev
```

## How to update GraphQL types?

1. Go to app directory:
```bash
cd apps/heureka-next
```
2. Update GraphQL types from the latest GraphQL schema:
```bash
npm run generate:types
```

## How to run tests?

1. Go to app directory:
```bash
cd apps/heureka-next
```
2. Run tests:
```bash
npm run test
```

## Contributing

We welcome contributions from the community. Please follow our [contribution guidelines] to contribute to this project.
Expand Down
4 changes: 4 additions & 0 deletions apps/heureka-next/appProps.template.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"apiEndpoint": "YOUR_GRAPHQL_API_ENDPOINT",
"embedded": false
}
3 changes: 1 addition & 2 deletions apps/heureka-next/codegen.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@ import * as dotenv from "dotenv"

// Load environment variables from .env file
dotenv.config()
const schemaUrl = ""

const config: CodegenConfig = {
schema: schemaUrl,
schema: process.env.API_ENDPOINT,
documents: "src/**/*.graphql",

generates: {
Expand Down
13 changes: 13 additions & 0 deletions apps/heureka-next/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,19 @@
<title>Heureka Next</title>
</head>
<body>
<script type="module">
// appProps are excluded from standalone build and should be generated from outside
fetch("./appProps.json")
.then((res) => res.json())
.catch((error) => {
console.warn("No appProps found, using default props", error.message)
})
.then((props) => {
import("./src/index").then((app) => {
app.mount(document.getElementById("root"), props)
})
})
</script>
<div id="root"></div>
<script type="module" src="/src/index.tsx"></script>
</body>
Expand Down
10 changes: 6 additions & 4 deletions apps/heureka-next/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,22 @@ import { AppShellProvider } from "@cloudoperators/juno-ui-components"
import { ErrorBoundary } from "./components/ErrorBoundary"
import { Shell } from "./components/Shell"
import { ApolloProvider } from "@apollo/client"
import { client } from "./apollo-client"
import { getClient } from "./apollo-client"

export type AppProps = {
theme?: "theme-dark" | "theme-light"
apiEndpoint?: string
embedded?: boolean
}

export const App = (props: AppProps) => (
<ApolloProvider client={client}>
const App = (props: AppProps) => (
<ApolloProvider client={getClient({ uri: props.apiEndpoint })}>
<AppShellProvider theme={`${props.theme ? props.theme : "theme-dark"}`}>
<ErrorBoundary>
<Shell {...props} />
</ErrorBoundary>
</AppShellProvider>
<App />
</ApolloProvider>
)

export default App
17 changes: 13 additions & 4 deletions apps/heureka-next/src/apollo-client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import { ApolloClient, InMemoryCache } from "@apollo/client"

export const client = new ApolloClient({
uri: "",
cache: new InMemoryCache(),
})
type ClientOptions = {
uri?: string
}

export const getClient = ({ uri }: ClientOptions) => {
if (typeof uri === "undefined") {
throw new Error("No API endpoint provided.")
}
return new ApolloClient({
uri,
cache: new InMemoryCache(),
})
}
37 changes: 34 additions & 3 deletions apps/heureka-next/src/components/Services/Services.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,42 @@

import React from "react"
import { render, screen } from "@testing-library/react"
import { MockedProvider } from "@apollo/client/testing"
import { Services } from "./Services"
import { GetServicesDocument } from "../../generated/graphql"

const mocks = [
{
request: {
query: GetServicesDocument,
},
result: {
data: {
Services: {
edges: [
{
node: {
id: "some-id",
ccrn: "some-ccrn",
__typename: "Service",
},
__typename: "ServiceEdge",
},
],
__typename: "ServiceConnection",
},
},
},
},
]

describe("Services", () => {
it("should render correctly", () => {
render(<Services />)
expect(screen.getByText("render services here...")).toBeInTheDocument()
it("should render correctly", async () => {
render(
<MockedProvider mocks={mocks}>
<Services />
</MockedProvider>
)
expect(await screen.findByText("some-ccrn")).toBeInTheDocument()
})
})
9 changes: 1 addition & 8 deletions apps/heureka-next/src/components/Services/Services.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,5 @@ export const Services = () => {
if (loading) return <p>Loading...</p>
if (error) return <p>Error</p>

return (
<div>
{data?.Services?.edges?.map((service) => {
console.log("TEST NAME", service?.node.ccrn)
return <p>{service?.node.ccrn}</p>
})}
</div>
)
return <div>{data?.Services?.edges?.map((service) => <div key={service?.node.id}>{service?.node.ccrn}</div>)}</div>
}
8 changes: 8 additions & 0 deletions apps/heureka-next/src/components/Shell/Shell.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ import { render, screen } from "@testing-library/react"
import userEvent from "@testing-library/user-event"
import { Shell } from "./Shell"

/**
* let's mock Services because that is a dependency of Shell
* and has been tested independently
**/
vitest.mock("../Services/Services", () => ({
Services: () => <div>render services here...</div>,
}))

const renderShell = () => ({
user: userEvent.setup(),
...render(<Shell />),
Expand Down
52 changes: 1 addition & 51 deletions apps/heureka-next/src/generated/graphql.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1354,33 +1354,7 @@ export type GetServicesQuery = {
__typename?: "ServiceConnection"
edges?: Array<{
__typename?: "ServiceEdge"
cursor?: string | null
node: {
__typename?: "Service"
id: string
ccrn?: string | null
objectMetadata?: {
__typename?: "ServiceMetadata"
componentInstanceCount: number
issueMatchCount: number
} | null
owners?: {
__typename?: "UserConnection"
edges?: Array<{
__typename?: "UserEdge"
cursor?: string | null
node: { __typename?: "User"; id: string; uniqueUserId?: string | null; name?: string | null }
} | null> | null
} | null
supportGroups?: {
__typename?: "SupportGroupConnection"
edges?: Array<{
__typename?: "SupportGroupEdge"
cursor?: string | null
node: { __typename?: "SupportGroup"; id: string; ccrn?: string | null }
} | null> | null
} | null
}
node: { __typename?: "Service"; id: string; ccrn?: string | null }
} | null> | null
} | null
}
Expand All @@ -1392,31 +1366,7 @@ export const GetServicesDocument = gql`
node {
id
ccrn
objectMetadata {
componentInstanceCount
issueMatchCount
}
owners {
edges {
node {
id
uniqueUserId
name
}
cursor
}
}
supportGroups {
edges {
node {
id
ccrn
}
cursor
}
}
}
cursor
}
}
}
Expand Down
24 changes: 0 additions & 24 deletions apps/heureka-next/src/graphql/Services/getServices.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -4,31 +4,7 @@ query GetServices($filter: ServiceFilter, $first: Int, $after: String) {
node {
id
ccrn
objectMetadata {
componentInstanceCount
issueMatchCount
}
owners {
edges {
node {
id
uniqueUserId
name
}
cursor
}
}
supportGroups {
edges {
node {
id
ccrn
}
cursor
}
}
}
cursor
}
}
}
21 changes: 16 additions & 5 deletions apps/heureka-next/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
/*
* SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Greenhouse contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from "react"
import { createRoot } from "react-dom/client"
import { createRoot, Root } from "react-dom/client"
import "tailwindcss/tailwind.css"
import "./index.scss"
import { App } from "./App"
import { AppProps } from "./App"

let root: Root

const container: HTMLElement = document.getElementById("root")!
const root = createRoot(container)
export const mount = (container: HTMLElement, props: AppProps = {}) => {
import("./App").then((App) => {
root = createRoot(container)
root.render(React.createElement(App.default, props))
})
}

root.render(<App />)
export const unmount = () => root?.unmount()
3 changes: 2 additions & 1 deletion apps/heureka-next/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export default defineConfig(({ mode }) => {
server: {
host: "0.0.0.0",
port: parseInt(process.env.PORT || "3000"),
allowedHosts: true,
},
}

Expand All @@ -52,7 +53,7 @@ export default defineConfig(({ mode }) => {
lib: {
entry: "src/index.tsx",
formats: ["es"],
fileName: (format) => `index.js`,
fileName: () => `index.js`,
},
},
}
Expand Down

0 comments on commit 0d81285

Please sign in to comment.