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
1c2998c4
Unverified
Commit
1c2998c4
authored
Oct 21, 2022
by
boojack
Committed by
GitHub
Oct 21, 2022
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat: pagination for memo list (#330)
parent
fc5d5cf2
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
234 additions
and
58 deletions
+234
-58
memo.go
server/memo.go
+50
-0
ArchivedMemo.tsx
web/src/components/ArchivedMemo.tsx
+0
-1
MemoList.tsx
web/src/components/MemoList.tsx
+38
-4
UsageHeatMap.tsx
web/src/components/UsageHeatMap.tsx
+16
-9
UserBanner.tsx
web/src/components/UserBanner.tsx
+13
-1
api.ts
web/src/helpers/api.ts
+20
-2
memo-content.less
web/src/less/memo-content.less
+5
-1
en.json
web/src/locales/en.json
+2
-1
vi.json
web/src/locales/vi.json
+2
-1
zh.json
web/src/locales/zh.json
+2
-1
Explore.tsx
web/src/pages/Explore.tsx
+49
-18
memoService.ts
web/src/services/memoService.ts
+26
-18
memo.ts
web/src/store/modules/memo.ts
+9
-1
memo.d.ts
web/src/types/modules/memo.d.ts
+2
-0
No files found.
server/memo.go
View file @
1c2998c4
...
...
@@ -203,6 +203,56 @@ func (s *Server) registerMemoRoutes(g *echo.Group) {
return
nil
})
g
.
GET
(
"/memo/stats"
,
func
(
c
echo
.
Context
)
error
{
ctx
:=
c
.
Request
()
.
Context
()
normalStatus
:=
api
.
Normal
memoFind
:=
&
api
.
MemoFind
{
RowStatus
:
&
normalStatus
,
}
if
userID
,
err
:=
strconv
.
Atoi
(
c
.
QueryParam
(
"creatorId"
));
err
==
nil
{
memoFind
.
CreatorID
=
&
userID
}
currentUserID
,
ok
:=
c
.
Get
(
getUserIDContextKey
())
.
(
int
)
if
!
ok
{
if
memoFind
.
CreatorID
==
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusBadRequest
,
"Missing user id to find memo"
)
}
memoFind
.
VisibilityList
=
[]
api
.
Visibility
{
api
.
Public
}
}
else
{
if
memoFind
.
CreatorID
==
nil
{
memoFind
.
CreatorID
=
&
currentUserID
}
else
{
memoFind
.
VisibilityList
=
[]
api
.
Visibility
{
api
.
Public
,
api
.
Protected
}
}
}
visibilitListStr
:=
c
.
QueryParam
(
"visibility"
)
if
visibilitListStr
!=
""
{
visibilityList
:=
[]
api
.
Visibility
{}
for
_
,
visibility
:=
range
strings
.
Split
(
visibilitListStr
,
","
)
{
visibilityList
=
append
(
visibilityList
,
api
.
Visibility
(
visibility
))
}
memoFind
.
VisibilityList
=
visibilityList
}
list
,
err
:=
s
.
Store
.
FindMemoList
(
ctx
,
memoFind
)
if
err
!=
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusInternalServerError
,
"Failed to fetch memo list"
)
.
SetInternal
(
err
)
}
displayTsList
:=
[]
int64
{}
for
_
,
memo
:=
range
list
{
displayTsList
=
append
(
displayTsList
,
memo
.
DisplayTs
)
}
c
.
Response
()
.
Header
()
.
Set
(
echo
.
HeaderContentType
,
echo
.
MIMEApplicationJSONCharsetUTF8
)
if
err
:=
json
.
NewEncoder
(
c
.
Response
()
.
Writer
)
.
Encode
(
composeResponse
(
displayTsList
));
err
!=
nil
{
return
echo
.
NewHTTPError
(
http
.
StatusInternalServerError
,
"Failed to encode memo stats response"
)
.
SetInternal
(
err
)
}
return
nil
})
g
.
GET
(
"/memo/all"
,
func
(
c
echo
.
Context
)
error
{
ctx
:=
c
.
Request
()
.
Context
()
memoFind
:=
&
api
.
MemoFind
{}
...
...
web/src/components/ArchivedMemo.tsx
View file @
1c2998c4
...
...
@@ -21,7 +21,6 @@ const ArchivedMemo: React.FC<Props> = (props: Props) => {
if
(
showConfirmDeleteBtn
)
{
try
{
await
memoService
.
deleteMemoById
(
memo
.
id
);
await
memoService
.
fetchMemos
();
}
catch
(
error
:
any
)
{
console
.
error
(
error
);
toastHelper
.
error
(
error
.
response
.
data
.
message
);
...
...
web/src/components/MemoList.tsx
View file @
1c2998c4
import
{
useEffect
}
from
"react"
;
import
{
useEffect
,
useState
}
from
"react"
;
import
{
useTranslation
}
from
"react-i18next"
;
import
{
memoService
,
shortcutService
}
from
"../services"
;
import
{
DEFAULT_MEMO_LIMIT
}
from
"../services/memoService"
;
import
{
useAppSelector
}
from
"../store"
;
import
{
TAG_REG
,
LINK_REG
}
from
"../labs/marked/parser"
;
import
*
as
utils
from
"../helpers/utils"
;
...
...
@@ -14,6 +15,7 @@ const MemoList = () => {
const
query
=
useAppSelector
((
state
)
=>
state
.
location
.
query
);
const
memoDisplayTsOption
=
useAppSelector
((
state
)
=>
state
.
user
.
user
?.
setting
.
memoDisplayTsOption
);
const
{
memos
,
isFetching
}
=
useAppSelector
((
state
)
=>
state
.
memo
);
const
[
isComplete
,
setIsComplete
]
=
useState
<
boolean
>
(
false
);
const
{
tag
:
tagQuery
,
duration
,
type
:
memoType
,
text
:
textQuery
,
shortcutId
}
=
query
??
{};
const
shortcut
=
shortcutId
?
shortcutService
.
getShortcutById
(
shortcutId
)
:
null
;
...
...
@@ -81,8 +83,12 @@ const MemoList = () => {
useEffect(() =
>
{
memoService
.
fetchMemos
()
.
then
(()
=>
{
// do nth
.
then
((
fetchedMemos
)
=>
{
if
(
fetchedMemos
.
length
<
DEFAULT_MEMO_LIMIT
)
{
setIsComplete
(
true
);
}
else
{
setIsComplete
(
false
);
}
})
.
catch
((
error
)
=>
{
console
.
error
(
error
);
...
...
@@ -97,6 +103,20 @@ const MemoList = () => {
}
}
, [query]);
const handleFetchMoreClick = async () =
>
{
try
{
const
fetchedMemos
=
await
memoService
.
fetchMemos
(
DEFAULT_MEMO_LIMIT
,
memos
.
length
);
if
(
fetchedMemos
.
length
<
DEFAULT_MEMO_LIMIT
)
{
setIsComplete
(
true
);
}
else
{
setIsComplete
(
false
);
}
}
catch
(
error
:
any
)
{
console
.
error
(
error
);
toastHelper
.
error
(
error
.
response
.
data
.
message
);
}
}
;
return (
<
div
className=
"memo-list-container"
>
{
sortedMemos
.
map
((
memo
)
=>
(
...
...
@@ -108,7 +128,21 @@ const MemoList = () => {
</
div
>
)
:
(
<
div
className=
"status-text-container"
>
<
p
className=
"status-text"
>
{
sortedMemos
.
length
===
0
?
t
(
"message.no-memos"
)
:
showMemoFilter
?
""
:
t
(
"message.memos-ready"
)
}
</
p
>
<
p
className=
"status-text"
>
{
isComplete
?
(
sortedMemos
.
length
===
0
?
(
t
(
"message.no-memos"
)
)
:
(
t
(
"message.memos-ready"
)
)
)
:
(
<>
<
span
className=
"cursor-pointer hover:text-green-600"
onClick=
{
handleFetchMoreClick
}
>
{
t
(
"memo-list.fetch-more"
)
}
</
span
>
</>
)
}
</
p
>
</
div
>
)
}
</
div
>
...
...
web/src/components/UsageHeatMap.tsx
View file @
1c2998c4
import
{
useCallback
,
useEffect
,
useRef
,
useState
}
from
"react"
;
import
{
useAppSelector
}
from
"../store"
;
import
{
locationService
}
from
"../services"
;
import
{
getMemoStats
}
from
"../helpers/api"
;
import
{
DAILY_TIMESTAMP
}
from
"../helpers/consts"
;
import
*
as
utils
from
"../helpers/utils"
;
import
"../less/usage-heat-map.less"
;
...
...
@@ -39,15 +40,21 @@ const UsageHeatMap = () => {
const
containerElRef
=
useRef
<
HTMLDivElement
>
(
null
);
useEffect
(()
=>
{
const
newStat
:
DailyUsageStat
[]
=
getInitialUsageStat
(
usedDaysAmount
,
beginDayTimestemp
);
for
(
const
m
of
memos
)
{
const
index
=
(
utils
.
getDateStampByDate
(
m
.
displayTs
)
-
beginDayTimestemp
)
/
(
1000
*
3600
*
24
)
-
1
;
if
(
index
>=
0
)
{
newStat
[
index
].
count
+=
1
;
}
}
setAllStat
([...
newStat
]);
},
[
memos
]);
getMemoStats
()
.
then
(({
data
:
{
data
}
})
=>
{
const
newStat
:
DailyUsageStat
[]
=
getInitialUsageStat
(
usedDaysAmount
,
beginDayTimestemp
);
for
(
const
record
of
data
)
{
const
index
=
(
utils
.
getDateStampByDate
(
record
*
1000
)
-
beginDayTimestemp
)
/
(
1000
*
3600
*
24
)
-
1
;
if
(
index
>=
0
)
{
newStat
[
index
].
count
+=
1
;
}
}
setAllStat
([...
newStat
]);
})
.
catch
((
error
)
=>
{
console
.
error
(
error
);
});
},
[
memos
.
length
]);
const
handleUsageStatItemMouseEnter
=
useCallback
((
event
:
React
.
MouseEvent
,
item
:
DailyUsageStat
)
=>
{
const
tempDiv
=
document
.
createElement
(
"div"
);
...
...
web/src/components/UserBanner.tsx
View file @
1c2998c4
import
{
useCallback
,
useEffect
,
useState
}
from
"react"
;
import
{
useTranslation
}
from
"react-i18next"
;
import
{
useNavigate
}
from
"react-router-dom"
;
import
{
getMemoStats
}
from
"../helpers/api"
;
import
*
as
utils
from
"../helpers/utils"
;
import
userService
from
"../services/userService"
;
import
{
locationService
}
from
"../services"
;
...
...
@@ -18,6 +19,7 @@ const UserBanner = () => {
const
{
user
,
owner
}
=
useAppSelector
((
state
)
=>
state
.
user
);
const
{
memos
,
tags
}
=
useAppSelector
((
state
)
=>
state
.
memo
);
const
[
username
,
setUsername
]
=
useState
(
"Memos"
);
const
[
memoAmount
,
setMemoAmount
]
=
useState
(
0
);
const
[
createdDays
,
setCreatedDays
]
=
useState
(
0
);
const
isVisitorMode
=
userService
.
isVisitorMode
();
...
...
@@ -34,6 +36,16 @@ const UserBanner = () => {
}
},
[
isVisitorMode
,
user
,
owner
]);
useEffect
(()
=>
{
getMemoStats
()
.
then
(({
data
:
{
data
}
})
=>
{
setMemoAmount
(
data
.
length
);
})
.
catch
((
error
)
=>
{
console
.
error
(
error
);
});
},
[
memos
]);
const
handleUsernameClick
=
useCallback
(()
=>
{
locationService
.
clearQuery
();
},
[]);
...
...
@@ -109,7 +121,7 @@ const UserBanner = () => {
</
div
>
<
div
className=
"amount-text-container"
>
<
div
className=
"status-text memos-text"
>
<
span
className=
"amount-text"
>
{
memo
s
.
length
}
</
span
>
<
span
className=
"amount-text"
>
{
memo
Amount
}
</
span
>
<
span
className=
"type-text"
>
{
t
(
"amount-text.memo"
)
}
</
span
>
</
div
>
<
div
className=
"status-text tags-text"
>
...
...
web/src/helpers/api.ts
View file @
1c2998c4
...
...
@@ -58,8 +58,16 @@ export function deleteUser(userDelete: UserDelete) {
return
axios
.
delete
(
`/api/user/
${
userDelete
.
id
}
`
);
}
export
function
getAllMemos
()
{
return
axios
.
get
<
ResponseObject
<
Memo
[]
>>
(
"/api/memo/all"
);
export
function
getAllMemos
(
memoFind
?:
MemoFind
)
{
const
queryList
=
[];
if
(
memoFind
?.
offset
)
{
queryList
.
push
(
`offset=
${
memoFind
.
offset
}
`
);
}
if
(
memoFind
?.
limit
)
{
queryList
.
push
(
`limit=
${
memoFind
.
limit
}
`
);
}
return
axios
.
get
<
ResponseObject
<
Memo
[]
>>
(
`/api/memo/all?
${
queryList
.
join
(
"&"
)}
`
);
}
export
function
getMemoList
(
memoFind
?:
MemoFind
)
{
...
...
@@ -70,9 +78,19 @@ export function getMemoList(memoFind?: MemoFind) {
if
(
memoFind
?.
rowStatus
)
{
queryList
.
push
(
`rowStatus=
${
memoFind
.
rowStatus
}
`
);
}
if
(
memoFind
?.
offset
)
{
queryList
.
push
(
`offset=
${
memoFind
.
offset
}
`
);
}
if
(
memoFind
?.
limit
)
{
queryList
.
push
(
`limit=
${
memoFind
.
limit
}
`
);
}
return
axios
.
get
<
ResponseObject
<
Memo
[]
>>
(
`/api/memo?
${
queryList
.
join
(
"&"
)}
`
);
}
export
function
getMemoStats
()
{
return
axios
.
get
<
ResponseObject
<
number
[]
>>
(
`/api/memo/stats`
);
}
export
function
getMemoById
(
id
:
MemoId
)
{
return
axios
.
get
<
ResponseObject
<
Memo
>>
(
`/api/memo/
${
id
}
`
);
}
...
...
web/src/less/memo-content.less
View file @
1c2998c4
...
...
@@ -40,7 +40,11 @@
.ol-block,
.ul-block,
.todo-block {
@apply inline-block box-border text-center w-7 font-mono select-none;
@apply inline-block box-border text-right w-8 mr-px font-mono select-none whitespace-nowrap;
}
.ul-block {
@apply text-center;
}
.todo-block {
...
...
web/src/locales/en.json
View file @
1c2998c4
...
...
@@ -88,7 +88,8 @@
}
},
"memo-list"
:
{
"fetching-data"
:
"fetching data..."
"fetching-data"
:
"fetching data..."
,
"fetch-more"
:
"Click here to fetch more"
},
"shortcut-list"
:
{
"shortcut-title"
:
"shortcut title"
,
...
...
web/src/locales/vi.json
View file @
1c2998c4
...
...
@@ -88,7 +88,8 @@
}
},
"memo-list"
:
{
"fetching-data"
:
"đang tải dữ liệu..."
"fetching-data"
:
"đang tải dữ liệu..."
,
"fetch-more"
:
"Click here to fetch more"
},
"shortcut-list"
:
{
"shortcut-title"
:
"Tên lối tắt"
,
...
...
web/src/locales/zh.json
View file @
1c2998c4
...
...
@@ -88,7 +88,8 @@
}
},
"memo-list"
:
{
"fetching-data"
:
"请求数据中..."
"fetching-data"
:
"请求数据中..."
,
"fetch-more"
:
"Click here to fetch more"
},
"shortcut-list"
:
{
"shortcut-title"
:
"捷径标题"
,
...
...
web/src/pages/Explore.tsx
View file @
1c2998c4
...
...
@@ -3,8 +3,10 @@ import { useEffect, useState } from "react";
import
{
useTranslation
}
from
"react-i18next"
;
import
{
Link
}
from
"react-router-dom"
;
import
{
memoService
}
from
"../services"
;
import
{
DEFAULT_MEMO_LIMIT
}
from
"../services/memoService"
;
import
{
useAppSelector
}
from
"../store"
;
import
useLoading
from
"../hooks/useLoading"
;
import
toastHelper
from
"../components/Toast"
;
import
MemoContent
from
"../components/MemoContent"
;
import
MemoResources
from
"../components/MemoResources"
;
import
"../less/explore.less"
;
...
...
@@ -20,10 +22,14 @@ const Explore = () => {
const
[
state
,
setState
]
=
useState
<
State
>
({
memos
:
[],
});
const
[
isComplete
,
setIsComplete
]
=
useState
<
boolean
>
(
false
);
const
loadingState
=
useLoading
();
useEffect
(()
=>
{
memoService
.
fetchAllMemos
().
then
((
memos
)
=>
{
memoService
.
fetchAllMemos
(
DEFAULT_MEMO_LIMIT
,
state
.
memos
.
length
).
then
((
memos
)
=>
{
if
(
memos
.
length
<
DEFAULT_MEMO_LIMIT
)
{
setIsComplete
(
true
);
}
setState
({
memos
,
});
...
...
@@ -31,6 +37,23 @@ const Explore = () => {
});
},
[
location
]);
const
handleFetchMoreClick
=
async
()
=>
{
try
{
const
fetchedMemos
=
await
memoService
.
fetchAllMemos
(
DEFAULT_MEMO_LIMIT
,
state
.
memos
.
length
);
if
(
fetchedMemos
.
length
<
DEFAULT_MEMO_LIMIT
)
{
setIsComplete
(
true
);
}
else
{
setIsComplete
(
false
);
}
setState
({
memos
:
state
.
memos
.
concat
(
fetchedMemos
),
});
}
catch
(
error
:
any
)
{
console
.
error
(
error
);
toastHelper
.
error
(
error
.
response
.
data
.
message
);
}
};
return
(
<
section
className=
"page-wrapper explore"
>
<
div
className=
"page-container"
>
...
...
@@ -53,25 +76,33 @@ const Explore = () => {
</
div
>
{
!
loadingState
.
isLoading
&&
(
<
main
className=
"memos-wrapper"
>
{
state
.
memos
.
length
>
0
?
(
state
.
memos
.
map
((
memo
)
=>
{
const
createdAtStr
=
dayjs
(
memo
.
displayTs
).
locale
(
i18n
.
language
).
format
(
"YYYY/MM/DD HH:mm:ss"
);
return
(
<
div
className=
"memo-container"
key=
{
memo
.
id
}
>
<
div
className=
"memo-header"
>
<
span
className=
"time-text"
>
{
createdAtStr
}
</
span
>
<
span
className=
"split-text"
>
by
</
span
>
<
a
className=
"name-text"
href=
{
`/u/${memo.creator.id}`
}
>
{
memo
.
creator
.
name
}
</
a
>
</
div
>
<
MemoContent
className=
"memo-content"
content=
{
memo
.
content
}
onMemoContentClick=
{
()
=>
undefined
}
/>
<
MemoResources
memo=
{
memo
}
/>
{
state
.
memos
.
map
((
memo
)
=>
{
const
createdAtStr
=
dayjs
(
memo
.
displayTs
).
locale
(
i18n
.
language
).
format
(
"YYYY/MM/DD HH:mm:ss"
);
return
(
<
div
className=
"memo-container"
key=
{
memo
.
id
}
>
<
div
className=
"memo-header"
>
<
span
className=
"time-text"
>
{
createdAtStr
}
</
span
>
<
span
className=
"split-text"
>
by
</
span
>
<
a
className=
"name-text"
href=
{
`/u/${memo.creator.id}`
}
>
{
memo
.
creator
.
name
}
</
a
>
</
div
>
);
})
<
MemoContent
className=
"memo-content"
content=
{
memo
.
content
}
onMemoContentClick=
{
()
=>
undefined
}
/>
<
MemoResources
memo=
{
memo
}
/>
</
div
>
);
})
}
{
isComplete
?
(
state
.
memos
.
length
===
0
?
(
<
p
className=
"w-full text-center mt-12 text-gray-600"
>
{
t
(
"message.no-memos"
)
}
</
p
>
)
:
null
)
:
(
<
p
className=
"w-full text-center mt-12 text-gray-600"
>
{
t
(
"message.no-memos"
)
}
</
p
>
<
p
className=
"m-auto text-center mt-4 italic cursor-pointer text-gray-500 hover:text-green-600"
onClick=
{
handleFetchMoreClick
}
>
{
t
(
"memo-list.fetch-more"
)
}
</
p
>
)
}
</
main
>
)
}
...
...
web/src/services/memoService.ts
View file @
1c2998c4
import
*
as
api
from
"../helpers/api"
;
import
{
createMemo
,
patchMemo
,
setIsFetching
,
setMemos
,
setTags
}
from
"../store/modules/memo"
;
import
{
createMemo
,
deleteMemo
,
patchMemo
,
setIsFetching
,
setMemos
,
setTags
}
from
"../store/modules/memo"
;
import
store
from
"../store"
;
import
userService
from
"./userService"
;
export
const
DEFAULT_MEMO_LIMIT
=
20
;
const
convertResponseModelMemo
=
(
memo
:
Memo
):
Memo
=>
{
return
{
...
memo
,
...
...
@@ -17,32 +19,37 @@ const memoService = {
return
store
.
getState
().
memo
;
},
fetchAllMemos
:
async
()
=>
{
const
memoFind
:
MemoFind
=
{};
if
(
userService
.
isVisitorMode
())
{
memoFind
.
creatorId
=
userService
.
getUserIdFromPath
();
}
const
{
data
}
=
(
await
api
.
getAllMemos
()).
data
;
const
memos
=
data
.
map
((
m
)
=>
convertResponseModelMemo
(
m
));
return
memos
;
},
fetchMemos
:
async
()
=>
{
const
timeoutIndex
=
setTimeout
(()
=>
{
store
.
dispatch
(
setIsFetching
(
true
));
},
1000
);
fetchMemos
:
async
(
limit
=
DEFAULT_MEMO_LIMIT
,
offset
=
0
)
=>
{
store
.
dispatch
(
setIsFetching
(
true
));
const
memoFind
:
MemoFind
=
{
rowStatus
:
"NORMAL"
,
limit
,
offset
,
};
if
(
userService
.
isVisitorMode
())
{
memoFind
.
creatorId
=
userService
.
getUserIdFromPath
();
}
const
{
data
}
=
(
await
api
.
getMemoList
(
memoFind
)).
data
;
const
memos
=
data
.
map
((
m
)
=>
convertResponseModelMemo
(
m
));
store
.
dispatch
(
setMemos
(
memos
));
clearTimeout
(
timeoutIndex
);
const
fetchedMemos
=
data
.
map
((
m
)
=>
convertResponseModelMemo
(
m
));
if
(
offset
===
0
)
{
store
.
dispatch
(
setMemos
([]));
}
const
memos
=
memoService
.
getState
().
memos
;
store
.
dispatch
(
setMemos
(
memos
.
concat
(
fetchedMemos
)));
store
.
dispatch
(
setIsFetching
(
false
));
return
fetchedMemos
;
},
fetchAllMemos
:
async
(
limit
=
DEFAULT_MEMO_LIMIT
,
offset
?:
number
)
=>
{
const
memoFind
:
MemoFind
=
{
rowStatus
:
"NORMAL"
,
limit
,
offset
,
};
const
{
data
}
=
(
await
api
.
getAllMemos
(
memoFind
)).
data
;
const
memos
=
data
.
map
((
m
)
=>
convertResponseModelMemo
(
m
));
return
memos
;
},
...
...
@@ -129,6 +136,7 @@ const memoService = {
deleteMemoById
:
async
(
memoId
:
MemoId
)
=>
{
await
api
.
deleteMemo
(
memoId
);
store
.
dispatch
(
deleteMemo
(
memoId
));
},
};
...
...
web/src/store/modules/memo.ts
View file @
1c2998c4
...
...
@@ -44,6 +44,14 @@ const memoSlice = createSlice({
.
filter
((
memo
)
=>
memo
.
rowStatus
===
"NORMAL"
),
};
},
deleteMemo
:
(
state
,
action
:
PayloadAction
<
MemoId
>
)
=>
{
return
{
...
state
,
memos
:
state
.
memos
.
filter
((
memo
)
=>
{
return
memo
.
id
!==
action
.
payload
;
}),
};
},
setTags
:
(
state
,
action
:
PayloadAction
<
string
[]
>
)
=>
{
return
{
...
state
,
...
...
@@ -59,6 +67,6 @@ const memoSlice = createSlice({
},
});
export
const
{
setMemos
,
createMemo
,
patchMemo
,
setTags
,
setIsFetching
}
=
memoSlice
.
actions
;
export
const
{
setMemos
,
createMemo
,
patchMemo
,
deleteMemo
,
setTags
,
setIsFetching
}
=
memoSlice
.
actions
;
export
default
memoSlice
.
reducer
;
web/src/types/modules/memo.d.ts
View file @
1c2998c4
...
...
@@ -38,4 +38,6 @@ interface MemoFind {
creatorId
?:
UserId
;
rowStatus
?:
RowStatus
;
visibility
?:
Visibility
;
offset
?:
number
;
limit
?:
number
;
}
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