Skip to content

Commit

Permalink
Add Login page (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
Or-Geva authored Jun 28, 2023
1 parent 2f9788b commit a39be82
Show file tree
Hide file tree
Showing 65 changed files with 2,781 additions and 173 deletions.
4 changes: 0 additions & 4 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,6 @@
"prefer-rest-params": "error",
"prefer-spread": "error",
"prefer-template": "error",
"quotes": [
"error",
"single"
],
"rest-spread-spacing": [
"error",
"never"
Expand Down
1 change: 1 addition & 0 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
</head>

<body>
<div id="overlay"></div>
<div id="root"></div>
</body>

Expand Down
8 changes: 7 additions & 1 deletion src/App.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,17 @@
height: calc(100vh);
}

.App-body {
.AppBody {
color: white;
padding: 15px;
}

.loading {
align-items: center;
display: flex;
justify-content: center;
}

* {
margin: 0;
padding: 0;
Expand Down
41 changes: 32 additions & 9 deletions src/App.test.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,27 @@
import { render, screen } from '@testing-library/react'
import App from './App'
import { webviewEventType } from './api/webviewEvent'
import { IDependencyPage, IEosPage, IIaCPage, ISecretsPage, PageType } from './model/webviewPages'
import {
IDependencyPage,
IEosPage,
IIaCPage,
ILoginPage,
ISecretsPage,
PageType
} from './model/webviewPages'
import { ISeverity } from './model/severity'
import { IImpactGraph } from './model/impactGraph'
import { sendWebviewPage } from './utils/testUtils'
import { IAnalysisStep } from './model/analysisStep'
import { WebviewReceiveEventType } from './api'
import { LoginConnectionType, LoginProgressStatus } from './model/login'

describe('App component', () => {
test('renders the Dependency page when the page type is "Dependency"', async () => {
render(<App />)

// Load Dependency.
const pageData = {
type: webviewEventType.ShowPage,
type: WebviewReceiveEventType.ShowPage,
pageData: {
id: 'Dependency-ID',
pageType: PageType.Dependency,
Expand All @@ -36,7 +44,7 @@ describe('App component', () => {

// Load Eos page.
const pageData = {
type: webviewEventType.ShowPage,
type: WebviewReceiveEventType.ShowPage,
pageData: {
pageType: PageType.Eos,
header: 'Header-eos',
Expand All @@ -54,7 +62,7 @@ describe('App component', () => {

// Load IaC page.
const pageData = {
type: webviewEventType.ShowPage,
type: WebviewReceiveEventType.ShowPage,
pageData: {
pageType: PageType.IaC,
header: 'Header-iac',
Expand All @@ -74,7 +82,7 @@ describe('App component', () => {

// Load Secrets page.
const pageData = {
type: webviewEventType.ShowPage,
type: WebviewReceiveEventType.ShowPage,
pageData: {
pageType: PageType.Secrets,
header: 'Header-secret',
Expand All @@ -89,10 +97,25 @@ describe('App component', () => {
expect(screen.getByText('Header-secret')).toBeInTheDocument()
})

test('renders "Nothing to show" when the page type is not recognized', () => {
test('renders the Login page when the page type is "Login"', async () => {
render(<App />)

// Assert that "Nothing to show" text is rendered.
expect(screen.getByText('Nothing to show')).toBeInTheDocument()
const pageData = {
type: WebviewReceiveEventType.ShowPage,
pageData: {
pageType: PageType.Login,
url: 'www.example.com',
status: LoginProgressStatus.Initial,
connectionType: LoginConnectionType.BasicAuthOrToken
} as ILoginPage
}
await sendWebviewPage(pageData)

expect(screen.getByText('Welcome to JFrog')).toBeInTheDocument()
})

test('renders loading spinner initially', () => {
const { container } = render(<App />)
expect(container.querySelector('.loader')).toBeInTheDocument()
})
})
28 changes: 19 additions & 9 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,36 +7,46 @@ import Secrets from './components/Page/Secrets/Secrets'
import { WebviewPage, PageType } from './model/webviewPages'
import { EventManager } from './api/eventManager'
import { eventManagerContext } from './store/eventContext'
import { Spinner, State } from './components/UI/Spinner/Spinner'
import { Login } from './components/Page/Login/Login'

/**
* The main page on which the Webview will be drawn based on the incoming request page type.
*/
function App(): JSX.Element {
const [data, setDependencyData] = useState<WebviewPage>({} as WebviewPage)
const eventManager = useMemo(() => new EventManager(setDependencyData), [])
const [pageData, setPageData] = useState<WebviewPage>({} as WebviewPage)

const eventManager = useMemo(() => new EventManager(setPageData), [])
let page

switch (data.pageType) {
switch (pageData.pageType) {
case PageType.Dependency:
page = <Dependency data={data} />
page = <Dependency data={pageData} />
break
case PageType.Eos:
page = <Eos data={data} />
page = <Eos data={pageData} />
break
case PageType.IaC:
page = <IaC data={data} />
page = <IaC data={pageData} />
break
case PageType.Secrets:
page = <Secrets data={data} />
page = <Secrets data={pageData} />
break
case PageType.Login:
page = <Login data={pageData} />
break
default:
page = <>Nothing to show</>
page = (
<div className={css.loading}>
<Spinner state={State.Loading} />
</div>
)
}

return (
<div className={css.App}>
<eventManagerContext.Provider value={eventManager}>
<div className={css['App-body']}>{page}</div>
<div className={css.AppBody}>{page}</div>
</eventManagerContext.Provider>
</div>
)
Expand Down
6 changes: 3 additions & 3 deletions src/api/eventManager.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { WebviewReceiveEventType } from '.'
import { IPageData, sendWebviewPage } from '../utils/testUtils'
import { EventManager } from './eventManager'
import { webviewEventType } from './webviewEvent'

describe('EventManager util', () => {
let setPageStateMock: jest.Mock
Expand All @@ -16,7 +16,7 @@ describe('EventManager util', () => {

test('sets the event receiver and handles ShowPage event', async () => {
const pageData = {
type: webviewEventType.ShowPage,
type: WebviewReceiveEventType.ShowPage,
pageData: { title: 'Test Page' }
}
await sendWebviewPage(pageData)
Expand All @@ -29,7 +29,7 @@ describe('EventManager util', () => {
const consoleLogSpy = jest.spyOn(global.console, 'warn')
const emitterFunc = 'return console.warn'
const setEmitterEvent = {
type: webviewEventType.SetEmitter,
type: WebviewReceiveEventType.SetEmitter,
emitterFunc
} as IPageData

Expand Down
27 changes: 19 additions & 8 deletions src/api/eventManager.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,46 @@
import {
WebviewReceiveEvent,
WebviewReceiveEventType,
WebviewSendEvent,
WebviewSendEventType
} from '.'
import { IAnalysisStep } from '../model/analysisStep'
import { ISendLoginEventData } from '../model/login'
import { WebviewPage } from '../model/webviewPages'
import { IdeEvent, IdeEventType, JumpToCodeEvent } from './ideEvent'
import { WebviewEvent, webviewEventType } from './webviewEvent'
import { SendJumpToCodeEvent } from './sendEvent/jumpToCode'
import { SendLoginEvent } from './sendEvent/login'

export class EventManager {
private sendFunc = new Function('request', 'console.log(request)')
protected sendFunc = new Function('request', 'console.log(request)')

constructor(private setPageState: React.Dispatch<React.SetStateAction<WebviewPage>>) {
this.setEventReceiver()
}

private sendEvent = (req: IdeEvent): void => {
private sendEvent = (req: WebviewSendEvent): void => {
this.sendFunc(req)
}

private setEventReceiver(): void {
window.addEventListener('message', event => {
const eventData: WebviewEvent = event.data
const eventData: WebviewReceiveEvent = event.data

switch (eventData.type) {
case webviewEventType.SetEmitter:
case WebviewReceiveEventType.SetEmitter:
this.sendFunc = new Function(eventData.emitterFunc)()
break
case webviewEventType.ShowPage:
case WebviewReceiveEventType.ShowPage:
this.setPageState(eventData.pageData)
break
}
})
}

public jumpToCode(data: IAnalysisStep): void {
this.sendEvent({ type: IdeEventType.JUMP_TO_CODE, data: data } as JumpToCodeEvent)
this.sendEvent({ type: WebviewSendEventType.JumpToCode, data: data } as SendJumpToCodeEvent)
}

public Login(data: ISendLoginEventData): void {
this.sendEvent({ type: WebviewSendEventType.Login, data: data } as SendLoginEvent)
}
}
28 changes: 0 additions & 28 deletions src/api/ideEvent.test.ts

This file was deleted.

12 changes: 0 additions & 12 deletions src/api/ideEvent.ts

This file was deleted.

20 changes: 20 additions & 0 deletions src/api/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { SendLoginEvent } from './sendEvent/login'
import { SendJumpToCodeEvent } from './sendEvent/jumpToCode'
import { ReceiveSetEmitterEvent } from './receiveEvent/setEmitter'
import { ReceiveShowPageEvent } from './receiveEvent/showPage'

// Send event to the IDEs.
export enum WebviewSendEventType {
JumpToCode = 'SHOW_CODE',
Login = 'LOGIN'
}

export type WebviewSendEvent = SendJumpToCodeEvent | SendLoginEvent

// Receive events from the IDEs.
export enum WebviewReceiveEventType {
SetEmitter = 'SET_EMITTER',
ShowPage = 'SHOW_DATA'
}

export type WebviewReceiveEvent = ReceiveShowPageEvent | ReceiveSetEmitterEvent
2 changes: 2 additions & 0 deletions src/api/receiveEvent/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { ReceiveSetEmitterEvent } from './setEmitter'
export { ReceiveShowPageEvent } from './showPage'
18 changes: 18 additions & 0 deletions src/api/receiveEvent/setEmitter.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { ReceiveSetEmitterEvent } from '.'
import { WebviewReceiveEventType } from '..'

describe('Event Types', () => {
test('defines webviewEventType enum correctly', () => {
expect(WebviewReceiveEventType.SetEmitter).toEqual('SET_EMITTER')
})

test('defines SetEmitterEvent interface correctly', () => {
const eventData: ReceiveSetEmitterEvent = {
type: WebviewReceiveEventType.SetEmitter,
emitterFunc: 'exampleEmitterFunc'
}

expect(eventData.type).toEqual(WebviewReceiveEventType.SetEmitter)
expect(eventData.emitterFunc).toEqual('exampleEmitterFunc')
})
})
6 changes: 6 additions & 0 deletions src/api/receiveEvent/setEmitter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { WebviewReceiveEventType } from '..'

export interface ReceiveSetEmitterEvent {
type: WebviewReceiveEventType.SetEmitter
emitterFunc: string
}
29 changes: 29 additions & 0 deletions src/api/receiveEvent/showPage.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { WebviewReceiveEventType } from '..'
import { IDependencyPage } from '../../model/webviewPages'
import { ReceiveShowPageEvent } from './showPage'

describe('Event Types', () => {
test('defines webviewEventType enum correctly', () => {
expect(WebviewReceiveEventType.SetEmitter).toEqual('SET_EMITTER')
})

test('defines ShowPageEvent interface correctly', () => {
const eventData: ReceiveShowPageEvent = {
type: WebviewReceiveEventType.ShowPage,
pageData: {} as IDependencyPage
}

expect(eventData.type).toEqual(WebviewReceiveEventType.ShowPage)
expect(eventData.pageData).toBeDefined()
})

test('defines WebviewEvent union type correctly', () => {
const event: ReceiveShowPageEvent = {
type: WebviewReceiveEventType.ShowPage,
pageData: {} as IDependencyPage
}

expect(event.type).toEqual(WebviewReceiveEventType.ShowPage)
expect(event.pageData).toBeDefined()
})
})
7 changes: 7 additions & 0 deletions src/api/receiveEvent/showPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { WebviewReceiveEventType } from '..'
import { WebviewPage } from '../../model/webviewPages'

export interface ReceiveShowPageEvent {
type: WebviewReceiveEventType.ShowPage
pageData: WebviewPage
}
2 changes: 2 additions & 0 deletions src/api/sendEvent/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { SendJumpToCodeEvent } from './jumpToCode'
export { SendLoginEvent } from './login'
Loading

0 comments on commit a39be82

Please sign in to comment.