Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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)

AltStyle によって変換されたページ (->オリジナル) /