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
d426f89c
Commit
d426f89c
authored
Jan 18, 2024
by
Steven
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: add time filter to timeline
parent
7de3de56
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
88 additions
and
27 deletions
+88
-27
memo_service.go
api/v2/memo_service.go
+55
-23
memo.go
store/db/mysql/memo.go
+6
-0
memo.go
store/db/postgres/memo.go
+6
-0
memo.go
store/db/sqlite/memo.go
+6
-0
memo.go
store/memo.go
+2
-0
ActivityCalendar.tsx
web/src/components/ActivityCalendar.tsx
+3
-1
Timeline.tsx
web/src/pages/Timeline.tsx
+10
-3
No files found.
api/v2/memo_service.go
View file @
d426f89c
...
...
@@ -105,11 +105,27 @@ func (s *APIV2Service) ListMemos(ctx context.Context, request *apiv2pb.ListMemos
if
filter
.
OrderByPinned
{
memoFind
.
OrderByPinned
=
filter
.
OrderByPinned
}
if
filter
.
CreatedTsBefore
!=
nil
{
memoFind
.
CreatedTsBefore
=
filter
.
CreatedTsBefore
if
filter
.
DisplayTimeAfter
!=
nil
{
displayWithUpdatedTs
,
err
:=
s
.
getMemoDisplayWithUpdatedTsSettingValue
(
ctx
)
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
"failed to get memo display with updated ts setting value"
)
}
if
displayWithUpdatedTs
{
memoFind
.
UpdatedTsAfter
=
filter
.
DisplayTimeAfter
}
else
{
memoFind
.
CreatedTsAfter
=
filter
.
DisplayTimeAfter
}
}
if
filter
.
CreatedTsAfter
!=
nil
{
memoFind
.
CreatedTsAfter
=
filter
.
CreatedTsAfter
if
filter
.
DisplayTimeBefore
!=
nil
{
displayWithUpdatedTs
,
err
:=
s
.
getMemoDisplayWithUpdatedTsSettingValue
(
ctx
)
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
"failed to get memo display with updated ts setting value"
)
}
if
displayWithUpdatedTs
{
memoFind
.
UpdatedTsBefore
=
filter
.
DisplayTimeBefore
}
else
{
memoFind
.
CreatedTsBefore
=
filter
.
DisplayTimeBefore
}
}
if
filter
.
Creator
!=
nil
{
username
,
err
:=
ExtractUsernameFromName
(
*
filter
.
Creator
)
...
...
@@ -463,11 +479,27 @@ func (s *APIV2Service) GetUserMemosStats(ctx context.Context, request *apiv2pb.G
if
filter
.
OrderByPinned
{
memoFind
.
OrderByPinned
=
filter
.
OrderByPinned
}
if
filter
.
CreatedTsBefore
!=
nil
{
memoFind
.
CreatedTsBefore
=
filter
.
CreatedTsBefore
if
filter
.
DisplayTimeAfter
!=
nil
{
displayWithUpdatedTs
,
err
:=
s
.
getMemoDisplayWithUpdatedTsSettingValue
(
ctx
)
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
"failed to get memo display with updated ts setting value"
)
}
if
displayWithUpdatedTs
{
memoFind
.
UpdatedTsAfter
=
filter
.
DisplayTimeAfter
}
else
{
memoFind
.
CreatedTsAfter
=
filter
.
DisplayTimeAfter
}
}
if
filter
.
CreatedTsAfter
!=
nil
{
memoFind
.
CreatedTsAfter
=
filter
.
CreatedTsAfter
if
filter
.
DisplayTimeBefore
!=
nil
{
displayWithUpdatedTs
,
err
:=
s
.
getMemoDisplayWithUpdatedTsSettingValue
(
ctx
)
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
"failed to get memo display with updated ts setting value"
)
}
if
displayWithUpdatedTs
{
memoFind
.
UpdatedTsBefore
=
filter
.
DisplayTimeBefore
}
else
{
memoFind
.
CreatedTsBefore
=
filter
.
DisplayTimeBefore
}
}
if
filter
.
RowStatus
!=
nil
{
memoFind
.
RowStatus
=
filter
.
RowStatus
...
...
@@ -590,20 +622,20 @@ var ListMemosFilterCELAttributes = []cel.EnvOption{
cel
.
Variable
(
"content_search"
,
cel
.
ListType
(
cel
.
StringType
)),
cel
.
Variable
(
"visibilities"
,
cel
.
ListType
(
cel
.
StringType
)),
cel
.
Variable
(
"order_by_pinned"
,
cel
.
BoolType
),
cel
.
Variable
(
"
created_ts
_before"
,
cel
.
IntType
),
cel
.
Variable
(
"
created_ts
_after"
,
cel
.
IntType
),
cel
.
Variable
(
"
display_time
_before"
,
cel
.
IntType
),
cel
.
Variable
(
"
display_time
_after"
,
cel
.
IntType
),
cel
.
Variable
(
"creator"
,
cel
.
StringType
),
cel
.
Variable
(
"row_status"
,
cel
.
StringType
),
}
type
ListMemosFilter
struct
{
ContentSearch
[]
string
Visibilities
[]
store
.
Visibility
OrderByPinned
bool
CreatedTs
Before
*
int64
CreatedTs
After
*
int64
Creator
*
string
RowStatus
*
store
.
RowStatus
ContentSearch
[]
string
Visibilities
[]
store
.
Visibility
OrderByPinned
bool
DisplayTime
Before
*
int64
DisplayTime
After
*
int64
Creator
*
string
RowStatus
*
store
.
RowStatus
}
func
parseListMemosFilter
(
expression
string
)
(
*
ListMemosFilter
,
error
)
{
...
...
@@ -646,12 +678,12 @@ func findField(callExpr *expr.Expr_Call, filter *ListMemosFilter) {
}
else
if
idExpr
.
Name
==
"order_by_pinned"
{
value
:=
callExpr
.
Args
[
1
]
.
GetConstExpr
()
.
GetBoolValue
()
filter
.
OrderByPinned
=
value
}
else
if
idExpr
.
Name
==
"
created_ts
_before"
{
createdTs
Before
:=
callExpr
.
Args
[
1
]
.
GetConstExpr
()
.
GetInt64Value
()
filter
.
CreatedTsBefore
=
&
createdTs
Before
}
else
if
idExpr
.
Name
==
"
created_ts
_after"
{
createdTs
After
:=
callExpr
.
Args
[
1
]
.
GetConstExpr
()
.
GetInt64Value
()
filter
.
CreatedTsAfter
=
&
createdTs
After
}
else
if
idExpr
.
Name
==
"
display_time
_before"
{
displayTime
Before
:=
callExpr
.
Args
[
1
]
.
GetConstExpr
()
.
GetInt64Value
()
filter
.
DisplayTimeBefore
=
&
displayTime
Before
}
else
if
idExpr
.
Name
==
"
display_time
_after"
{
displayTime
After
:=
callExpr
.
Args
[
1
]
.
GetConstExpr
()
.
GetInt64Value
()
filter
.
DisplayTimeAfter
=
&
displayTime
After
}
else
if
idExpr
.
Name
==
"creator"
{
creator
:=
callExpr
.
Args
[
1
]
.
GetConstExpr
()
.
GetStringValue
()
filter
.
Creator
=
&
creator
...
...
store/db/mysql/memo.go
View file @
d426f89c
...
...
@@ -55,6 +55,12 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo
if
v
:=
find
.
CreatedTsAfter
;
v
!=
nil
{
where
,
args
=
append
(
where
,
"UNIX_TIMESTAMP(`memo`.`created_ts`) > ?"
),
append
(
args
,
*
v
)
}
if
v
:=
find
.
UpdatedTsBefore
;
v
!=
nil
{
where
,
args
=
append
(
where
,
"UNIX_TIMESTAMP(`memo`.`updated_ts`) < ?"
),
append
(
args
,
*
v
)
}
if
v
:=
find
.
UpdatedTsAfter
;
v
!=
nil
{
where
,
args
=
append
(
where
,
"UNIX_TIMESTAMP(`memo`.`updated_ts`) > ?"
),
append
(
args
,
*
v
)
}
if
v
:=
find
.
ContentSearch
;
len
(
v
)
!=
0
{
for
_
,
s
:=
range
v
{
where
,
args
=
append
(
where
,
"`memo`.`content` LIKE ?"
),
append
(
args
,
"%"
+
s
+
"%"
)
...
...
store/db/postgres/memo.go
View file @
d426f89c
...
...
@@ -46,6 +46,12 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo
if
v
:=
find
.
CreatedTsAfter
;
v
!=
nil
{
where
,
args
=
append
(
where
,
"memo.created_ts > "
+
placeholder
(
len
(
args
)
+
1
)),
append
(
args
,
*
v
)
}
if
v
:=
find
.
UpdatedTsBefore
;
v
!=
nil
{
where
,
args
=
append
(
where
,
"memo.updated_ts < "
+
placeholder
(
len
(
args
)
+
1
)),
append
(
args
,
*
v
)
}
if
v
:=
find
.
UpdatedTsAfter
;
v
!=
nil
{
where
,
args
=
append
(
where
,
"memo.updated_ts > "
+
placeholder
(
len
(
args
)
+
1
)),
append
(
args
,
*
v
)
}
if
v
:=
find
.
ContentSearch
;
len
(
v
)
!=
0
{
for
_
,
s
:=
range
v
{
where
,
args
=
append
(
where
,
"memo.content LIKE "
+
placeholder
(
len
(
args
)
+
1
)),
append
(
args
,
fmt
.
Sprintf
(
"%%%s%%"
,
s
))
...
...
store/db/sqlite/memo.go
View file @
d426f89c
...
...
@@ -45,6 +45,12 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo
if
v
:=
find
.
CreatedTsAfter
;
v
!=
nil
{
where
,
args
=
append
(
where
,
"memo.created_ts > ?"
),
append
(
args
,
*
v
)
}
if
v
:=
find
.
UpdatedTsBefore
;
v
!=
nil
{
where
,
args
=
append
(
where
,
"memo.updated_ts < ?"
),
append
(
args
,
*
v
)
}
if
v
:=
find
.
UpdatedTsAfter
;
v
!=
nil
{
where
,
args
=
append
(
where
,
"memo.updated_ts > ?"
),
append
(
args
,
*
v
)
}
if
v
:=
find
.
ContentSearch
;
len
(
v
)
!=
0
{
for
_
,
s
:=
range
v
{
where
,
args
=
append
(
where
,
"memo.content LIKE ?"
),
append
(
args
,
fmt
.
Sprintf
(
"%%%s%%"
,
s
))
...
...
store/memo.go
View file @
d426f89c
...
...
@@ -54,6 +54,8 @@ type FindMemo struct {
CreatorID
*
int32
CreatedTsAfter
*
int64
CreatedTsBefore
*
int64
UpdatedTsAfter
*
int64
UpdatedTsBefore
*
int64
// Domain specific fields
ContentSearch
[]
string
...
...
web/src/components/ActivityCalendar.tsx
View file @
d426f89c
...
...
@@ -6,6 +6,7 @@ interface Props {
// Format: 2021-1
month
:
string
;
data
:
Record
<
string
,
number
>
;
onClick
?:
(
date
:
string
)
=>
void
;
}
const
getBgColor
=
(
count
:
number
,
maxCount
:
number
)
=>
{
...
...
@@ -26,7 +27,7 @@ const getBgColor = (count: number, maxCount: number) => {
};
const
ActivityCalendar
=
(
props
:
Props
)
=>
{
const
{
month
:
monthStr
,
data
}
=
props
;
const
{
month
:
monthStr
,
data
,
onClick
}
=
props
;
const
year
=
new
Date
(
monthStr
).
getFullYear
();
const
month
=
new
Date
(
monthStr
).
getMonth
()
+
1
;
const
dayInMonth
=
new
Date
(
year
,
month
,
0
).
getDate
();
...
...
@@ -60,6 +61,7 @@ const ActivityCalendar = (props: Props) => {
getBgColor
(
count
,
maxCount
),
isToday
&&
"border-gray-600 dark:!border-gray-400"
)
}
onClick=
{
()
=>
count
&&
onClick
&&
onClick
(
date
)
}
></
div
>
</
Tooltip
>
)
:
(
...
...
web/src/pages/Timeline.tsx
View file @
d426f89c
...
...
@@ -10,7 +10,7 @@ import MemoFilter from "@/components/MemoFilter";
import
MemoView
from
"@/components/MemoView"
;
import
MobileHeader
from
"@/components/MobileHeader"
;
import
{
memoServiceClient
}
from
"@/grpcweb"
;
import
{
DEFAULT_MEMO_LIMIT
}
from
"@/helpers/consts"
;
import
{
D
AILY_TIMESTAMP
,
D
EFAULT_MEMO_LIMIT
}
from
"@/helpers/consts"
;
import
{
getNormalizedTimeString
,
getTimeStampByDate
}
from
"@/helpers/datetime"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
useResponsiveWidth
from
"@/hooks/useResponsiveWidth"
;
...
...
@@ -52,6 +52,7 @@ const Timeline = () => {
const
memoList
=
useMemoList
();
const
filterStore
=
useFilterStore
();
const
[
activityStats
,
setActivityStats
]
=
useState
<
Record
<
string
,
number
>>
({});
const
[
selectedDay
,
setSelectedDay
]
=
useState
<
string
|
undefined
>
();
const
[
isRequesting
,
setIsRequesting
]
=
useState
(
true
);
const
[
isComplete
,
setIsComplete
]
=
useState
(
false
);
const
{
tag
:
tagQuery
,
text
:
textQuery
}
=
filterStore
.
state
;
...
...
@@ -61,7 +62,7 @@ const Timeline = () => {
useEffect
(()
=>
{
memoList
.
reset
();
fetchMemos
();
},
[
tagQuery
,
textQuery
]);
},
[
selectedDay
,
tagQuery
,
textQuery
]);
useEffect
(()
=>
{
(
async
()
=>
{
...
...
@@ -97,6 +98,12 @@ const Timeline = () => {
if
(
contentSearch
.
length
>
0
)
{
filters
.
push
(
`content_search == [
${
contentSearch
.
join
(
", "
)}
]`
);
}
if
(
selectedDay
)
{
const
selectedDateStamp
=
getTimeStampByDate
(
selectedDay
)
+
new
Date
().
getTimezoneOffset
()
*
60
*
1000
;
filters
.
push
(
...[
`display_time_after ==
${
selectedDateStamp
/
1000
}
`
,
`display_time_before ==
${(
selectedDateStamp
+
DAILY_TIMESTAMP
)
/
1000
}
`
]
);
}
setIsRequesting
(
true
);
const
data
=
await
memoStore
.
fetchMemos
({
filter
:
filters
.
join
(
" && "
),
...
...
@@ -143,7 +150,7 @@ const Timeline = () => {
<
span
className=
"opacity-60"
>
{
new
Date
(
group
.
month
).
getFullYear
()
}
</
span
>
<
span
className=
"text-xs opacity-40"
>
Total:
{
sum
(
Object
.
values
(
group
.
data
))
}
</
span
>
</
div
>
<
ActivityCalendar
month=
{
group
.
month
}
data=
{
group
.
data
}
/>
<
ActivityCalendar
month=
{
group
.
month
}
data=
{
group
.
data
}
onClick=
{
(
date
)
=>
setSelectedDay
(
date
)
}
/>
</
div
>
<
div
className=
{
classNames
(
"flex flex-col justify-start items-start"
,
md
?
"w-[calc(100%-8rem)]"
:
"w-full"
)
}
>
...
...
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