Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
canifa_note
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Vũ Hoàng Anh
canifa_note
Commits
370054e0
Commit
370054e0
authored
Jan 21, 2024
by
Steven
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: implement collapsed navigation
parent
fae0b4e9
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
71 additions
and
48 deletions
+71
-48
index.tsx
web/src/components/MemoEditor/index.tsx
+2
-2
Navigation.tsx
web/src/components/Navigation.tsx
+25
-16
UserBanner.tsx
web/src/components/UserBanner.tsx
+27
-27
Root.tsx
web/src/layouts/Root.tsx
+17
-3
No files found.
web/src/components/MemoEditor/index.tsx
View file @
370054e0
...
...
@@ -381,6 +381,8 @@ const MemoEditor = (props: Props) => {
onFocus=
{
handleEditorFocus
}
>
<
Editor
ref=
{
editorRef
}
{
...
editorConfig
}
/>
<
ResourceListView
resourceList=
{
state
.
resourceList
}
setResourceList=
{
handleSetResourceList
}
/>
<
RelationListView
relationList=
{
referenceRelations
}
setRelationList=
{
handleSetRelationList
}
/>
<
div
className=
"relative w-full flex flex-row justify-between items-center pt-2"
onFocus=
{
(
e
)
=>
e
.
stopPropagation
()
}
>
<
div
className=
"flex flex-row justify-start items-center opacity-80"
>
<
TagSelector
editorRef=
{
editorRef
}
/>
...
...
@@ -393,8 +395,6 @@ const MemoEditor = (props: Props) => {
</
IconButton
>
</
div
>
</
div
>
<
ResourceListView
resourceList=
{
state
.
resourceList
}
setResourceList=
{
handleSetResourceList
}
/>
<
RelationListView
relationList=
{
referenceRelations
}
setRelationList=
{
handleSetRelationList
}
/>
<
Divider
className=
"!mt-2"
/>
<
div
className=
"w-full flex flex-row justify-between items-center py-3 dark:border-t-zinc-500"
>
<
div
className=
"relative flex flex-row justify-start items-center"
onFocus=
{
(
e
)
=>
e
.
stopPropagation
()
}
>
...
...
web/src/components/Navigation.tsx
View file @
370054e0
import
{
Tooltip
}
from
"@mui/joy"
;
import
classNames
from
"classnames"
;
import
{
useEffect
}
from
"react"
;
import
{
NavLink
}
from
"react-router-dom"
;
...
...
@@ -16,10 +17,12 @@ interface NavLinkItem {
}
interface
Props
{
collapsed
?:
boolean
;
className
?:
string
;
}
const
Navigation
=
(
props
:
Props
)
=>
{
const
{
collapsed
,
className
}
=
props
;
const
t
=
useTranslate
();
const
user
=
useCurrentUser
();
const
inboxStore
=
useInboxStore
();
...
...
@@ -45,31 +48,31 @@ const Navigation = (props: Props) => {
id
:
"header-home"
,
path
:
"/"
,
title
:
t
(
"common.home"
),
icon
:
<
Icon
.
Home
className=
"
mr-3
w-6 h-auto opacity-70"
/>,
icon
:
<
Icon
.
Home
className=
"w-6 h-auto opacity-70"
/>,
};
const
timelineNavLink
:
NavLinkItem
=
{
id
:
"header-timeline"
,
path
:
"/timeline"
,
title
:
t
(
"timeline.title"
),
icon
:
<
Icon
.
GanttChartSquare
className=
"
mr-3
w-6 h-auto opacity-70"
/>,
icon
:
<
Icon
.
GanttChartSquare
className=
"w-6 h-auto opacity-70"
/>,
};
const
resourcesNavLink
:
NavLinkItem
=
{
id
:
"header-resources"
,
path
:
"/resources"
,
title
:
t
(
"common.resources"
),
icon
:
<
Icon
.
Paperclip
className=
"
mr-3
w-6 h-auto opacity-70"
/>,
icon
:
<
Icon
.
Paperclip
className=
"w-6 h-auto opacity-70"
/>,
};
const
exploreNavLink
:
NavLinkItem
=
{
id
:
"header-explore"
,
path
:
"/explore"
,
title
:
t
(
"common.explore"
),
icon
:
<
Icon
.
Globe2
className=
"
mr-3
w-6 h-auto opacity-70"
/>,
icon
:
<
Icon
.
Globe2
className=
"w-6 h-auto opacity-70"
/>,
};
const
profileNavLink
:
NavLinkItem
=
{
id
:
"header-profile"
,
path
:
user
?
`/u/
${
encodeURIComponent
(
user
.
username
)}
`
:
""
,
title
:
t
(
"common.profile"
),
icon
:
<
Icon
.
User2
className=
"
mr-3
w-6 h-auto opacity-70"
/>,
icon
:
<
Icon
.
User2
className=
"w-6 h-auto opacity-70"
/>,
};
const
inboxNavLink
:
NavLinkItem
=
{
id
:
"header-inbox"
,
...
...
@@ -78,7 +81,7 @@ const Navigation = (props: Props) => {
icon
:
(
<>
<
div
className=
"relative"
>
<
Icon
.
Bell
className=
"
mr-3
w-6 h-auto opacity-70"
/>
<
Icon
.
Bell
className=
"w-6 h-auto opacity-70"
/>
{
hasUnreadInbox
&&
<
div
className=
"absolute top-0 left-5 w-2 h-2 rounded-full bg-blue-500"
></
div
>
}
</
div
>
</>
...
...
@@ -88,25 +91,25 @@ const Navigation = (props: Props) => {
id
:
"header-archived"
,
path
:
"/archived"
,
title
:
t
(
"common.archived"
),
icon
:
<
Icon
.
Archive
className=
"
mr-3
w-6 h-auto opacity-70"
/>,
icon
:
<
Icon
.
Archive
className=
"w-6 h-auto opacity-70"
/>,
};
const
settingNavLink
:
NavLinkItem
=
{
id
:
"header-setting"
,
path
:
"/setting"
,
title
:
t
(
"common.settings"
),
icon
:
<
Icon
.
Settings
className=
"
mr-3
w-6 h-auto opacity-70"
/>,
icon
:
<
Icon
.
Settings
className=
"w-6 h-auto opacity-70"
/>,
};
const
signInNavLink
:
NavLinkItem
=
{
id
:
"header-auth"
,
path
:
"/auth"
,
title
:
t
(
"common.sign-in"
),
icon
:
<
Icon
.
LogIn
className=
"
mr-3
w-6 h-auto opacity-70"
/>,
icon
:
<
Icon
.
LogIn
className=
"w-6 h-auto opacity-70"
/>,
};
const
aboutNavLink
:
NavLinkItem
=
{
id
:
"header-about"
,
path
:
"/about"
,
title
:
t
(
"common.about"
),
icon
:
<
Icon
.
Smile
className=
"
mr-3
w-6 h-auto opacity-70"
/>,
icon
:
<
Icon
.
Smile
className=
"w-6 h-auto opacity-70"
/>,
};
const
navLinks
:
NavLinkItem
[]
=
user
...
...
@@ -117,16 +120,17 @@ const Navigation = (props: Props) => {
<
header
className=
{
classNames
(
"w-full h-full overflow-auto flex flex-col justify-start items-start py-4 md:pt-6 z-30 hide-scrollbar"
,
props
.
className
className
)
}
>
<
UserBanner
/>
<
UserBanner
collapsed=
{
collapsed
}
/>
<
div
className=
"w-full px-1 py-2 flex flex-col justify-start items-start shrink-0 space-y-2"
>
{
navLinks
.
map
((
navLink
)
=>
(
<
NavLink
className=
{
({
isActive
})
=>
classNames
(
"w-full px-4 pr-5 py-2 rounded-2xl border flex flex-row items-center text-lg text-gray-800 dark:text-gray-300 hover:bg-white hover:border-gray-200 dark:hover:border-zinc-700 dark:hover:bg-zinc-800"
,
"px-2 py-2 rounded-2xl border flex flex-row items-center text-lg text-gray-800 dark:text-gray-300 hover:bg-white hover:border-gray-200 dark:hover:border-zinc-700 dark:hover:bg-zinc-800"
,
collapsed
?
""
:
"w-full px-4"
,
isActive
?
"bg-white drop-shadow-sm dark:bg-zinc-800 border-gray-200 dark:border-zinc-700"
:
"border-transparent"
)
}
...
...
@@ -135,9 +139,14 @@ const Navigation = (props: Props) => {
id=
{
navLink
.
id
}
unstable_viewTransition
>
<>
{
navLink
.
icon
}
{
navLink
.
title
}
</>
{
props
.
collapsed
?
(
<
Tooltip
title=
{
navLink
.
title
}
placement=
"right"
arrow
>
<
div
>
{
navLink
.
icon
}
</
div
>
</
Tooltip
>
)
:
(
navLink
.
icon
)
}
{
!
props
.
collapsed
&&
<
span
className=
"ml-3"
>
{
navLink
.
title
}
</
span
>
}
</
NavLink
>
))
}
</
div
>
...
...
web/src/components/UserBanner.tsx
View file @
370054e0
import
{
Dropdown
,
Menu
,
MenuButton
,
MenuItem
}
from
"@mui/joy"
;
import
classNames
from
"classnames"
;
import
*
as
api
from
"@/helpers/api"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
{
useGlobalStore
}
from
"@/store/module"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
Icon
from
"./Icon"
;
import
UserAvatar
from
"./UserAvatar"
;
import
Dropdown
from
"./kit/Dropdown"
;
const
UserBanner
=
()
=>
{
interface
Props
{
collapsed
?:
boolean
;
}
const
UserBanner
=
(
props
:
Props
)
=>
{
const
{
collapsed
}
=
props
;
const
t
=
useTranslate
();
const
globalStore
=
useGlobalStore
();
const
{
systemStatus
}
=
globalStore
.
state
;
...
...
@@ -20,32 +26,26 @@ const UserBanner = () => {
};
return
(
<
div
className=
"relative w-full h-auto px-1 shrink-0"
>
<
Dropdown
className=
"w-auto inline-flex"
trigger=
{
<
div
className=
"px-3 py-2 max-w-full flex flex-row justify-start items-center cursor-pointer rounded-2xl border border-transparent text-gray-800 dark:text-gray-300 hover:bg-white hover:border-gray-200 dark:hover:border-zinc-700 dark:hover:bg-zinc-800"
>
<
UserAvatar
className=
"shadow shrink-0 mr-2"
avatarUrl=
{
avatarUrl
}
/>
<
span
className=
"text-lg font-medium text-slate-800 dark:text-gray-200 shrink truncate"
>
{
title
}
</
span
>
</
div
>
}
disabled=
{
user
==
undefined
}
actionsClassName=
"min-w-[128px] max-w-full"
positionClassName=
"top-full mt-2"
actions=
{
<>
{
user
!=
undefined
&&
(
<
button
className=
"w-full px-3 truncate text-left leading-10 cursor-pointer rounded flex flex-row justify-start items-center dark:text-gray-200 hover:bg-gray-100 dark:hover:bg-zinc-800"
onClick=
{
handleSignOut
}
<
div
className=
"relative w-auto h-auto px-1 shrink-0"
>
<
Dropdown
>
<
MenuButton
slots=
{
{
root
:
"div"
}
}
>
<
div
className=
{
classNames
(
"py-1 my-1 w-auto flex flex-row justify-start items-center cursor-pointer rounded-2xl border border-transparent text-gray-800 dark:text-gray-300"
,
collapsed
?
"px-1"
:
"px-3"
)
}
>
<
Icon
.
LogOut
className=
"w-5 h-auto mr-1 opacity-60 shrink-0"
/>
<
UserAvatar
className=
"shadow shrink-0"
avatarUrl=
{
avatarUrl
}
/>
{
!
collapsed
&&
<
span
className=
"ml-2 text-lg font-medium text-slate-800 dark:text-gray-200 shrink truncate"
>
{
title
}
</
span
>
}
</
div
>
</
MenuButton
>
<
Menu
placement=
"bottom-start"
>
<
MenuItem
onClick=
{
handleSignOut
}
>
<
Icon
.
LogOut
className=
"w-5 h-auto opacity-60 shrink-0"
/>
<
span
className=
"truncate"
>
{
t
(
"common.sign-out"
)
}
</
span
>
</
button
>
)
}
</>
}
/>
</
MenuItem
>
</
Menu
>
</
Dropdown
>
</
div
>
);
};
...
...
web/src/layouts/Root.tsx
View file @
370054e0
import
classNames
from
"classnames"
;
import
{
Suspense
}
from
"react"
;
import
{
Outlet
}
from
"react-router-dom"
;
import
useLocalStorage
from
"react-use/lib/useLocalStorage"
;
import
Navigation
from
"@/components/Navigation"
;
import
useResponsiveWidth
from
"@/hooks/useResponsiveWidth"
;
import
Loading
from
"@/pages/Loading"
;
function
Root
()
{
const
{
sm
}
=
useResponsiveWidth
();
const
[
collapsed
,
setCollapsed
]
=
useLocalStorage
<
boolean
>
(
"navigation-collapsed"
,
false
);
return
(
<
div
className=
"w-full min-h-full"
>
<
div
className=
"w-full sm:pl-56 md:pl-64 mx-auto flex flex-row justify-center items-start"
>
<
div
className=
{
classNames
(
"w-full transition-all mx-auto flex flex-row justify-center items-start"
,
collapsed
?
"sm:pl-16"
:
"sm:pl-56"
)
}
>
{
sm
&&
(
<
div
className=
"hidden sm:block fixed top-0 left-0 w-56 md:w-64 border-r dark:border-zinc-800 h-full bg-zinc-50 dark:bg-zinc-800 dark:bg-opacity-40 transition-all hover:shadow-xl z-2"
>
<
Navigation
className=
"px-4"
/>
<
div
className=
{
classNames
(
"hidden sm:block fixed top-0 left-0 select-none border-r dark:border-zinc-800 h-full bg-zinc-50 dark:bg-zinc-800 dark:bg-opacity-40 transition-all hover:shadow-xl z-2"
,
collapsed
?
"w-16 px-2"
:
"w-56 px-4"
)
}
onDoubleClick=
{
()
=>
setCollapsed
(
!
collapsed
)
}
>
<
Navigation
collapsed=
{
collapsed
}
/>
</
div
>
)
}
<
main
className=
"w-full h-auto flex-grow shrink flex flex-col justify-start items-center"
>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment