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
5334fdf1
Commit
5334fdf1
authored
Dec 19, 2023
by
Steven
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
chore: use api v2 in archived page
parent
abc14217
Changes
15
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
474 additions
and
442 deletions
+474
-442
memo_service.go
api/v2/memo_service.go
+98
-44
resource_service.go
api/v2/resource_service.go
+1
-1
memo_service.proto
proto/api/v2/memo_service.proto
+9
-8
resource_service.proto
proto/api/v2/resource_service.proto
+1
-1
README.md
proto/gen/api/v2/README.md
+4
-4
memo_service.pb.go
proto/gen/api/v2/memo_service.pb.go
+179
-169
resource_service.pb.go
proto/gen/api/v2/resource_service.pb.go
+102
-101
ArchivedMemo.tsx
web/src/components/ArchivedMemo.tsx
+3
-4
ArchivedMemoDialog.tsx
web/src/components/ArchivedMemoDialog.tsx
+0
-74
index.tsx
web/src/components/MemoContentV1/index.tsx
+8
-2
Archived.tsx
web/src/pages/Archived.tsx
+10
-9
Resources.tsx
web/src/pages/Resources.tsx
+1
-1
index.ts
web/src/store/v1/index.ts
+1
-0
memo.ts
web/src/store/v1/memo.ts
+16
-24
memoCache.ts
web/src/store/v1/memoCache.ts
+41
-0
No files found.
api/v2/memo_service.go
View file @
5334fdf1
...
@@ -2,13 +2,19 @@ package v2
...
@@ -2,13 +2,19 @@ package v2
import
(
import
(
"context"
"context"
"encoding/json"
"time"
"github.com/google/cel-go/cel"
"github.com/google/cel-go/cel"
"github.com/pkg/errors"
"github.com/pkg/errors"
expr
"google.golang.org/genproto/googleapis/api/expr/v1alpha1"
expr
"google.golang.org/genproto/googleapis/api/expr/v1alpha1"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/timestamppb"
apiv1
"github.com/usememos/memos/api/v1"
"github.com/usememos/memos/plugin/gomark/parser"
"github.com/usememos/memos/plugin/gomark/parser/tokenizer"
apiv2pb
"github.com/usememos/memos/proto/gen/api/v2"
apiv2pb
"github.com/usememos/memos/proto/gen/api/v2"
"github.com/usememos/memos/store"
"github.com/usememos/memos/store"
)
)
...
@@ -32,7 +38,7 @@ func (s *APIV2Service) CreateMemo(ctx context.Context, request *apiv2pb.CreateMe
...
@@ -32,7 +38,7 @@ func (s *APIV2Service) CreateMemo(ctx context.Context, request *apiv2pb.CreateMe
return
nil
,
err
return
nil
,
err
}
}
memoMessage
,
err
:=
convertMemoFromStore
(
memo
)
memoMessage
,
err
:=
s
.
convertMemoFromStore
(
ctx
,
memo
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
errors
.
Wrap
(
err
,
"failed to convert memo"
)
return
nil
,
errors
.
Wrap
(
err
,
"failed to convert memo"
)
}
}
...
@@ -58,26 +64,34 @@ func (s *APIV2Service) ListMemos(ctx context.Context, request *apiv2pb.ListMemos
...
@@ -58,26 +64,34 @@ func (s *APIV2Service) ListMemos(ctx context.Context, request *apiv2pb.ListMemos
if
filter
.
CreatedTsAfter
!=
nil
{
if
filter
.
CreatedTsAfter
!=
nil
{
memoFind
.
CreatedTsAfter
=
filter
.
CreatedTsAfter
memoFind
.
CreatedTsAfter
=
filter
.
CreatedTsAfter
}
}
if
filter
.
Creator
!=
nil
{
username
,
err
:=
ExtractUsernameFromName
(
*
filter
.
Creator
)
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
InvalidArgument
,
"invalid creator name"
)
}
user
,
err
:=
s
.
Store
.
GetUser
(
ctx
,
&
store
.
FindUser
{
Username
:
&
username
,
})
if
err
!=
nil
{
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
"failed to get user"
)
}
}
user
,
_
:=
getCurrentUser
(
ctx
,
s
.
Store
)
// If the user is not authenticated, only public memos are visible.
if
user
==
nil
{
if
user
==
nil
{
memoFind
.
VisibilityList
=
[]
store
.
Visibility
{
store
.
Public
}
return
nil
,
status
.
Errorf
(
codes
.
NotFound
,
"user not found"
)
}
}
memoFind
.
CreatorID
=
&
user
.
ID
if
request
.
CreatorId
!=
nil
{
memoFind
.
CreatorID
=
request
.
CreatorId
}
}
if
filter
.
RowStatus
!=
nil
{
// Remove the private memos from the list if the user is not the creator.
memoFind
.
RowStatus
=
filter
.
RowStatus
if
user
!=
nil
&&
request
.
CreatorId
!=
nil
&&
*
request
.
CreatorId
!=
user
.
ID
{
var
filteredVisibility
[]
store
.
Visibility
for
_
,
v
:=
range
memoFind
.
VisibilityList
{
if
v
!=
store
.
Private
{
filteredVisibility
=
append
(
filteredVisibility
,
v
)
}
}
}
}
memoFind
.
VisibilityList
=
filteredVisibility
user
,
_
:=
getCurrentUser
(
ctx
,
s
.
Store
)
// If the user is not authenticated, only public memos are visible.
if
user
==
nil
{
memoFind
.
VisibilityList
=
[]
store
.
Visibility
{
store
.
Public
}
}
if
user
!=
nil
&&
memoFind
.
CreatorID
!=
nil
&&
*
memoFind
.
CreatorID
!=
user
.
ID
{
memoFind
.
VisibilityList
=
[]
store
.
Visibility
{
store
.
Public
,
store
.
Protected
}
}
}
if
request
.
PageSize
!=
0
{
if
request
.
PageSize
!=
0
{
...
@@ -93,7 +107,7 @@ func (s *APIV2Service) ListMemos(ctx context.Context, request *apiv2pb.ListMemos
...
@@ -93,7 +107,7 @@ func (s *APIV2Service) ListMemos(ctx context.Context, request *apiv2pb.ListMemos
memoMessages
:=
make
([]
*
apiv2pb
.
Memo
,
len
(
memos
))
memoMessages
:=
make
([]
*
apiv2pb
.
Memo
,
len
(
memos
))
for
i
,
memo
:=
range
memos
{
for
i
,
memo
:=
range
memos
{
memoMessage
,
err
:=
convertMemoFromStore
(
memo
)
memoMessage
,
err
:=
s
.
convertMemoFromStore
(
ctx
,
memo
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
errors
.
Wrap
(
err
,
"failed to convert memo"
)
return
nil
,
errors
.
Wrap
(
err
,
"failed to convert memo"
)
}
}
...
@@ -129,7 +143,7 @@ func (s *APIV2Service) GetMemo(ctx context.Context, request *apiv2pb.GetMemoRequ
...
@@ -129,7 +143,7 @@ func (s *APIV2Service) GetMemo(ctx context.Context, request *apiv2pb.GetMemoRequ
}
}
}
}
memoMessage
,
err
:=
convertMemoFromStore
(
memo
)
memoMessage
,
err
:=
s
.
convertMemoFromStore
(
ctx
,
memo
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
errors
.
Wrap
(
err
,
"failed to convert memo"
)
return
nil
,
errors
.
Wrap
(
err
,
"failed to convert memo"
)
}
}
...
@@ -182,7 +196,7 @@ func (s *APIV2Service) ListMemoComments(ctx context.Context, request *apiv2pb.Li
...
@@ -182,7 +196,7 @@ func (s *APIV2Service) ListMemoComments(ctx context.Context, request *apiv2pb.Li
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
"failed to get memo"
)
return
nil
,
status
.
Errorf
(
codes
.
Internal
,
"failed to get memo"
)
}
}
if
memo
!=
nil
{
if
memo
!=
nil
{
memoMessage
,
err
:=
convertMemoFromStore
(
memo
)
memoMessage
,
err
:=
s
.
convertMemoFromStore
(
ctx
,
memo
)
if
err
!=
nil
{
if
err
!=
nil
{
return
nil
,
errors
.
Wrap
(
err
,
"failed to convert memo"
)
return
nil
,
errors
.
Wrap
(
err
,
"failed to convert memo"
)
}
}
...
@@ -196,17 +210,75 @@ func (s *APIV2Service) ListMemoComments(ctx context.Context, request *apiv2pb.Li
...
@@ -196,17 +210,75 @@ func (s *APIV2Service) ListMemoComments(ctx context.Context, request *apiv2pb.Li
return
response
,
nil
return
response
,
nil
}
}
func
(
s
*
APIV2Service
)
convertMemoFromStore
(
ctx
context
.
Context
,
memo
*
store
.
Memo
)
(
*
apiv2pb
.
Memo
,
error
)
{
rawNodes
,
err
:=
parser
.
Parse
(
tokenizer
.
Tokenize
(
memo
.
Content
))
if
err
!=
nil
{
return
nil
,
errors
.
Wrap
(
err
,
"failed to parse memo content"
)
}
displayTs
:=
memo
.
CreatedTs
if
displayWithUpdatedTs
,
err
:=
s
.
getMemoDisplayWithUpdatedTsSettingValue
(
ctx
);
err
==
nil
&&
displayWithUpdatedTs
{
displayTs
=
memo
.
UpdatedTs
}
return
&
apiv2pb
.
Memo
{
Id
:
int32
(
memo
.
ID
),
RowStatus
:
convertRowStatusFromStore
(
memo
.
RowStatus
),
CreateTime
:
timestamppb
.
New
(
time
.
Unix
(
memo
.
CreatedTs
,
0
)),
UpdateTime
:
timestamppb
.
New
(
time
.
Unix
(
memo
.
UpdatedTs
,
0
)),
DisplayTime
:
timestamppb
.
New
(
time
.
Unix
(
displayTs
,
0
)),
CreatorId
:
int32
(
memo
.
CreatorID
),
Content
:
memo
.
Content
,
Nodes
:
convertFromASTNodes
(
rawNodes
),
Visibility
:
convertVisibilityFromStore
(
memo
.
Visibility
),
Pinned
:
memo
.
Pinned
,
},
nil
}
func
(
s
*
APIV2Service
)
getMemoDisplayWithUpdatedTsSettingValue
(
ctx
context
.
Context
)
(
bool
,
error
)
{
memoDisplayWithUpdatedTsSetting
,
err
:=
s
.
Store
.
GetSystemSetting
(
ctx
,
&
store
.
FindSystemSetting
{
Name
:
apiv1
.
SystemSettingMemoDisplayWithUpdatedTsName
.
String
(),
})
if
err
!=
nil
{
return
false
,
errors
.
Wrap
(
err
,
"failed to find system setting"
)
}
memoDisplayWithUpdatedTs
:=
false
if
memoDisplayWithUpdatedTsSetting
!=
nil
{
err
=
json
.
Unmarshal
([]
byte
(
memoDisplayWithUpdatedTsSetting
.
Value
),
&
memoDisplayWithUpdatedTs
)
if
err
!=
nil
{
return
false
,
errors
.
Wrap
(
err
,
"failed to unmarshal system setting value"
)
}
}
return
memoDisplayWithUpdatedTs
,
nil
}
func
convertVisibilityFromStore
(
visibility
store
.
Visibility
)
apiv2pb
.
Visibility
{
switch
visibility
{
case
store
.
Private
:
return
apiv2pb
.
Visibility_PRIVATE
case
store
.
Protected
:
return
apiv2pb
.
Visibility_PROTECTED
case
store
.
Public
:
return
apiv2pb
.
Visibility_PUBLIC
default
:
return
apiv2pb
.
Visibility_VISIBILITY_UNSPECIFIED
}
}
// ListMemosFilterCELAttributes are the CEL attributes for ListMemosFilter.
// ListMemosFilterCELAttributes are the CEL attributes for ListMemosFilter.
var
ListMemosFilterCELAttributes
=
[]
cel
.
EnvOption
{
var
ListMemosFilterCELAttributes
=
[]
cel
.
EnvOption
{
cel
.
Variable
(
"visibility"
,
cel
.
StringType
),
cel
.
Variable
(
"visibility"
,
cel
.
StringType
),
cel
.
Variable
(
"created_ts_before"
,
cel
.
IntType
),
cel
.
Variable
(
"created_ts_before"
,
cel
.
IntType
),
cel
.
Variable
(
"created_ts_after"
,
cel
.
IntType
),
cel
.
Variable
(
"created_ts_after"
,
cel
.
IntType
),
cel
.
Variable
(
"creator"
,
cel
.
StringType
),
cel
.
Variable
(
"row_status"
,
cel
.
StringType
),
}
}
type
ListMemosFilter
struct
{
type
ListMemosFilter
struct
{
Visibility
*
store
.
Visibility
Visibility
*
store
.
Visibility
CreatedTsBefore
*
int64
CreatedTsBefore
*
int64
CreatedTsAfter
*
int64
CreatedTsAfter
*
int64
Creator
*
string
RowStatus
*
store
.
RowStatus
}
}
func
parseListMemosFilter
(
expression
string
)
(
*
ListMemosFilter
,
error
)
{
func
parseListMemosFilter
(
expression
string
)
(
*
ListMemosFilter
,
error
)
{
...
@@ -244,6 +316,14 @@ func findField(callExpr *expr.Expr_Call, filter *ListMemosFilter) {
...
@@ -244,6 +316,14 @@ func findField(callExpr *expr.Expr_Call, filter *ListMemosFilter) {
createdTsAfter
:=
callExpr
.
Args
[
1
]
.
GetConstExpr
()
.
GetInt64Value
()
createdTsAfter
:=
callExpr
.
Args
[
1
]
.
GetConstExpr
()
.
GetInt64Value
()
filter
.
CreatedTsAfter
=
&
createdTsAfter
filter
.
CreatedTsAfter
=
&
createdTsAfter
}
}
if
idExpr
.
Name
==
"creator"
{
creator
:=
callExpr
.
Args
[
1
]
.
GetConstExpr
()
.
GetStringValue
()
filter
.
Creator
=
&
creator
}
if
idExpr
.
Name
==
"row_status"
{
rowStatus
:=
store
.
RowStatus
(
callExpr
.
Args
[
1
]
.
GetConstExpr
()
.
GetStringValue
())
filter
.
RowStatus
=
&
rowStatus
}
return
return
}
}
}
}
...
@@ -254,29 +334,3 @@ func findField(callExpr *expr.Expr_Call, filter *ListMemosFilter) {
...
@@ -254,29 +334,3 @@ func findField(callExpr *expr.Expr_Call, filter *ListMemosFilter) {
}
}
}
}
}
}
func
convertMemoFromStore
(
memo
*
store
.
Memo
)
(
*
apiv2pb
.
Memo
,
error
)
{
return
&
apiv2pb
.
Memo
{
Id
:
int32
(
memo
.
ID
),
RowStatus
:
convertRowStatusFromStore
(
memo
.
RowStatus
),
CreatedTs
:
memo
.
CreatedTs
,
UpdatedTs
:
memo
.
UpdatedTs
,
CreatorId
:
int32
(
memo
.
CreatorID
),
Content
:
memo
.
Content
,
Visibility
:
convertVisibilityFromStore
(
memo
.
Visibility
),
Pinned
:
memo
.
Pinned
,
},
nil
}
func
convertVisibilityFromStore
(
visibility
store
.
Visibility
)
apiv2pb
.
Visibility
{
switch
visibility
{
case
store
.
Private
:
return
apiv2pb
.
Visibility_PRIVATE
case
store
.
Protected
:
return
apiv2pb
.
Visibility_PROTECTED
case
store
.
Public
:
return
apiv2pb
.
Visibility_PUBLIC
default
:
return
apiv2pb
.
Visibility_VISIBILITY_UNSPECIFIED
}
}
api/v2/resource_service.go
View file @
5334fdf1
...
@@ -95,7 +95,7 @@ func (s *APIV2Service) convertResourceFromStore(ctx context.Context, resource *s
...
@@ -95,7 +95,7 @@ func (s *APIV2Service) convertResourceFromStore(ctx context.Context, resource *s
return
&
apiv2pb
.
Resource
{
return
&
apiv2pb
.
Resource
{
Id
:
resource
.
ID
,
Id
:
resource
.
ID
,
Create
dTs
:
timestamppb
.
New
(
time
.
Unix
(
resource
.
CreatedTs
,
0
)),
Create
Time
:
timestamppb
.
New
(
time
.
Unix
(
resource
.
CreatedTs
,
0
)),
Filename
:
resource
.
Filename
,
Filename
:
resource
.
Filename
,
ExternalLink
:
resource
.
ExternalLink
,
ExternalLink
:
resource
.
ExternalLink
,
Type
:
resource
.
Type
,
Type
:
resource
.
Type
,
...
...
proto/api/v2/memo_service.proto
View file @
5334fdf1
...
@@ -6,6 +6,7 @@ import "api/v2/common.proto";
...
@@ -6,6 +6,7 @@ import "api/v2/common.proto";
import
"api/v2/markdown_service.proto"
;
import
"api/v2/markdown_service.proto"
;
import
"google/api/annotations.proto"
;
import
"google/api/annotations.proto"
;
import
"google/api/client.proto"
;
import
"google/api/client.proto"
;
import
"google/protobuf/timestamp.proto"
;
option
go_package
=
"gen/api/v2"
;
option
go_package
=
"gen/api/v2"
;
...
@@ -51,17 +52,19 @@ message Memo {
...
@@ -51,17 +52,19 @@ message Memo {
int32
creator_id
=
3
;
int32
creator_id
=
3
;
int64
created_ts
=
4
;
google.protobuf.Timestamp
create_time
=
4
;
int64
updated_ts
=
5
;
google.protobuf.Timestamp
update_time
=
5
;
string
content
=
6
;
google.protobuf.Timestamp
display_time
=
6
;
repeated
Node
nodes
=
7
;
string
content
=
7
;
Visibility
visibility
=
8
;
repeated
Node
nodes
=
8
;
bool
pinned
=
9
;
Visibility
visibility
=
9
;
bool
pinned
=
10
;
}
}
message
CreateMemoRequest
{
message
CreateMemoRequest
{
...
@@ -81,8 +84,6 @@ message ListMemosRequest {
...
@@ -81,8 +84,6 @@ message ListMemosRequest {
// Filter is used to filter memos returned in the list.
// Filter is used to filter memos returned in the list.
string
filter
=
3
;
string
filter
=
3
;
optional
int32
creator_id
=
4
;
}
}
message
ListMemosResponse
{
message
ListMemosResponse
{
...
...
proto/api/v2/resource_service.proto
View file @
5334fdf1
...
@@ -31,7 +31,7 @@ service ResourceService {
...
@@ -31,7 +31,7 @@ service ResourceService {
message
Resource
{
message
Resource
{
int32
id
=
1
;
int32
id
=
1
;
google.protobuf.Timestamp
create
d_ts
=
2
;
google.protobuf.Timestamp
create
_time
=
2
;
string
filename
=
3
;
string
filename
=
3
;
string
external_link
=
4
;
string
external_link
=
4
;
string
type
=
5
;
string
type
=
5
;
...
...
proto/gen/api/v2/README.md
View file @
5334fdf1
...
@@ -1451,7 +1451,6 @@
...
@@ -1451,7 +1451,6 @@
| page |
[
int32
](
#int32
)
| | |
| page |
[
int32
](
#int32
)
| | |
| page_size |
[
int32
](
#int32
)
| | |
| page_size |
[
int32
](
#int32
)
| | |
| filter |
[
string
](
#string
)
| | Filter is used to filter memos returned in the list. |
| filter |
[
string
](
#string
)
| | Filter is used to filter memos returned in the list. |
| creator_id |
[
int32
](
#int32
)
| optional | |
...
@@ -1484,8 +1483,9 @@
...
@@ -1484,8 +1483,9 @@
| id |
[
int32
](
#int32
)
| | |
| id |
[
int32
](
#int32
)
| | |
| row_status |
[
RowStatus
](
#memos-api-v2-RowStatus
)
| | |
| row_status |
[
RowStatus
](
#memos-api-v2-RowStatus
)
| | |
| creator_id |
[
int32
](
#int32
)
| | |
| creator_id |
[
int32
](
#int32
)
| | |
| created_ts |
[
int64
](
#int64
)
| | |
| create_time |
[
google.protobuf.Timestamp
](
#google-protobuf-Timestamp
)
| | |
| updated_ts |
[
int64
](
#int64
)
| | |
| update_time |
[
google.protobuf.Timestamp
](
#google-protobuf-Timestamp
)
| | |
| display_time |
[
google.protobuf.Timestamp
](
#google-protobuf-Timestamp
)
| | |
| content |
[
string
](
#string
)
| | |
| content |
[
string
](
#string
)
| | |
| nodes |
[
Node
](
#memos-api-v2-Node
)
| repeated | |
| nodes |
[
Node
](
#memos-api-v2-Node
)
| repeated | |
| visibility |
[
Visibility
](
#memos-api-v2-Visibility
)
| | |
| visibility |
[
Visibility
](
#memos-api-v2-Visibility
)
| | |
...
@@ -1632,7 +1632,7 @@
...
@@ -1632,7 +1632,7 @@
| Field | Type | Label | Description |
| Field | Type | Label | Description |
| ----- | ---- | ----- | ----------- |
| ----- | ---- | ----- | ----------- |
| id |
[
int32
](
#int32
)
| | |
| id |
[
int32
](
#int32
)
| | |
| create
d_ts
|
[
google.protobuf.Timestamp
](
#google-protobuf-Timestamp
)
| | |
| create
_time
|
[
google.protobuf.Timestamp
](
#google-protobuf-Timestamp
)
| | |
| filename |
[
string
](
#string
)
| | |
| filename |
[
string
](
#string
)
| | |
| external_link |
[
string
](
#string
)
| | |
| external_link |
[
string
](
#string
)
| | |
| type |
[
string
](
#string
)
| | |
| type |
[
string
](
#string
)
| | |
...
...
proto/gen/api/v2/memo_service.pb.go
View file @
5334fdf1
This diff is collapsed.
Click to expand it.
proto/gen/api/v2/resource_service.pb.go
View file @
5334fdf1
This diff is collapsed.
Click to expand it.
web/src/components/ArchivedMemo.tsx
View file @
5334fdf1
...
@@ -2,11 +2,11 @@ import { Tooltip } from "@mui/joy";
...
@@ -2,11 +2,11 @@ import { Tooltip } from "@mui/joy";
import
{
toast
}
from
"react-hot-toast"
;
import
{
toast
}
from
"react-hot-toast"
;
import
{
getDateTimeString
}
from
"@/helpers/datetime"
;
import
{
getDateTimeString
}
from
"@/helpers/datetime"
;
import
{
useMemoStore
}
from
"@/store/module"
;
import
{
useMemoStore
}
from
"@/store/module"
;
import
{
Memo
}
from
"@/types/proto/api/v2/memo_service"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
showCommonDialog
}
from
"./Dialog/CommonDialog"
;
import
{
showCommonDialog
}
from
"./Dialog/CommonDialog"
;
import
Icon
from
"./Icon"
;
import
Icon
from
"./Icon"
;
import
MemoContentV1
from
"./MemoContentV1"
;
import
MemoContentV1
from
"./MemoContentV1"
;
import
MemoResourceListView
from
"./MemoResourceListView"
;
import
"@/less/memo.less"
;
import
"@/less/memo.less"
;
interface
Props
{
interface
Props
{
...
@@ -48,7 +48,7 @@ const ArchivedMemo: React.FC<Props> = (props: Props) => {
...
@@ -48,7 +48,7 @@ const ArchivedMemo: React.FC<Props> = (props: Props) => {
<
div
className=
{
`memo-wrapper archived ${"memos-" + memo.id}`
}
>
<
div
className=
{
`memo-wrapper archived ${"memos-" + memo.id}`
}
>
<
div
className=
"memo-top-wrapper"
>
<
div
className=
"memo-top-wrapper"
>
<
div
className=
"w-full max-w-[calc(100%-20px)] flex flex-row justify-start items-center mr-1"
>
<
div
className=
"w-full max-w-[calc(100%-20px)] flex flex-row justify-start items-center mr-1"
>
<
span
className=
"text-sm text-gray-400 select-none"
>
{
getDateTimeString
(
memo
.
displayT
s
)
}
</
span
>
<
span
className=
"text-sm text-gray-400 select-none"
>
{
getDateTimeString
(
memo
.
displayT
ime
)
}
</
span
>
</
div
>
</
div
>
<
div
className=
"flex flex-row justify-end items-center gap-x-2"
>
<
div
className=
"flex flex-row justify-end items-center gap-x-2"
>
<
Tooltip
title=
{
t
(
"common.restore"
)
}
placement=
"top"
>
<
Tooltip
title=
{
t
(
"common.restore"
)
}
placement=
"top"
>
...
@@ -63,8 +63,7 @@ const ArchivedMemo: React.FC<Props> = (props: Props) => {
...
@@ -63,8 +63,7 @@ const ArchivedMemo: React.FC<Props> = (props: Props) => {
</
Tooltip
>
</
Tooltip
>
</
div
>
</
div
>
</
div
>
</
div
>
<
MemoContentV1
content=
{
memo
.
content
}
/>
<
MemoContentV1
content=
{
memo
.
content
}
nodes=
{
memo
.
nodes
}
/>
<
MemoResourceListView
resourceList=
{
memo
.
resourceList
}
/>
</
div
>
</
div
>
);
);
};
};
...
...
web/src/components/ArchivedMemoDialog.tsx
deleted
100644 → 0
View file @
abc14217
import
{
useEffect
,
useState
}
from
"react"
;
import
{
toast
}
from
"react-hot-toast"
;
import
useLoading
from
"@/hooks/useLoading"
;
import
{
useMemoStore
}
from
"@/store/module"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
ArchivedMemo
from
"./ArchivedMemo"
;
import
{
generateDialog
}
from
"./Dialog"
;
import
Icon
from
"./Icon"
;
import
"@/less/archived-memo-dialog.less"
;
type
Props
=
DialogProps
;
const
ArchivedMemoDialog
:
React
.
FC
<
Props
>
=
(
props
:
Props
)
=>
{
const
t
=
useTranslate
();
const
{
destroy
}
=
props
;
const
memoStore
=
useMemoStore
();
const
memos
=
memoStore
.
state
.
memos
;
const
loadingState
=
useLoading
();
const
[
archivedMemos
,
setArchivedMemos
]
=
useState
<
Memo
[]
>
([]);
useEffect
(()
=>
{
memoStore
.
fetchArchivedMemos
()
.
then
((
result
)
=>
{
setArchivedMemos
(
result
);
})
.
catch
((
error
)
=>
{
console
.
error
(
error
);
toast
.
error
(
error
.
response
.
data
.
message
);
})
.
finally
(()
=>
{
loadingState
.
setFinish
();
});
},
[
memos
]);
return
(
<>
<
div
className=
"dialog-header-container"
>
<
p
className=
"title-text"
>
{
t
(
"memo.archived-memos"
)
}
</
p
>
<
button
className=
"btn close-btn"
onClick=
{
destroy
}
>
<
Icon
.
X
className=
"icon-img"
/>
</
button
>
</
div
>
<
div
className=
"dialog-content-container"
>
{
loadingState
.
isLoading
?
(
<
div
className=
"tip-text-container"
>
<
p
className=
"tip-text"
>
{
t
(
"memo.fetching-data"
)
}
</
p
>
</
div
>
)
:
archivedMemos
.
length
===
0
?
(
<
div
className=
"tip-text-container"
>
<
p
className=
"tip-text"
>
{
t
(
"memo.no-archived-memos"
)
}
</
p
>
</
div
>
)
:
(
<
div
className=
"archived-memos-container"
>
{
archivedMemos
.
map
((
memo
)
=>
(
<
ArchivedMemo
key=
{
`${memo.id}-${memo.updatedTs}`
}
memo=
{
memo
}
/>
))
}
</
div
>
)
}
</
div
>
</>
);
};
export
default
function
showArchivedMemoDialog
():
void
{
generateDialog
(
{
className
:
"archived-memo-dialog"
,
dialogName
:
"archived-memo-dialog"
,
},
ArchivedMemoDialog
,
{}
);
}
web/src/components/MemoContentV1/index.tsx
View file @
5334fdf1
import
{
isUndefined
}
from
"lodash-es"
;
import
{
useEffect
,
useRef
,
useState
}
from
"react"
;
import
{
useEffect
,
useRef
,
useState
}
from
"react"
;
import
{
markdownServiceClient
}
from
"@/grpcweb"
;
import
{
markdownServiceClient
}
from
"@/grpcweb"
;
import
{
Node
}
from
"@/types/proto/api/v2/markdown_service"
;
import
{
Node
}
from
"@/types/proto/api/v2/markdown_service"
;
...
@@ -5,16 +6,21 @@ import Renderer from "./Renderer";
...
@@ -5,16 +6,21 @@ import Renderer from "./Renderer";
interface
Props
{
interface
Props
{
content
:
string
;
content
:
string
;
nodes
?:
Node
[];
className
?:
string
;
className
?:
string
;
onMemoContentClick
?:
(
e
:
React
.
MouseEvent
)
=>
void
;
onMemoContentClick
?:
(
e
:
React
.
MouseEvent
)
=>
void
;
}
}
const
MemoContentV1
:
React
.
FC
<
Props
>
=
(
props
:
Props
)
=>
{
const
MemoContentV1
:
React
.
FC
<
Props
>
=
(
props
:
Props
)
=>
{
const
{
className
,
content
,
onMemoContentClick
}
=
props
;
const
{
className
,
content
,
onMemoContentClick
}
=
props
;
const
[
nodes
,
setNodes
]
=
useState
<
Node
[]
>
([]);
const
[
nodes
,
setNodes
]
=
useState
<
Node
[]
>
(
props
.
nodes
??
[]);
const
memoContentContainerRef
=
useRef
<
HTMLDivElement
>
(
null
);
const
memoContentContainerRef
=
useRef
<
HTMLDivElement
>
(
null
);
useEffect
(()
=>
{
useEffect
(()
=>
{
if
(
!
isUndefined
(
props
.
nodes
))
{
return
;
}
markdownServiceClient
markdownServiceClient
.
parseMarkdown
({
.
parseMarkdown
({
markdown
:
content
,
markdown
:
content
,
...
@@ -22,7 +28,7 @@ const MemoContentV1: React.FC<Props> = (props: Props) => {
...
@@ -22,7 +28,7 @@ const MemoContentV1: React.FC<Props> = (props: Props) => {
.
then
(({
nodes
})
=>
{
.
then
(({
nodes
})
=>
{
setNodes
(
nodes
);
setNodes
(
nodes
);
});
});
},
[
content
]);
},
[
content
,
props
.
nodes
]);
const
handleMemoContentClick
=
async
(
e
:
React
.
MouseEvent
)
=>
{
const
handleMemoContentClick
=
async
(
e
:
React
.
MouseEvent
)
=>
{
if
(
onMemoContentClick
)
{
if
(
onMemoContentClick
)
{
...
...
web/src/pages/Archived.tsx
View file @
5334fdf1
...
@@ -3,22 +3,23 @@ import toast from "react-hot-toast";
...
@@ -3,22 +3,23 @@ import toast from "react-hot-toast";
import
ArchivedMemo
from
"@/components/ArchivedMemo"
;
import
ArchivedMemo
from
"@/components/ArchivedMemo"
;
import
Empty
from
"@/components/Empty"
;
import
Empty
from
"@/components/Empty"
;
import
MobileHeader
from
"@/components/MobileHeader"
;
import
MobileHeader
from
"@/components/MobileHeader"
;
import
{
memoServiceClient
}
from
"@/grpcweb"
;
import
useLoading
from
"@/hooks/useLoading"
;
import
useLoading
from
"@/hooks/useLoading"
;
import
{
useMemoStore
}
from
"@/store/modul
e"
;
import
{
Memo
}
from
"@/types/proto/api/v2/memo_servic
e"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
import
{
useTranslate
}
from
"@/utils/i18n"
;
const
Archived
=
()
=>
{
const
Archived
=
()
=>
{
const
t
=
useTranslate
();
const
t
=
useTranslate
();
const
memoStore
=
useMemoStore
();
const
loadingState
=
useLoading
();
const
loadingState
=
useLoading
();
const
[
archivedMemos
,
setArchivedMemos
]
=
useState
<
Memo
[]
>
([]);
const
[
archivedMemos
,
setArchivedMemos
]
=
useState
<
Memo
[]
>
([]);
const
memos
=
memoStore
.
state
.
memos
;
useEffect
(()
=>
{
useEffect
(()
=>
{
memoStore
memoServiceClient
.
fetchArchivedMemos
()
.
listMemos
({
.
then
((
result
)
=>
{
filter
:
"row_status == 'ARCHIVED'"
,
setArchivedMemos
(
result
);
})
.
then
(({
memos
})
=>
{
setArchivedMemos
(
memos
);
})
})
.
catch
((
error
)
=>
{
.
catch
((
error
)
=>
{
console
.
error
(
error
);
console
.
error
(
error
);
...
@@ -27,7 +28,7 @@ const Archived = () => {
...
@@ -27,7 +28,7 @@ const Archived = () => {
.
finally
(()
=>
{
.
finally
(()
=>
{
loadingState
.
setFinish
();
loadingState
.
setFinish
();
});
});
},
[
memos
]);
},
[]);
return
(
return
(
<
section
className=
"@container w-full max-w-5xl min-h-full flex flex-col justify-start items-start sm:pt-3 md:pt-6 pb-8"
>
<
section
className=
"@container w-full max-w-5xl min-h-full flex flex-col justify-start items-start sm:pt-3 md:pt-6 pb-8"
>
...
@@ -45,7 +46,7 @@ const Archived = () => {
...
@@ -45,7 +46,7 @@ const Archived = () => {
)
:
(
)
:
(
<
div
className=
"w-full flex flex-col justify-start items-start"
>
<
div
className=
"w-full flex flex-col justify-start items-start"
>
{
archivedMemos
.
map
((
memo
)
=>
(
{
archivedMemos
.
map
((
memo
)
=>
(
<
ArchivedMemo
key=
{
`${memo.id}-${memo.update
dTs
}`
}
memo=
{
memo
}
/>
<
ArchivedMemo
key=
{
`${memo.id}-${memo.update
Time
}`
}
memo=
{
memo
}
/>
))
}
))
}
</
div
>
</
div
>
)
}
)
}
...
...
web/src/pages/Resources.tsx
View file @
5334fdf1
...
@@ -16,7 +16,7 @@ import { useTranslate } from "@/utils/i18n";
...
@@ -16,7 +16,7 @@ import { useTranslate } from "@/utils/i18n";
function
groupResourcesByDate
(
resources
:
Resource
[])
{
function
groupResourcesByDate
(
resources
:
Resource
[])
{
const
grouped
=
new
Map
<
number
,
Resource
[]
>
();
const
grouped
=
new
Map
<
number
,
Resource
[]
>
();
resources
.
forEach
((
item
)
=>
{
resources
.
forEach
((
item
)
=>
{
const
date
=
new
Date
(
item
.
create
dTs
as
any
);
const
date
=
new
Date
(
item
.
create
Time
as
any
);
const
year
=
date
.
getFullYear
();
const
year
=
date
.
getFullYear
();
const
month
=
date
.
getMonth
()
+
1
;
const
month
=
date
.
getMonth
()
+
1
;
const
timestamp
=
Date
.
UTC
(
year
,
month
-
1
,
1
);
const
timestamp
=
Date
.
UTC
(
year
,
month
-
1
,
1
);
...
...
web/src/store/v1/index.ts
View file @
5334fdf1
export
*
from
"./user"
;
export
*
from
"./user"
;
export
*
from
"./memo"
;
export
*
from
"./memo"
;
export
*
from
"./memoCache"
;
export
*
from
"./inbox"
;
export
*
from
"./inbox"
;
export
*
from
"./resourceName"
;
export
*
from
"./resourceName"
;
web/src/store/v1/memo.ts
View file @
5334fdf1
import
{
create
}
from
"zustand"
;
import
{
create
}
from
"zustand"
;
import
{
combine
}
from
"zustand/middleware"
;
import
{
combine
}
from
"zustand/middleware"
;
import
*
as
api
from
"@/helpers/api
"
;
import
{
memoServiceClient
}
from
"@/grpcweb
"
;
import
{
convertResponseModelMemo
}
from
"../modul
e"
;
import
{
Memo
}
from
"@/types/proto/api/v2/memo_servic
e"
;
export
const
useMemo
Cache
Store
=
create
(
export
const
useMemo
V1
Store
=
create
(
combine
({
memoById
:
new
Map
<
MemoId
,
Memo
>
()
},
(
set
,
get
)
=>
({
combine
({
memoById
:
new
Map
<
number
,
Memo
>
()
},
(
set
,
get
)
=>
({
getState
:
()
=>
get
(),
getState
:
()
=>
get
(),
getOrFetchMemoById
:
async
(
memoI
d
:
MemoId
)
=>
{
getOrFetchMemoById
:
async
(
i
d
:
MemoId
)
=>
{
const
memo
=
get
().
memoById
.
get
(
memoI
d
);
const
memo
=
get
().
memoById
.
get
(
i
d
);
if
(
memo
)
{
if
(
memo
)
{
return
memo
;
return
memo
;
}
}
const
{
data
}
=
await
api
.
getMemoById
(
memoId
);
const
res
=
await
memoServiceClient
.
getMemo
({
const
formatedMemo
=
convertResponseModelMemo
(
data
);
id
,
set
((
state
)
=>
{
state
.
memoById
.
set
(
memoId
,
formatedMemo
);
return
state
;
});
});
if
(
!
res
.
memo
)
{
throw
new
Error
(
"Memo not found"
);
}
return
formatedMemo
;
},
getMemoById
:
(
memoId
:
MemoId
)
=>
{
return
get
().
memoById
.
get
(
memoId
);
},
setMemoCache
:
(
memo
:
Memo
)
=>
{
set
((
state
)
=>
{
set
((
state
)
=>
{
state
.
memoById
.
set
(
memo
.
id
,
m
emo
);
state
.
memoById
.
set
(
id
,
res
.
memo
as
M
emo
);
return
state
;
return
state
;
});
});
return
res
.
memo
;
},
},
deleteMemoCache
:
(
memoId
:
MemoId
)
=>
{
getMemoById
:
(
id
:
number
)
=>
{
set
((
state
)
=>
{
return
get
().
memoById
.
get
(
id
);
state
.
memoById
.
delete
(
memoId
);
return
state
;
});
},
},
}))
}))
);
);
web/src/store/v1/memoCache.ts
0 → 100644
View file @
5334fdf1
import
{
create
}
from
"zustand"
;
import
{
combine
}
from
"zustand/middleware"
;
import
*
as
api
from
"@/helpers/api"
;
import
{
convertResponseModelMemo
}
from
"../module"
;
export
const
useMemoCacheStore
=
create
(
combine
({
memoById
:
new
Map
<
MemoId
,
Memo
>
()
},
(
set
,
get
)
=>
({
getState
:
()
=>
get
(),
getOrFetchMemoById
:
async
(
memoId
:
MemoId
)
=>
{
const
memo
=
get
().
memoById
.
get
(
memoId
);
if
(
memo
)
{
return
memo
;
}
const
{
data
}
=
await
api
.
getMemoById
(
memoId
);
const
formatedMemo
=
convertResponseModelMemo
(
data
);
set
((
state
)
=>
{
state
.
memoById
.
set
(
memoId
,
formatedMemo
);
return
state
;
});
return
formatedMemo
;
},
getMemoById
:
(
memoId
:
MemoId
)
=>
{
return
get
().
memoById
.
get
(
memoId
);
},
setMemoCache
:
(
memo
:
Memo
)
=>
{
set
((
state
)
=>
{
state
.
memoById
.
set
(
memo
.
id
,
memo
);
return
state
;
});
},
deleteMemoCache
:
(
memoId
:
MemoId
)
=>
{
set
((
state
)
=>
{
state
.
memoById
.
delete
(
memoId
);
return
state
;
});
},
}))
);
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