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
feefaabc
Commit
feefaabc
authored
Dec 22, 2023
by
Steven
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: update heatmap click handler
parent
29b540ad
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
25 additions
and
64 deletions
+25
-64
Tag.tsx
web/src/components/MemoContent/Tag.tsx
+3
-1
MemoFilter.tsx
web/src/components/MemoFilter.tsx
+2
-19
MemoView.tsx
web/src/components/MemoView.tsx
+1
-1
UsageHeatMap.tsx
web/src/components/UsageHeatMap.tsx
+4
-15
Timeline.tsx
web/src/pages/Timeline.tsx
+9
-1
UserProfile.tsx
web/src/pages/UserProfile.tsx
+6
-6
filter.ts
web/src/store/module/filter.ts
+0
-15
filter.ts
web/src/store/reducer/filter.ts
+0
-6
No files found.
web/src/components/MemoContent/Tag.tsx
View file @
feefaabc
...
@@ -3,7 +3,9 @@ interface Props {
...
@@ -3,7 +3,9 @@ interface Props {
}
}
const
Tag
:
React
.
FC
<
Props
>
=
({
content
}:
Props
)
=>
{
const
Tag
:
React
.
FC
<
Props
>
=
({
content
}:
Props
)
=>
{
return
<
span
className=
"inline-block w-auto text-blue-600 dark:text-blue-400"
>
#
{
content
}
</
span
>;
return
(
<
span
className=
"tag-container cursor-pointer inline-block w-auto text-blue-600 dark:text-blue-400 hover:opacity-80"
>
#
{
content
}
</
span
>
);
};
};
export
default
Tag
;
export
default
Tag
;
web/src/components/MemoFilter.tsx
View file @
feefaabc
import
{
useEffect
}
from
"react"
;
import
{
useEffect
}
from
"react"
;
import
{
useLocation
}
from
"react-router-dom"
;
import
{
useLocation
}
from
"react-router-dom"
;
import
{
getDateString
}
from
"@/helpers/datetime"
;
import
{
useFilterStore
}
from
"@/store/module"
;
import
{
useFilterStore
}
from
"@/store/module"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
Icon
from
"./Icon"
;
import
Icon
from
"./Icon"
;
...
@@ -10,8 +9,8 @@ const MemoFilter = () => {
...
@@ -10,8 +9,8 @@ const MemoFilter = () => {
const
location
=
useLocation
();
const
location
=
useLocation
();
const
filterStore
=
useFilterStore
();
const
filterStore
=
useFilterStore
();
const
filter
=
filterStore
.
state
;
const
filter
=
filterStore
.
state
;
const
{
tag
:
tagQuery
,
duration
,
text
:
textQuery
,
visibility
}
=
filter
;
const
{
tag
:
tagQuery
,
text
:
textQuery
,
visibility
}
=
filter
;
const
showFilter
=
Boolean
(
tagQuery
||
(
duration
&&
duration
.
from
<
duration
.
to
)
||
textQuery
||
visibility
);
const
showFilter
=
Boolean
(
tagQuery
||
textQuery
||
visibility
);
useEffect
(()
=>
{
useEffect
(()
=>
{
filterStore
.
clearFilter
();
filterStore
.
clearFilter
();
...
@@ -48,22 +47,6 @@ const MemoFilter = () => {
...
@@ -48,22 +47,6 @@ const MemoFilter = () => {
<
Icon
.
Eye
className=
"w-4 h-auto mr-1 text-gray-500 dark:text-gray-400"
/>
{
visibility
}
<
Icon
.
Eye
className=
"w-4 h-auto mr-1 text-gray-500 dark:text-gray-400"
/>
{
visibility
}
<
Icon
.
X
className=
"w-4 h-auto ml-1 opacity-40"
/>
<
Icon
.
X
className=
"w-4 h-auto ml-1 opacity-40"
/>
</
div
>
</
div
>
{
duration
&&
duration
.
from
<
duration
.
to
?
(
<
div
className=
"max-w-xs flex flex-row justify-start items-center px-2 mr-2 cursor-pointer dark:text-gray-300 bg-gray-200 dark:bg-zinc-700 rounded whitespace-nowrap truncate hover:line-through"
onClick=
{
()
=>
{
filterStore
.
setFromAndToFilter
();
}
}
>
<
Icon
.
Calendar
className=
"w-4 h-auto mr-1 text-gray-500 dark:text-gray-400"
/>
{
t
(
"common.filter-period"
,
{
from
:
getDateString
(
duration
.
from
),
to
:
getDateString
(
duration
.
to
),
interpolation
:
{
escapeValue
:
false
},
})
}
<
Icon
.
X
className=
"w-4 h-auto ml-1 opacity-40"
/>
</
div
>
)
:
null
}
<
div
<
div
className=
{
className=
{
"max-w-xs flex flex-row justify-start items-center px-2 mr-2 cursor-pointer dark:text-gray-300 bg-gray-200 dark:bg-zinc-700 rounded whitespace-nowrap truncate hover:line-through "
+
"max-w-xs flex flex-row justify-start items-center px-2 mr-2 cursor-pointer dark:text-gray-300 bg-gray-200 dark:bg-zinc-700 rounded whitespace-nowrap truncate hover:line-through "
+
...
...
web/src/components/MemoView.tsx
View file @
feefaabc
...
@@ -202,7 +202,7 @@ const MemoView: React.FC<Props> = (props: Props) => {
...
@@ -202,7 +202,7 @@ const MemoView: React.FC<Props> = (props: Props) => {
const
handleMemoContentClick
=
async
(
e
:
React
.
MouseEvent
)
=>
{
const
handleMemoContentClick
=
async
(
e
:
React
.
MouseEvent
)
=>
{
const
targetEl
=
e
.
target
as
HTMLElement
;
const
targetEl
=
e
.
target
as
HTMLElement
;
if
(
targetEl
.
class
Name
===
"tag-span"
)
{
if
(
targetEl
.
class
List
.
contains
(
"tag-container"
)
)
{
const
tagName
=
targetEl
.
innerText
.
slice
(
1
);
const
tagName
=
targetEl
.
innerText
.
slice
(
1
);
const
currTagQuery
=
filterStore
.
getState
().
tag
;
const
currTagQuery
=
filterStore
.
getState
().
tag
;
if
(
currTagQuery
===
tagName
)
{
if
(
currTagQuery
===
tagName
)
{
...
...
web/src/components/UsageHeatMap.tsx
View file @
feefaabc
...
@@ -4,10 +4,10 @@ import { DAILY_TIMESTAMP } from "@/helpers/consts";
...
@@ -4,10 +4,10 @@ import { DAILY_TIMESTAMP } from "@/helpers/consts";
import
{
getDateStampByDate
,
getDateString
,
getTimeStampByDate
}
from
"@/helpers/datetime"
;
import
{
getDateStampByDate
,
getDateString
,
getTimeStampByDate
}
from
"@/helpers/datetime"
;
import
*
as
utils
from
"@/helpers/utils"
;
import
*
as
utils
from
"@/helpers/utils"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
useNavigateTo
from
"@/hooks/useNavigateTo"
;
import
{
useGlobalStore
}
from
"@/store/module"
;
import
{
useGlobalStore
}
from
"@/store/module"
;
import
{
useUserV1Store
,
extractUsernameFromName
,
useMemoV1Store
}
from
"@/store/v1"
;
import
{
useUserV1Store
,
extractUsernameFromName
,
useMemoV1Store
}
from
"@/store/v1"
;
import
{
useTranslate
,
Translations
}
from
"@/utils/i18n"
;
import
{
useTranslate
,
Translations
}
from
"@/utils/i18n"
;
import
{
useFilterStore
}
from
"../store/module"
;
import
"@/less/usage-heat-map.less"
;
import
"@/less/usage-heat-map.less"
;
const
tableConfig
=
{
const
tableConfig
=
{
...
@@ -33,7 +33,7 @@ interface DailyUsageStat {
...
@@ -33,7 +33,7 @@ interface DailyUsageStat {
const
UsageHeatMap
=
()
=>
{
const
UsageHeatMap
=
()
=>
{
const
t
=
useTranslate
();
const
t
=
useTranslate
();
const
filterStore
=
useFilterStore
();
const
navigateTo
=
useNavigateTo
();
const
userV1Store
=
useUserV1Store
();
const
userV1Store
=
useUserV1Store
();
const
user
=
useCurrentUser
();
const
user
=
useCurrentUser
();
const
memoStore
=
useMemoV1Store
();
const
memoStore
=
useMemoV1Store
();
...
@@ -48,7 +48,6 @@ const UsageHeatMap = () => {
...
@@ -48,7 +48,6 @@ const UsageHeatMap = () => {
const
[
memoAmount
,
setMemoAmount
]
=
useState
(
0
);
const
[
memoAmount
,
setMemoAmount
]
=
useState
(
0
);
const
[
createdDays
,
setCreatedDays
]
=
useState
(
0
);
const
[
createdDays
,
setCreatedDays
]
=
useState
(
0
);
const
[
allStat
,
setAllStat
]
=
useState
<
DailyUsageStat
[]
>
(
getInitialUsageStat
(
usedDaysAmount
,
beginDayTimestamp
));
const
[
allStat
,
setAllStat
]
=
useState
<
DailyUsageStat
[]
>
(
getInitialUsageStat
(
usedDaysAmount
,
beginDayTimestamp
));
const
[
currentStat
,
setCurrentStat
]
=
useState
<
DailyUsageStat
|
null
>
(
null
);
const
containerElRef
=
useRef
<
HTMLDivElement
>
(
null
);
const
containerElRef
=
useRef
<
HTMLDivElement
>
(
null
);
const
memos
=
Array
.
from
(
memoStore
.
getState
().
memoById
.
values
());
const
memos
=
Array
.
from
(
memoStore
.
getState
().
memoById
.
values
());
...
@@ -108,13 +107,7 @@ const UsageHeatMap = () => {
...
@@ -108,13 +107,7 @@ const UsageHeatMap = () => {
},
[]);
},
[]);
const
handleUsageStatItemClick
=
useCallback
((
item
:
DailyUsageStat
)
=>
{
const
handleUsageStatItemClick
=
useCallback
((
item
:
DailyUsageStat
)
=>
{
if
(
filterStore
.
getState
().
duration
?.
from
===
item
.
timestamp
)
{
navigateTo
(
`/timeline?timestamp=
${
item
.
timestamp
}
`
);
filterStore
.
setFromAndToFilter
();
setCurrentStat
(
null
);
}
else
if
(
item
.
count
>
0
)
{
filterStore
.
setFromAndToFilter
(
item
.
timestamp
,
item
.
timestamp
+
DAILY_TIMESTAMP
);
setCurrentStat
(
item
);
}
},
[]);
},
[]);
// This interpolation is not being used because of the current styling,
// This interpolation is not being used because of the current styling,
...
@@ -146,11 +139,7 @@ const UsageHeatMap = () => {
...
@@ -146,11 +139,7 @@ const UsageHeatMap = () => {
onMouseLeave=
{
handleUsageStatItemMouseLeave
}
onMouseLeave=
{
handleUsageStatItemMouseLeave
}
onClick=
{
()
=>
handleUsageStatItemClick
(
v
)
}
onClick=
{
()
=>
handleUsageStatItemClick
(
v
)
}
>
>
<
span
<
span
className=
{
`stat-container ${colorLevel} ${todayTimeStamp === v.timestamp ? "today" : ""}`
}
></
span
>
className=
{
`stat-container ${colorLevel} ${currentStat === v ? "current" : ""} ${
todayTimeStamp === v.timestamp ? "today" : ""
}`
}
></
span
>
</
div
>
</
div
>
);
);
})
}
})
}
...
...
web/src/pages/Timeline.tsx
View file @
feefaabc
import
{
Button
}
from
"@mui/joy"
;
import
{
Button
}
from
"@mui/joy"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useSearchParams
}
from
"react-router-dom"
;
import
useToggle
from
"react-use/lib/useToggle"
;
import
useToggle
from
"react-use/lib/useToggle"
;
import
Empty
from
"@/components/Empty"
;
import
Empty
from
"@/components/Empty"
;
import
Icon
from
"@/components/Icon"
;
import
Icon
from
"@/components/Icon"
;
...
@@ -15,15 +16,22 @@ import { useTranslate } from "@/utils/i18n";
...
@@ -15,15 +16,22 @@ import { useTranslate } from "@/utils/i18n";
const
Timeline
=
()
=>
{
const
Timeline
=
()
=>
{
const
t
=
useTranslate
();
const
t
=
useTranslate
();
const
[
searchParams
,
setSearchParams
]
=
useSearchParams
();
const
user
=
useCurrentUser
();
const
user
=
useCurrentUser
();
const
memoStore
=
useMemoV1Store
();
const
memoStore
=
useMemoV1Store
();
const
memoList
=
useMemoList
();
const
memoList
=
useMemoList
();
const
currentDateStamp
=
getDateStampByDate
(
getNormalizedDateString
())
as
number
;
const
currentDateStamp
=
getDateStampByDate
(
getNormalizedDateString
())
as
number
;
const
[
selectedDateStamp
,
setSelectedDateStamp
]
=
useState
<
number
>
(
currentDateStamp
as
number
);
const
[
selectedDateStamp
,
setSelectedDateStamp
]
=
useState
<
number
>
(
(
searchParams
.
get
(
"timestamp"
)
?
Number
(
searchParams
.
get
(
"timestamp"
))
:
currentDateStamp
)
as
number
);
const
[
isRequesting
,
setIsRequesting
]
=
useState
(
true
);
const
[
isRequesting
,
setIsRequesting
]
=
useState
(
true
);
const
[
showDatePicker
,
toggleShowDatePicker
]
=
useToggle
(
false
);
const
[
showDatePicker
,
toggleShowDatePicker
]
=
useToggle
(
false
);
const
sortedMemos
=
memoList
.
value
.
sort
((
a
,
b
)
=>
getTimeStampByDate
(
a
.
createTime
)
-
getTimeStampByDate
(
b
.
createTime
));
const
sortedMemos
=
memoList
.
value
.
sort
((
a
,
b
)
=>
getTimeStampByDate
(
a
.
createTime
)
-
getTimeStampByDate
(
b
.
createTime
));
useEffect
(()
=>
{
setSearchParams
();
},
[]);
useEffect
(()
=>
{
useEffect
(()
=>
{
memoList
.
reset
();
memoList
.
reset
();
fetchMemos
();
fetchMemos
();
...
...
web/src/pages/UserProfile.tsx
View file @
feefaabc
...
@@ -48,16 +48,16 @@ const UserProfile = () => {
...
@@ -48,16 +48,16 @@ const UserProfile = () => {
},
[
params
.
username
]);
},
[
params
.
username
]);
useEffect
(()
=>
{
useEffect
(()
=>
{
memoList
.
reset
();
fetchMemos
();
},
[
tagQuery
,
textQuery
]);
const
fetchMemos
=
async
()
=>
{
if
(
!
user
)
{
if
(
!
user
)
{
return
;
return
;
}
}
const
filters
=
[
`creator == "
${
user
.
name
}
"`
,
`row_status == "NORMAL"`
];
memoList
.
reset
();
fetchMemos
();
},
[
user
,
tagQuery
,
textQuery
]);
const
fetchMemos
=
async
()
=>
{
const
filters
=
[
`creator == "
${
user
!
.
name
}
"`
,
`row_status == "NORMAL"`
,
`order_by_pinned == true`
];
const
contentSearch
:
string
[]
=
[];
const
contentSearch
:
string
[]
=
[];
if
(
tagQuery
)
{
if
(
tagQuery
)
{
contentSearch
.
push
(
`"#
${
tagQuery
}
"`
);
contentSearch
.
push
(
`"#
${
tagQuery
}
"`
);
...
...
web/src/store/module/filter.ts
View file @
feefaabc
...
@@ -16,7 +16,6 @@ export const useFilterStore = () => {
...
@@ -16,7 +16,6 @@ export const useFilterStore = () => {
store
.
dispatch
(
store
.
dispatch
(
setFilter
({
setFilter
({
tag
:
undefined
,
tag
:
undefined
,
duration
:
undefined
,
text
:
undefined
,
text
:
undefined
,
visibility
:
undefined
,
visibility
:
undefined
,
})
})
...
@@ -36,20 +35,6 @@ export const useFilterStore = () => {
...
@@ -36,20 +35,6 @@ export const useFilterStore = () => {
})
})
);
);
},
},
setFromAndToFilter
:
(
from
?:
number
,
to
?:
number
)
=>
{
let
duration
=
undefined
;
if
(
from
&&
to
&&
from
<
to
)
{
duration
=
{
from
,
to
,
};
}
store
.
dispatch
(
setFilter
({
duration
,
})
);
},
setMemoVisibilityFilter
:
(
visibility
?:
Visibility
)
=>
{
setMemoVisibilityFilter
:
(
visibility
?:
Visibility
)
=>
{
store
.
dispatch
(
store
.
dispatch
(
setFilter
({
setFilter
({
...
...
web/src/store/reducer/filter.ts
View file @
feefaabc
import
{
createSlice
,
PayloadAction
}
from
"@reduxjs/toolkit"
;
import
{
createSlice
,
PayloadAction
}
from
"@reduxjs/toolkit"
;
interface
Duration
{
from
:
number
;
to
:
number
;
}
interface
State
{
interface
State
{
tag
?:
string
;
tag
?:
string
;
duration
?:
Duration
;
text
?:
string
;
text
?:
string
;
visibility
?:
Visibility
;
visibility
?:
Visibility
;
}
}
...
...
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