Skip to content

Commit 74fb4ad

Browse files
chore(example): improve example app types (1st iteration) (#734)
* chore(ui): convert components to typescript syntax * chore(ui): improve types * chore(ui): improve types changeset * chore(ui): disable errors * chore(ui): fix lint errors * chore(ui): fix lint errors * chore(ui): delete MonorepoChecker * chore(ui): disable lint errors * chore(ui): PR comment improvements
1 parent 065652a commit 74fb4ad

30 files changed

+635
-524
lines changed

.changeset/fair-ears-shave.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@cloudoperators/juno-app-example": minor
3+
---
4+
5+
Improve example app types

apps/example/src/App.test.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,20 +6,19 @@
66
import React from "react"
77
import { render } from "@testing-library/react"
88
import App from "./App"
9-
import { describe } from "node:test"
9+
import { describe, it, expect, vi } from "vitest"
1010
import { screen } from "shadow-dom-testing-library"
1111

1212
// Mock the styles
1313
vi.mock("./styles.module.scss", () => ({
14-
default: new Proxy(new Object(), {
15-
// @ts-ignore
16-
toString() {
17-
return "/*TEST STYLES*/"
18-
},
19-
}),
14+
default: new Proxy(
15+
{},
16+
{
17+
get: () => "/*TEST STYLES*/",
18+
}
19+
),
2020
}))
2121

22-
// eslint-disable-next-line @typescript-eslint/no-floating-promises
2322
describe("App", () => {
2423
it("should render the App component", () => {
2524
render(<App id="123" />)

apps/example/src/App.tsx

Lines changed: 31 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,17 @@
22
/* eslint-disable @typescript-eslint/no-unsafe-return */
33
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
44
/* eslint-disable @typescript-eslint/no-unsafe-call */
5+
56
/*
67
* SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Juno contributors
78
* SPDX-License-Identifier: Apache-2.0
89
*/
910

10-
import React, { useEffect } from "react"
11-
import PropTypes from "prop-types"
11+
import React, { useEffect, useMemo } from "react"
12+
1213
// @ts-ignore
1314
import styles from "./styles.scss?inline"
1415

15-
import MonorepoChecker from "./components/MonorepoChecker"
16-
1716
import {
1817
AppShellProvider,
1918
AppShell,
@@ -24,87 +23,74 @@ import {
2423
} from "@cloudoperators/juno-ui-components"
2524
import { mockedSession } from "@cloudoperators/juno-oauth"
2625
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
26+
import { MessagesProvider } from "@cloudoperators/juno-messages-provider"
27+
2728
import AppContent from "./components/AppContent"
2829
import HeaderUser from "./components/auth/HeaderUser"
2930
import AsyncWorker from "./components/AsyncWorker"
3031
import StoreProvider, { useGlobalsActions, useAuthActions } from "./components/StoreProvider"
31-
import { MessagesProvider } from "@cloudoperators/juno-messages-provider"
3232

33-
const App = (props = {}) => {
33+
interface AppProps {
34+
endpoint?: string
35+
embedded?: boolean
36+
id?: string
37+
theme?: string
38+
}
39+
40+
const App: React.FC<AppProps> = ({ endpoint, embedded, id }) => {
3441
// @ts-ignore
3542
const { setEndpoint } = useGlobalsActions()
3643
// @ts-ignore
3744
const { setData } = useAuthActions()
3845

39-
// Create query client which it can be used from overall in the app
4046
const queryClient = new QueryClient()
4147

42-
// on app initial load save Endpoint and URL_STATE_KEY so it can be
43-
// used from overall in the application
4448
useEffect(() => {
45-
// set default endpoint so the useQueryClientFn can be used
46-
// @ts-ignore
47-
setEndpoint(props.endpoint)
48-
}, [])
49+
setEndpoint(endpoint || "")
50+
}, [endpoint, setEndpoint])
4951

50-
// fetch the mocked auth object and save it globally
51-
const oidc = React.useMemo(() => {
52-
// force fetch mocked session
53-
return mockedSession({
54-
initialLogin: true,
55-
onUpdate: (data: any) => {
56-
setData(data)
57-
},
58-
})
59-
}, [])
52+
const oidc = useMemo(
53+
() =>
54+
mockedSession({
55+
initialLogin: true,
56+
onUpdate: setData,
57+
}),
58+
[setData]
59+
)
6060

61-
// @ts-ignore
62-
console.debug("[exampleapp] embedded mode:", props.embedded)
61+
console.debug("[exampleapp] embedded mode:", embedded)
6362

6463
return (
6564
<QueryClientProvider client={queryClient}>
66-
<MonorepoChecker></MonorepoChecker>
67-
{/* @ts-ignore */}
68-
<AsyncWorker consumerId={props.id} />
6965
{/* @ts-ignore */}
66+
<AsyncWorker consumerId={id} />
7067
<AppShell
71-
//@ts-ignore
72-
embedded={props.embedded === "true" || props.embedded === true}
68+
// @ts-ignore
69+
embedded={embedded === "true" || embedded === true}
7370
pageHeader={
74-
//@ts-ignore
7571
<PageHeader heading="Converged Cloud | Example App">
76-
{/* @ts-ignore */}
7772
<HeaderUser login={oidc.login} logout={oidc.logout} />
7873
</PageHeader>
7974
}
8075
topNavigation={
81-
//@ts-ignore
8276
<TopNavigation>
83-
{/* @ts-ignore */}
8477
<TopNavigationItem icon="home" label="Home" />
85-
{/* @ts-ignore */}
8678
<TopNavigationItem active label="Navigation Item" />
8779
</TopNavigation>
8880
}
8981
>
9082
<Container py>
91-
{/* @ts-ignore */}
92-
<AppContent props={props} />
83+
<AppContent />
9384
</Container>
9485
</AppShell>
9586
</QueryClientProvider>
9687
)
9788
}
9889

99-
App.propTypes = {
100-
endpoint: PropTypes.string,
101-
embedded: PropTypes.bool,
102-
id: PropTypes.string,
103-
}
104-
105-
const StyledApp = (props: any) => {
90+
const StyledApp: React.FC<AppProps> = (props) => {
10691
return (
107-
<AppShellProvider theme={`${props.theme ? props.theme : "theme-dark"}`}>
92+
// @ts-ignore
93+
<AppShellProvider theme={props.theme || "theme-dark"}>
10894
{/* load styles inside the shadow dom */}
10995
<style>{styles.toString()}</style>
11096
<MessagesProvider>
@@ -116,10 +102,4 @@ const StyledApp = (props: any) => {
116102
)
117103
}
118104

119-
StyledApp.propTypes = {
120-
theme: PropTypes.string,
121-
embedded: PropTypes.bool,
122-
endpoint: PropTypes.string,
123-
id: PropTypes.string,
124-
}
125105
export default StyledApp

apps/example/src/components/AppContent.tsx

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
/* eslint-disable @typescript-eslint/no-unsafe-return */
21
/* eslint-disable @typescript-eslint/no-unsafe-call */
32
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
3+
44
/*
55
* SPDX-FileCopyrightText: 2024 SAP SE or an SAP affiliate company and Juno contributors
66
* SPDX-License-Identifier: Apache-2.0
@@ -22,14 +22,14 @@ import {
2222
} from "@cloudoperators/juno-ui-components"
2323
import { useGlobalsActions, useGlobalsTabIndex, useAuthLoggedIn, useAuthError } from "./StoreProvider"
2424
import { useActions, Messages } from "@cloudoperators/juno-messages-provider"
25+
2526
import ModalManager from "./ModalManager"
2627
import PanelManager from "./PanelManager"
2728
import Peaks from "./peaks/Peaks"
2829
import WelcomeView from "./WelcomeView"
2930
import PositionArea from "./PositionArea"
3031

31-
const AppContent = () => {
32-
// @ts-ignore
32+
const AppContent: React.FC = () => {
3333
const { setTabIndex, setCurrentModal } = useGlobalsActions()
3434
const loggedIn = useAuthLoggedIn()
3535
const authError = useAuthError()
@@ -44,9 +44,9 @@ const AppContent = () => {
4444
text: JSON.stringify(authError),
4545
})
4646
}
47-
}, [authError])
47+
}, [authError, addMessage])
4848

49-
const onTabSelected = (index: any) => {
49+
const onTabSelected = (index: number) => {
5050
setTabIndex(index)
5151
}
5252

@@ -55,23 +55,17 @@ const AppContent = () => {
5555
{loggedIn && !authError ? (
5656
<>
5757
<Breadcrumb>
58-
{/* @ts-ignore */}
5958
<BreadcrumbItem icon="home" label="Example App Home" />
6059
</Breadcrumb>
6160

6261
<Container py>
63-
{/* @ts-ignore */}
6462
<MainTabs selectedIndex={tabIndex} onSelect={onTabSelected}>
65-
{/* @ts-ignore */}
6663
<TabList>
67-
{/* @ts-ignore */}
6864
<Tab>Peaks</Tab>
69-
{/* @ts-ignore */}
7065
<Tab>Tab Two</Tab>
7166
</TabList>
7267

7368
<TabPanel>
74-
{/* @ts-ignore */}
7569
<Container py px={false}>
7670
{/* Set the background graphic using tailwind background image syntax as below. The image must exist at the specified location in your app */}
7771
{/*<IntroBox variant="hero" heroImage="bg-[url('img/app_bg_example.svg')]">
@@ -84,28 +78,20 @@ const AppContent = () => {
8478
</Container>
8579
</TabPanel>
8680
<TabPanel>
87-
{/* @ts-ignore */}
8881
<Container py px={false}>
8982
<p>Test a panel pressing the Button</p>
90-
{/* @ts-ignore */}
91-
<Button label="Button" onClick={() => setCurrentModal("TestModal")} />
83+
<Button label="Button" onClick={() => setCurrentModal({ type: "TestModal" })} />
9284
<p>Test a select</p>
93-
{/* @ts-ignore */}
9485
<Select
9586
name="filter"
9687
className="filter-label-select w-64 mb-0"
9788
label="Filter"
98-
onChange={(e: any) => console.debug(e)}
89+
onChange={(e) => console.debug(e)}
9990
>
100-
{/* @ts-ignore */}
10191
<SelectOption value="0" label="Option 0" />
102-
{/* @ts-ignore */}
10392
<SelectOption value="1" label="Option 1" />
104-
{/* @ts-ignore */}
10593
<SelectOption value="2" label="Option 2" />
106-
{/* @ts-ignore */}
10794
<SelectOption value="3" label="Option 3" />
108-
{/* @ts-ignore */}
10995
<SelectOption value="4" label="Option 4" />
11096
</Select>
11197
</Container>

apps/example/src/components/AsyncWorker.tsx

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,19 @@
33
* SPDX-License-Identifier: Apache-2.0
44
*/
55

6-
import PropTypes from "prop-types"
6+
import React from "react"
7+
78
import useQueryClientFn from "../hooks/useQueryClientFn"
89
import useUrlState from "../hooks/useUrlState"
910

10-
const AsyncWorker = ({ consumerId }: any) => {
11+
interface AsyncWorkerProps {
12+
consumerId: string
13+
}
14+
15+
const AsyncWorker: React.FC<AsyncWorkerProps> = ({ consumerId }) => {
1116
useQueryClientFn()
1217
useUrlState(consumerId)
1318
return null
1419
}
1520

16-
AsyncWorker.propTypes = {
17-
consumerId: PropTypes.string.isRequired,
18-
}
19-
2021
export default AsyncWorker

apps/example/src/components/ModalManager.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@
44
*/
55

66
import React from "react"
7+
78
import { useGlobalsCurrentModal } from "./StoreProvider"
89
import TestModal from "./TestModal"
910

10-
const ModalManager = () => {
11+
const ModalManager: React.FC = () => {
1112
const currentModal = useGlobalsCurrentModal()
1213

1314
switch (currentModal) {

apps/example/src/components/MonorepoChecker.tsx

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

0 commit comments

Comments
 (0)