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
9265b8e2
Commit
9265b8e2
authored
May 14, 2024
by
Steven
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: update tags filter
parent
2317204c
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
374 additions
and
316 deletions
+374
-316
apidocs.swagger.yaml
docs/apidocs.swagger.yaml
+7
-0
memo_service.proto
proto/api/v1/memo_service.proto
+4
-0
memo_service.pb.go
proto/gen/api/v1/memo_service.pb.go
+292
-281
memo_service.pb.gw.go
proto/gen/api/v1/memo_service.pb.gw.go
+18
-0
acl_config.go
server/router/api/v1/acl_config.go
+1
-0
memo_service.go
server/router/api/v1/memo_service.go
+4
-7
ExploreSidebar.tsx
web/src/components/ExploreSidebar/ExploreSidebar.tsx
+2
-2
TagsSection.tsx
web/src/components/HomeSidebar/TagsSection.tsx
+42
-22
MemoEditorDialog.tsx
web/src/components/MemoEditor/MemoEditorDialog.tsx
+1
-1
RenameTagDialog.tsx
web/src/components/RenameTagDialog.tsx
+1
-1
tag.ts
web/src/store/v1/tag.ts
+2
-2
No files found.
docs/apidocs.swagger.yaml
View file @
9265b8e2
...
@@ -1514,6 +1514,13 @@ paths:
...
@@ -1514,6 +1514,13 @@ paths:
required: true
required: true
type: string
type: string
pattern: memos/[^/]+
pattern: memos/[^/]+
-
name
:
filter
description
:
|-
Filter is used to filter memos.
Format: "creator == users/{uid} && visibilities == ['PUBLIC', 'PROTECTED']"
in: query
required: false
type: string
tags
:
tags
:
-
MemoService
-
MemoService
/api/v1/{parent}/tags/{tag}
:
/api/v1/{parent}/tags/{tag}
:
...
...
proto/api/v1/memo_service.proto
View file @
9265b8e2
...
@@ -264,6 +264,10 @@ message ListMemoTagsRequest {
...
@@ -264,6 +264,10 @@ message ListMemoTagsRequest {
// The parent, who owns the tags.
// The parent, who owns the tags.
// Format: memos/{id}. Use "memos/-" to list all tags.
// Format: memos/{id}. Use "memos/-" to list all tags.
string
parent
=
1
;
string
parent
=
1
;
// Filter is used to filter memos.
// Format: "creator == users/{uid} && visibilities == ['PUBLIC', 'PROTECTED']"
string
filter
=
2
;
}
}
message
ListMemoTagsResponse
{
message
ListMemoTagsResponse
{
...
...
proto/gen/api/v1/memo_service.pb.go
View file @
9265b8e2
This diff is collapsed.
Click to expand it.
proto/gen/api/v1/memo_service.pb.gw.go
View file @
9265b8e2
...
@@ -419,6 +419,10 @@ func local_request_MemoService_RebuildMemoProperty_0(ctx context.Context, marsha
...
@@ -419,6 +419,10 @@ func local_request_MemoService_RebuildMemoProperty_0(ctx context.Context, marsha
}
}
var
(
filter_MemoService_ListMemoTags_0
=
&
utilities
.
DoubleArray
{
Encoding
:
map
[
string
]
int
{
"parent"
:
0
},
Base
:
[]
int
{
1
,
1
,
0
},
Check
:
[]
int
{
0
,
1
,
2
}}
)
func
request_MemoService_ListMemoTags_0
(
ctx
context
.
Context
,
marshaler
runtime
.
Marshaler
,
client
MemoServiceClient
,
req
*
http
.
Request
,
pathParams
map
[
string
]
string
)
(
proto
.
Message
,
runtime
.
ServerMetadata
,
error
)
{
func
request_MemoService_ListMemoTags_0
(
ctx
context
.
Context
,
marshaler
runtime
.
Marshaler
,
client
MemoServiceClient
,
req
*
http
.
Request
,
pathParams
map
[
string
]
string
)
(
proto
.
Message
,
runtime
.
ServerMetadata
,
error
)
{
var
protoReq
ListMemoTagsRequest
var
protoReq
ListMemoTagsRequest
var
metadata
runtime
.
ServerMetadata
var
metadata
runtime
.
ServerMetadata
...
@@ -440,6 +444,13 @@ func request_MemoService_ListMemoTags_0(ctx context.Context, marshaler runtime.M
...
@@ -440,6 +444,13 @@ func request_MemoService_ListMemoTags_0(ctx context.Context, marshaler runtime.M
return
nil
,
metadata
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"type mismatch, parameter: %s, error: %v"
,
"parent"
,
err
)
return
nil
,
metadata
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"type mismatch, parameter: %s, error: %v"
,
"parent"
,
err
)
}
}
if
err
:=
req
.
ParseForm
();
err
!=
nil
{
return
nil
,
metadata
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"%v"
,
err
)
}
if
err
:=
runtime
.
PopulateQueryParameters
(
&
protoReq
,
req
.
Form
,
filter_MemoService_ListMemoTags_0
);
err
!=
nil
{
return
nil
,
metadata
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"%v"
,
err
)
}
msg
,
err
:=
client
.
ListMemoTags
(
ctx
,
&
protoReq
,
grpc
.
Header
(
&
metadata
.
HeaderMD
),
grpc
.
Trailer
(
&
metadata
.
TrailerMD
))
msg
,
err
:=
client
.
ListMemoTags
(
ctx
,
&
protoReq
,
grpc
.
Header
(
&
metadata
.
HeaderMD
),
grpc
.
Trailer
(
&
metadata
.
TrailerMD
))
return
msg
,
metadata
,
err
return
msg
,
metadata
,
err
...
@@ -466,6 +477,13 @@ func local_request_MemoService_ListMemoTags_0(ctx context.Context, marshaler run
...
@@ -466,6 +477,13 @@ func local_request_MemoService_ListMemoTags_0(ctx context.Context, marshaler run
return
nil
,
metadata
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"type mismatch, parameter: %s, error: %v"
,
"parent"
,
err
)
return
nil
,
metadata
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"type mismatch, parameter: %s, error: %v"
,
"parent"
,
err
)
}
}
if
err
:=
req
.
ParseForm
();
err
!=
nil
{
return
nil
,
metadata
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"%v"
,
err
)
}
if
err
:=
runtime
.
PopulateQueryParameters
(
&
protoReq
,
req
.
Form
,
filter_MemoService_ListMemoTags_0
);
err
!=
nil
{
return
nil
,
metadata
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"%v"
,
err
)
}
msg
,
err
:=
server
.
ListMemoTags
(
ctx
,
&
protoReq
)
msg
,
err
:=
server
.
ListMemoTags
(
ctx
,
&
protoReq
)
return
msg
,
metadata
,
err
return
msg
,
metadata
,
err
...
...
server/router/api/v1/acl_config.go
View file @
9265b8e2
...
@@ -16,6 +16,7 @@ var authenticationAllowlistMethods = map[string]bool{
...
@@ -16,6 +16,7 @@ var authenticationAllowlistMethods = map[string]bool{
"/memos.api.v1.UserService/SearchUsers"
:
true
,
"/memos.api.v1.UserService/SearchUsers"
:
true
,
"/memos.api.v1.MemoService/GetMemo"
:
true
,
"/memos.api.v1.MemoService/GetMemo"
:
true
,
"/memos.api.v1.MemoService/ListMemos"
:
true
,
"/memos.api.v1.MemoService/ListMemos"
:
true
,
"/memos.api.v1.MemoService/ListMemoTags"
:
true
,
"/memos.api.v1.MemoService/SearchMemos"
:
true
,
"/memos.api.v1.MemoService/SearchMemos"
:
true
,
"/memos.api.v1.MarkdownService/GetLinkMetadata"
:
true
,
"/memos.api.v1.MarkdownService/GetLinkMetadata"
:
true
,
"/memos.api.v1.ResourceService/GetResourceBinary"
:
true
,
"/memos.api.v1.ResourceService/GetResourceBinary"
:
true
,
...
...
server/router/api/v1/memo_service.go
View file @
9265b8e2
...
@@ -595,14 +595,8 @@ func (s *APIV1Service) RebuildMemoProperty(ctx context.Context, request *v1pb.Re
...
@@ -595,14 +595,8 @@ func (s *APIV1Service) RebuildMemoProperty(ctx context.Context, request *v1pb.Re
}
}
func
(
s
*
APIV1Service
)
ListMemoTags
(
ctx
context
.
Context
,
request
*
v1pb
.
ListMemoTagsRequest
)
(
*
v1pb
.
ListMemoTagsResponse
,
error
)
{
func
(
s
*
APIV1Service
)
ListMemoTags
(
ctx
context
.
Context
,
request
*
v1pb
.
ListMemoTagsRequest
)
(
*
v1pb
.
ListMemoTagsResponse
,
error
)
{
user
,
err
:=
getCurrentUser
(
ctx
,
s
.
Store
)
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
"failed to get current user"
)
}
normalRowStatus
:=
store
.
Normal
normalRowStatus
:=
store
.
Normal
memoFind
:=
&
store
.
FindMemo
{
memoFind
:=
&
store
.
FindMemo
{
CreatorID
:
&
user
.
ID
,
RowStatus
:
&
normalRowStatus
,
RowStatus
:
&
normalRowStatus
,
ExcludeComments
:
true
,
ExcludeComments
:
true
,
// Default exclude content for performance.
// Default exclude content for performance.
...
@@ -615,6 +609,9 @@ func (s *APIV1Service) ListMemoTags(ctx context.Context, request *v1pb.ListMemoT
...
@@ -615,6 +609,9 @@ func (s *APIV1Service) ListMemoTags(ctx context.Context, request *v1pb.ListMemoT
}
}
memoFind
.
ID
=
&
memoID
memoFind
.
ID
=
&
memoID
}
}
if
err
:=
s
.
buildMemoFindWithFilter
(
ctx
,
memoFind
,
request
.
Filter
);
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
"failed to build find memos with filter: %v"
,
err
)
}
memos
,
err
:=
s
.
Store
.
ListMemos
(
ctx
,
memoFind
)
memos
,
err
:=
s
.
Store
.
ListMemos
(
ctx
,
memoFind
)
if
err
!=
nil
{
if
err
!=
nil
{
...
@@ -815,7 +812,6 @@ func convertVisibilityToStore(visibility v1pb.Visibility) store.Visibility {
...
@@ -815,7 +812,6 @@ func convertVisibilityToStore(visibility v1pb.Visibility) store.Visibility {
}
}
func
(
s
*
APIV1Service
)
buildMemoFindWithFilter
(
ctx
context
.
Context
,
find
*
store
.
FindMemo
,
filter
string
)
error
{
func
(
s
*
APIV1Service
)
buildMemoFindWithFilter
(
ctx
context
.
Context
,
find
*
store
.
FindMemo
,
filter
string
)
error
{
user
,
_
:=
getCurrentUser
(
ctx
,
s
.
Store
)
if
find
==
nil
{
if
find
==
nil
{
find
=
&
store
.
FindMemo
{}
find
=
&
store
.
FindMemo
{}
}
}
...
@@ -894,6 +890,7 @@ func (s *APIV1Service) buildMemoFindWithFilter(ctx context.Context, find *store.
...
@@ -894,6 +890,7 @@ func (s *APIV1Service) buildMemoFindWithFilter(ctx context.Context, find *store.
}
}
}
}
user
,
_
:=
getCurrentUser
(
ctx
,
s
.
Store
)
// If the user is not authenticated, only public memos are visible.
// If the user is not authenticated, only public memos are visible.
if
user
==
nil
{
if
user
==
nil
{
if
filter
==
""
{
if
filter
==
""
{
...
...
web/src/components/ExploreSidebar/ExploreSidebar.tsx
View file @
9265b8e2
import
clsx
from
"clsx"
;
import
clsx
from
"clsx"
;
import
SearchBar
from
"@/components/SearchBar"
;
import
SearchBar
from
"@/components/SearchBar"
;
import
UsersSection
from
"./User
sSection"
;
import
TagsSection
from
"../HomeSidebar/Tag
sSection"
;
interface
Props
{
interface
Props
{
className
?:
string
;
className
?:
string
;
...
@@ -15,7 +15,7 @@ const ExploreSidebar = (props: Props) => {
...
@@ -15,7 +15,7 @@ const ExploreSidebar = (props: Props) => {
)
}
)
}
>
>
<
SearchBar
/>
<
SearchBar
/>
<
UsersSection
/>
<
TagsSection
hideTips=
{
true
}
/>
</
aside
>
</
aside
>
);
);
};
};
...
...
web/src/components/HomeSidebar/TagsSection.tsx
View file @
9265b8e2
import
{
Dropdown
,
Menu
,
MenuButton
,
MenuItem
,
Tooltip
}
from
"@mui/joy"
;
import
{
Dropdown
,
Menu
,
MenuButton
,
MenuItem
,
Tooltip
}
from
"@mui/joy"
;
import
clsx
from
"clsx"
;
import
clsx
from
"clsx"
;
import
toast
from
"react-hot-toast"
;
import
toast
from
"react-hot-toast"
;
import
{
useLocation
}
from
"react-router-dom"
;
import
useDebounce
from
"react-use/lib/useDebounce"
;
import
useDebounce
from
"react-use/lib/useDebounce"
;
import
{
memoServiceClient
}
from
"@/grpcweb"
;
import
{
memoServiceClient
}
from
"@/grpcweb"
;
import
useCurrentUser
from
"@/hooks/useCurrentUser"
;
import
{
Routes
}
from
"@/router"
;
import
{
useFilterStore
}
from
"@/store/module"
;
import
{
useFilterStore
}
from
"@/store/module"
;
import
{
useMemoList
,
useTagStore
}
from
"@/store/v1"
;
import
{
useMemoList
,
useTagStore
}
from
"@/store/v1"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
...
@@ -10,21 +13,34 @@ import { showCommonDialog } from "../Dialog/CommonDialog";
...
@@ -10,21 +13,34 @@ import { showCommonDialog } from "../Dialog/CommonDialog";
import
Icon
from
"../Icon"
;
import
Icon
from
"../Icon"
;
import
showRenameTagDialog
from
"../RenameTagDialog"
;
import
showRenameTagDialog
from
"../RenameTagDialog"
;
const
TagsSection
=
()
=>
{
interface
Props
{
hideTips
?:
boolean
;
}
const
TagsSection
=
(
props
:
Props
)
=>
{
const
t
=
useTranslate
();
const
t
=
useTranslate
();
const
location
=
useLocation
();
const
user
=
useCurrentUser
();
const
tagStore
=
useTagStore
();
const
tagStore
=
useTagStore
();
const
memoList
=
useMemoList
();
const
memoList
=
useMemoList
();
const
tagAmounts
=
Object
.
entries
(
tagStore
.
getState
().
tagAmounts
)
const
tagAmounts
=
Object
.
entries
(
tagStore
.
getState
().
tagAmounts
)
.
sort
((
a
,
b
)
=>
a
[
0
].
localeCompare
(
b
[
0
]))
.
sort
((
a
,
b
)
=>
a
[
0
].
localeCompare
(
b
[
0
]))
.
sort
((
a
,
b
)
=>
b
[
1
]
-
a
[
1
]);
.
sort
((
a
,
b
)
=>
b
[
1
]
-
a
[
1
]);
useDebounce
(
useDebounce
(()
=>
fetchTags
(),
300
,
[
memoList
.
size
(),
location
.
pathname
]);
()
=>
{
tagStore
.
fetchTags
();
const
fetchTags
=
async
()
=>
{
},
const
filters
=
[
`row_status == "NORMAL"`
];
300
,
if
(
user
)
{
[
memoList
.
size
()],
if
(
location
.
pathname
===
Routes
.
EXPLORE
)
{
);
filters
.
push
(
`visibilities == ["PUBLIC", "PROTECTED"]`
);
}
filters
.
push
(
`creator == "
${
user
.
name
}
"`
);
}
else
{
filters
.
push
(
`visibilities == ["PUBLIC"]`
);
}
await
tagStore
.
fetchTags
(
filters
.
join
(
" && "
));
};
const
handleRebuildMemoTags
=
()
=>
{
const
handleRebuildMemoTags
=
()
=>
{
showCommonDialog
({
showCommonDialog
({
...
@@ -36,7 +52,7 @@ const TagsSection = () => {
...
@@ -36,7 +52,7 @@ const TagsSection = () => {
await
memoServiceClient
.
rebuildMemoProperty
({
await
memoServiceClient
.
rebuildMemoProperty
({
name
:
"memos/-"
,
name
:
"memos/-"
,
});
});
await
tagStore
.
fetchTags
({
skipCache
:
true
}
);
await
fetchTags
(
);
toast
.
success
(
"Rebuild tags successfully"
);
toast
.
success
(
"Rebuild tags successfully"
);
},
},
});
});
...
@@ -46,14 +62,16 @@ const TagsSection = () => {
...
@@ -46,14 +62,16 @@ const TagsSection = () => {
<
div
className=
"flex flex-col justify-start items-start w-full mt-3 px-1 h-auto shrink-0 flex-nowrap hide-scrollbar"
>
<
div
className=
"flex flex-col justify-start items-start w-full mt-3 px-1 h-auto shrink-0 flex-nowrap hide-scrollbar"
>
<
div
className=
"group flex flex-row justify-start items-center w-full gap-1 mb-1"
>
<
div
className=
"group flex flex-row justify-start items-center w-full gap-1 mb-1"
>
<
span
className=
"text-sm leading-6 font-mono text-gray-400 select-none"
>
{
t
(
"common.tags"
)
}
</
span
>
<
span
className=
"text-sm leading-6 font-mono text-gray-400 select-none"
>
{
t
(
"common.tags"
)
}
</
span
>
<
div
className=
{
clsx
(
"group-hover:block"
,
tagAmounts
.
length
>
0
?
"hidden"
:
""
)
}
>
{
!
props
.
hideTips
&&
(
<
Tooltip
title=
{
"Rebuild"
}
placement=
"top"
>
<
div
className=
{
clsx
(
"group-hover:block"
,
tagAmounts
.
length
>
0
?
"hidden"
:
""
)
}
>
<
Icon
.
RefreshCcw
<
Tooltip
title=
{
"Rebuild"
}
placement=
"top"
>
className=
"text-gray-400 w-4 h-auto cursor-pointer opacity-60 hover:opacity-100"
<
Icon
.
RefreshCcw
onClick=
{
handleRebuildMemoTags
}
className=
"text-gray-400 w-4 h-auto cursor-pointer opacity-60 hover:opacity-100"
/>
onClick=
{
handleRebuildMemoTags
}
</
Tooltip
>
/>
</
div
>
</
Tooltip
>
</
div
>
)
}
</
div
>
</
div
>
{
tagAmounts
.
length
>
0
?
(
{
tagAmounts
.
length
>
0
?
(
<
div
className=
"w-full flex flex-row justify-start items-center relative flex-wrap gap-x-2 gap-y-1"
>
<
div
className=
"w-full flex flex-row justify-start items-center relative flex-wrap gap-x-2 gap-y-1"
>
...
@@ -62,10 +80,12 @@ const TagsSection = () => {
...
@@ -62,10 +80,12 @@ const TagsSection = () => {
))
}
))
}
</
div
>
</
div
>
)
:
(
)
:
(
<
div
className=
"p-2 border border-dashed dark:border-zinc-800 rounded-md flex flex-row justify-start items-start gap-1 text-gray-400 dark:text-gray-500"
>
!
props
.
hideTips
&&
(
<
Icon
.
Tags
/>
<
div
className=
"p-2 border border-dashed dark:border-zinc-800 rounded-md flex flex-row justify-start items-start gap-1 text-gray-400 dark:text-gray-500"
>
<
p
className=
"mt-0.5 text-sm leading-snug italic"
>
{
t
(
"tag.create-tags-guide"
)
}
</
p
>
<
Icon
.
Tags
/>
</
div
>
<
p
className=
"mt-0.5 text-sm leading-snug italic"
>
{
t
(
"tag.create-tags-guide"
)
}
</
p
>
</
div
>
)
)
}
)
}
</
div
>
</
div
>
);
);
...
@@ -101,7 +121,7 @@ const TagContainer: React.FC<TagContainerProps> = (props: TagContainerProps) =>
...
@@ -101,7 +121,7 @@ const TagContainer: React.FC<TagContainerProps> = (props: TagContainerProps) =>
parent
:
"memos/-"
,
parent
:
"memos/-"
,
tag
:
tag
,
tag
:
tag
,
});
});
await
tagStore
.
fetchTags
({
skipCache
:
true
});
await
tagStore
.
fetchTags
(
undefined
,
{
skipCache
:
true
});
toast
.
success
(
t
(
"message.deleted-successfully"
));
toast
.
success
(
t
(
"message.deleted-successfully"
));
},
},
});
});
...
...
web/src/components/MemoEditor/MemoEditorDialog.tsx
View file @
9265b8e2
...
@@ -19,7 +19,7 @@ const MemoEditorDialog: React.FC<Props> = ({
...
@@ -19,7 +19,7 @@ const MemoEditorDialog: React.FC<Props> = ({
const
tagStore
=
useTagStore
();
const
tagStore
=
useTagStore
();
useEffect
(()
=>
{
useEffect
(()
=>
{
tagStore
.
fetchTags
({
skipCache
:
false
});
tagStore
.
fetchTags
(
undefined
,
{
skipCache
:
false
});
},
[]);
},
[]);
const
handleCloseBtnClick
=
()
=>
{
const
handleCloseBtnClick
=
()
=>
{
...
...
web/src/components/RenameTagDialog.tsx
View file @
9265b8e2
...
@@ -43,7 +43,7 @@ const RenameTagDialog: React.FC<Props> = (props: Props) => {
...
@@ -43,7 +43,7 @@ const RenameTagDialog: React.FC<Props> = (props: Props) => {
});
});
toast
.
success
(
"Rename tag successfully"
);
toast
.
success
(
"Rename tag successfully"
);
filterStore
.
setTagFilter
(
newName
);
filterStore
.
setTagFilter
(
newName
);
tagStore
.
fetchTags
({
skipCache
:
true
});
tagStore
.
fetchTags
(
undefined
,
{
skipCache
:
true
});
}
catch
(
error
:
any
)
{
}
catch
(
error
:
any
)
{
console
.
error
(
error
);
console
.
error
(
error
);
toast
.
error
(
error
.
details
);
toast
.
error
(
error
.
details
);
...
...
web/src/store/v1/tag.ts
View file @
9265b8e2
...
@@ -20,12 +20,12 @@ export const useTagStore = create(
...
@@ -20,12 +20,12 @@ export const useTagStore = create(
.
sort
((
a
,
b
)
=>
b
[
1
]
-
a
[
1
])
.
sort
((
a
,
b
)
=>
b
[
1
]
-
a
[
1
])
.
map
(([
tag
])
=>
tag
);
.
map
(([
tag
])
=>
tag
);
},
},
fetchTags
:
async
(
options
?:
{
skipCache
:
boolean
})
=>
{
fetchTags
:
async
(
filter
?:
string
,
options
?:
{
skipCache
:
boolean
})
=>
{
const
{
tagAmounts
:
cache
}
=
get
();
const
{
tagAmounts
:
cache
}
=
get
();
if
(
cache
.
length
>
0
&&
!
options
?.
skipCache
)
{
if
(
cache
.
length
>
0
&&
!
options
?.
skipCache
)
{
return
cache
;
return
cache
;
}
}
const
{
tagAmounts
}
=
await
memoServiceClient
.
listMemoTags
({
parent
:
"memos/-"
});
const
{
tagAmounts
}
=
await
memoServiceClient
.
listMemoTags
({
parent
:
"memos/-"
,
filter
});
set
({
tagAmounts
});
set
({
tagAmounts
});
},
},
})),
})),
...
...
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