Skip to content

Commit 3e96212

Browse files
committed
Merge branch '482-ui-exit-if-token-is-incorrect' into 'master'
feat(ui): exit if token is incorrect; add exit button (#482) Closes #482 See merge request postgres-ai/database-lab!678
2 parents c14dc9f + dc1ec5f commit 3e96212

File tree

5 files changed

+138
-59
lines changed

5 files changed

+138
-59
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { Modal } from '@postgres.ai/shared/components/Modal'
2+
import { Text } from '@postgres.ai/shared/components/Text'
3+
import { SimpleModalControls } from '@postgres.ai/shared/components/SimpleModalControls'
4+
5+
export const SignOutModal = ({
6+
handleSignOut,
7+
onClose,
8+
isOpen,
9+
}: {
10+
handleSignOut: () => void
11+
onClose: () => void
12+
isOpen: boolean
13+
}) => {
14+
return (
15+
<Modal title={'Sign out'} onClose={onClose} isOpen={isOpen}>
16+
<Text>
17+
Are you sure you want to sign out? You will be redirected to the login
18+
page.
19+
</Text>
20+
<SimpleModalControls
21+
items={[
22+
{
23+
text: 'Cancel',
24+
onClick: onClose,
25+
},
26+
{
27+
text: 'Sign out',
28+
variant: 'primary',
29+
onClick: handleSignOut,
30+
},
31+
]}
32+
/>
33+
</Modal>
34+
)
35+
}
Lines changed: 16 additions & 0 deletions
Loading

ui/packages/ce/src/App/Menu/index.tsx

Lines changed: 85 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@ import { observer } from 'mobx-react-lite'
44

55
import { linksConfig } from '@postgres.ai/shared/config/links'
66
import { Button } from '@postgres.ai/shared/components/MenuButton'
7+
import { ROUTES } from 'config/routes'
78

9+
import { SignOutModal } from './SignOutModal'
810
import { Header } from './Header'
911
import githubIconUrl from './icons/github.svg'
1012
import docsIconUrl from './icons/docs.svg'
13+
import exitIcon from './icons/exit-icon.svg'
1114
import discussionIconUrl from './icons/discussion.svg'
1215
import arrowLeftIconUrl from './icons/arrow-left.svg'
1316
import arrowRightIconUrl from './icons/arrow-right.svg'
@@ -17,66 +20,90 @@ import styles from './styles.module.scss'
1720
const LAPTOP_WIDTH_PX = 1024
1821
const SIDEBAR_COLLAPSED_PARAM = 'sidebarMenuCollapsed'
1922

20-
export const Menu = observer(() => {
21-
const [isCollapsed, setIsCollapsed] = useState(
22-
() =>
23-
window.innerWidth < LAPTOP_WIDTH_PX ||
24-
localStorage.getItem(SIDEBAR_COLLAPSED_PARAM) === '1',
25-
)
23+
export const Menu = observer(
24+
({ isValidToken }: { isValidToken: boolean | undefined }) => {
25+
const [isOpen, setIsOpen] = useState(false)
26+
const [isCollapsed, setIsCollapsed] = useState(
27+
() =>
28+
window.innerWidth < LAPTOP_WIDTH_PX ||
29+
localStorage.getItem(SIDEBAR_COLLAPSED_PARAM) === '1',
30+
)
2631

27-
const handleClick = () => {
28-
setIsCollapsed(!isCollapsed)
29-
localStorage.setItem(SIDEBAR_COLLAPSED_PARAM, isCollapsed ? '0' : '1')
30-
}
32+
const handleCollapse = () => {
33+
setIsCollapsed(!isCollapsed)
34+
localStorage.setItem(SIDEBAR_COLLAPSED_PARAM, isCollapsed ? '0' : '1')
35+
}
3136

32-
return (
33-
<div className={cn(styles.root, isCollapsed && styles.collapsed)}>
34-
<div className={styles.content}>
35-
<Header isCollapsed={isCollapsed} />
36-
</div>
37-
<footer className={styles.footer}>
38-
<Button
39-
type="gateway-link"
40-
href={linksConfig.github}
41-
icon={<img src={githubIconUrl} alt="GitHub" />}
42-
isCollapsed={isCollapsed}
43-
>
44-
Star us on GitHub
45-
</Button>
37+
const handleSignOut = () => {
38+
localStorage.removeItem('token')
39+
window.location.href = ROUTES.AUTH.path
40+
}
4641

47-
<Button
48-
type="gateway-link"
49-
href={linksConfig.docs}
50-
icon={<img src={docsIconUrl} alt="Documentation" />}
51-
isCollapsed={isCollapsed}
52-
>
53-
Documentation
54-
</Button>
42+
return (
43+
<div className={cn(styles.root, isCollapsed && styles.collapsed)}>
44+
<div className={styles.content}>
45+
<Header isCollapsed={isCollapsed} />
46+
</div>
47+
<footer className={styles.footer}>
48+
<Button
49+
type="gateway-link"
50+
href={linksConfig.github}
51+
icon={<img src={githubIconUrl} alt="GitHub" />}
52+
isCollapsed={isCollapsed}
53+
>
54+
Star us on GitHub
55+
</Button>
5556

56-
<Button
57-
type="gateway-link"
58-
href={linksConfig.support}
59-
className={styles.supportBtn}
60-
icon={<img src={discussionIconUrl} alt="Discussion" />}
61-
isCollapsed={isCollapsed}
62-
>
63-
Ask support
64-
</Button>
57+
<Button
58+
type="gateway-link"
59+
href={linksConfig.docs}
60+
icon={<img src={docsIconUrl} alt="Documentation" />}
61+
isCollapsed={isCollapsed}
62+
>
63+
Documentation
64+
</Button>
6565

66-
<Button
67-
className={styles.collapseBtn}
68-
onClick={handleClick}
69-
isCollapsed={isCollapsed}
70-
icon={
71-
<img
72-
src={isCollapsed ? arrowRightIconUrl : arrowLeftIconUrl}
73-
alt={isCollapsed ? 'Arrow right' : 'Arrow left'}
74-
/>
75-
}
76-
>
77-
Collapse
78-
</Button>
79-
</footer>
80-
</div>
81-
)
82-
})
66+
<Button
67+
type="gateway-link"
68+
href={linksConfig.support}
69+
className={styles.supportBtn}
70+
icon={<img src={discussionIconUrl} alt="Discussion" />}
71+
isCollapsed={isCollapsed}
72+
>
73+
Ask support
74+
</Button>
75+
{isValidToken && (
76+
<Button
77+
type="button"
78+
onClick={() => setIsOpen(true)}
79+
icon={<img src={exitIcon} alt="Profile" />}
80+
isCollapsed={isCollapsed}
81+
>
82+
Sign out
83+
</Button>
84+
)}
85+
<Button
86+
className={styles.collapseBtn}
87+
onClick={handleCollapse}
88+
isCollapsed={isCollapsed}
89+
icon={
90+
<img
91+
src={isCollapsed ? arrowRightIconUrl : arrowLeftIconUrl}
92+
alt={isCollapsed ? 'Arrow right' : 'Arrow left'}
93+
/>
94+
}
95+
>
96+
Collapse
97+
</Button>
98+
</footer>
99+
{isOpen && (
100+
<SignOutModal
101+
handleSignOut={handleSignOut}
102+
onClose={() => setIsOpen(false)}
103+
isOpen={isOpen}
104+
/>
105+
)}
106+
</div>
107+
)
108+
},
109+
)

ui/packages/ce/src/App/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export const App = observer(() => {
2222

2323
return (
2424
<BrowserRouter>
25-
<Layout menu={<Menu />}>
25+
<Layout menu={<Menu isValidToken={appStore.isValidAuthToken} />}>
2626
{appStore.isValidAuthToken ? (
2727
<Switch>
2828
<Route path={ROUTES.INSTANCE.path}>

ui/packages/ce/src/helpers/request.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export const request = async (path: string, options?: RequestOptions) => {
2020

2121
if (response.status === 401) {
2222
appStore.setIsInvalidAuthToken()
23+
localStorage.removeAuthToken()
2324
} else {
2425
appStore.setIsValidAuthToken()
2526
}

0 commit comments

Comments
 (0)