mirror of https://github.com/usememos/memos.git
feat: enhance memo sorting functionality to support multiple fields
This commit is contained in:
parent
95de5cc700
commit
b4ea7d843f
|
|
@ -291,7 +291,9 @@ message ListMemosRequest {
|
||||||
|
|
||||||
// Optional. The order to sort results by.
|
// Optional. The order to sort results by.
|
||||||
// Default to "display_time desc".
|
// Default to "display_time desc".
|
||||||
// Example: "display_time desc" or "create_time asc"
|
// Supports comma-separated list of fields following AIP-132.
|
||||||
|
// Example: "pinned desc, display_time desc" or "create_time asc"
|
||||||
|
// Supported fields: pinned, display_time, create_time, update_time, name
|
||||||
string order_by = 4 [(google.api.field_behavior) = OPTIONAL];
|
string order_by = 4 [(google.api.field_behavior) = OPTIONAL];
|
||||||
|
|
||||||
// Optional. Filter to apply to the list results.
|
// Optional. Filter to apply to the list results.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.9
|
// protoc-gen-go v1.36.10
|
||||||
// protoc (unknown)
|
// protoc (unknown)
|
||||||
// source: api/v1/activity_service.proto
|
// source: api/v1/activity_service.proto
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.9
|
// protoc-gen-go v1.36.10
|
||||||
// protoc (unknown)
|
// protoc (unknown)
|
||||||
// source: api/v1/attachment_service.proto
|
// source: api/v1/attachment_service.proto
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.9
|
// protoc-gen-go v1.36.10
|
||||||
// protoc (unknown)
|
// protoc (unknown)
|
||||||
// source: api/v1/auth_service.proto
|
// source: api/v1/auth_service.proto
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.9
|
// protoc-gen-go v1.36.10
|
||||||
// protoc (unknown)
|
// protoc (unknown)
|
||||||
// source: api/v1/common.proto
|
// source: api/v1/common.proto
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.9
|
// protoc-gen-go v1.36.10
|
||||||
// protoc (unknown)
|
// protoc (unknown)
|
||||||
// source: api/v1/idp_service.proto
|
// source: api/v1/idp_service.proto
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.9
|
// protoc-gen-go v1.36.10
|
||||||
// protoc (unknown)
|
// protoc (unknown)
|
||||||
// source: api/v1/inbox_service.proto
|
// source: api/v1/inbox_service.proto
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.9
|
// protoc-gen-go v1.36.10
|
||||||
// protoc (unknown)
|
// protoc (unknown)
|
||||||
// source: api/v1/markdown_service.proto
|
// source: api/v1/markdown_service.proto
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.9
|
// protoc-gen-go v1.36.10
|
||||||
// protoc (unknown)
|
// protoc (unknown)
|
||||||
// source: api/v1/memo_service.proto
|
// source: api/v1/memo_service.proto
|
||||||
|
|
||||||
|
|
@ -564,7 +564,9 @@ type ListMemosRequest struct {
|
||||||
State State `protobuf:"varint,3,opt,name=state,proto3,enum=memos.api.v1.State" json:"state,omitempty"`
|
State State `protobuf:"varint,3,opt,name=state,proto3,enum=memos.api.v1.State" json:"state,omitempty"`
|
||||||
// Optional. The order to sort results by.
|
// Optional. The order to sort results by.
|
||||||
// Default to "display_time desc".
|
// Default to "display_time desc".
|
||||||
// Example: "display_time desc" or "create_time asc"
|
// Supports comma-separated list of fields following AIP-132.
|
||||||
|
// Example: "pinned desc, display_time desc" or "create_time asc"
|
||||||
|
// Supported fields: pinned, display_time, create_time, update_time, name
|
||||||
OrderBy string `protobuf:"bytes,4,opt,name=order_by,json=orderBy,proto3" json:"order_by,omitempty"`
|
OrderBy string `protobuf:"bytes,4,opt,name=order_by,json=orderBy,proto3" json:"order_by,omitempty"`
|
||||||
// Optional. Filter to apply to the list results.
|
// Optional. Filter to apply to the list results.
|
||||||
// Filter is a CEL expression to filter memos.
|
// Filter is a CEL expression to filter memos.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.9
|
// protoc-gen-go v1.36.10
|
||||||
// protoc (unknown)
|
// protoc (unknown)
|
||||||
// source: api/v1/shortcut_service.proto
|
// source: api/v1/shortcut_service.proto
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.9
|
// protoc-gen-go v1.36.10
|
||||||
// protoc (unknown)
|
// protoc (unknown)
|
||||||
// source: api/v1/user_service.proto
|
// source: api/v1/user_service.proto
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.9
|
// protoc-gen-go v1.36.10
|
||||||
// protoc (unknown)
|
// protoc (unknown)
|
||||||
// source: api/v1/workspace_service.proto
|
// source: api/v1/workspace_service.proto
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -656,7 +656,9 @@ paths:
|
||||||
description: |-
|
description: |-
|
||||||
Optional. The order to sort results by.
|
Optional. The order to sort results by.
|
||||||
Default to "display_time desc".
|
Default to "display_time desc".
|
||||||
Example: "display_time desc" or "create_time asc"
|
Supports comma-separated list of fields following AIP-132.
|
||||||
|
Example: "pinned desc, display_time desc" or "create_time asc"
|
||||||
|
Supported fields: pinned, display_time, create_time, update_time, name
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
- name: filter
|
- name: filter
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.9
|
// protoc-gen-go v1.36.10
|
||||||
// protoc (unknown)
|
// protoc (unknown)
|
||||||
// source: store/activity.proto
|
// source: store/activity.proto
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.9
|
// protoc-gen-go v1.36.10
|
||||||
// protoc (unknown)
|
// protoc (unknown)
|
||||||
// source: store/attachment.proto
|
// source: store/attachment.proto
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.9
|
// protoc-gen-go v1.36.10
|
||||||
// protoc (unknown)
|
// protoc (unknown)
|
||||||
// source: store/idp.proto
|
// source: store/idp.proto
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.9
|
// protoc-gen-go v1.36.10
|
||||||
// protoc (unknown)
|
// protoc (unknown)
|
||||||
// source: store/inbox.proto
|
// source: store/inbox.proto
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.9
|
// protoc-gen-go v1.36.10
|
||||||
// protoc (unknown)
|
// protoc (unknown)
|
||||||
// source: store/memo.proto
|
// source: store/memo.proto
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.9
|
// protoc-gen-go v1.36.10
|
||||||
// protoc (unknown)
|
// protoc (unknown)
|
||||||
// source: store/user_setting.proto
|
// source: store/user_setting.proto
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by protoc-gen-go. DO NOT EDIT.
|
// Code generated by protoc-gen-go. DO NOT EDIT.
|
||||||
// versions:
|
// versions:
|
||||||
// protoc-gen-go v1.36.9
|
// protoc-gen-go v1.36.10
|
||||||
// protoc (unknown)
|
// protoc (unknown)
|
||||||
// source: store/workspace_setting.proto
|
// source: store/workspace_setting.proto
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -875,30 +875,55 @@ func substring(s string, length int) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// parseMemoOrderBy parses the order_by field and sets the appropriate ordering in memoFind.
|
// parseMemoOrderBy parses the order_by field and sets the appropriate ordering in memoFind.
|
||||||
|
// Follows AIP-132: supports comma-separated list of fields with optional "desc" suffix.
|
||||||
|
// Example: "pinned desc, display_time desc" or "create_time asc".
|
||||||
func (*APIV1Service) parseMemoOrderBy(orderBy string, memoFind *store.FindMemo) error {
|
func (*APIV1Service) parseMemoOrderBy(orderBy string, memoFind *store.FindMemo) error {
|
||||||
// Parse order_by field like "display_time desc" or "create_time asc"
|
if strings.TrimSpace(orderBy) == "" {
|
||||||
parts := strings.Fields(strings.TrimSpace(orderBy))
|
|
||||||
if len(parts) == 0 {
|
|
||||||
return errors.New("empty order_by")
|
return errors.New("empty order_by")
|
||||||
}
|
}
|
||||||
|
|
||||||
field := parts[0]
|
// Split by comma to support multiple sort fields per AIP-132.
|
||||||
direction := "desc" // default
|
fields := strings.Split(orderBy, ",")
|
||||||
if len(parts) > 1 {
|
|
||||||
direction = strings.ToLower(parts[1])
|
// Track if we've seen pinned field.
|
||||||
if direction != "asc" && direction != "desc" {
|
hasPinned := false
|
||||||
return errors.Errorf("invalid order direction: %s, must be 'asc' or 'desc'", parts[1])
|
|
||||||
|
for _, field := range fields {
|
||||||
|
parts := strings.Fields(strings.TrimSpace(field))
|
||||||
|
if len(parts) == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldName := parts[0]
|
||||||
|
fieldDirection := "desc" // default per AIP-132 (we use desc as default for time fields)
|
||||||
|
if len(parts) > 1 {
|
||||||
|
fieldDirection = strings.ToLower(parts[1])
|
||||||
|
if fieldDirection != "asc" && fieldDirection != "desc" {
|
||||||
|
return errors.Errorf("invalid order direction: %s, must be 'asc' or 'desc'", parts[1])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch fieldName {
|
||||||
|
case "pinned":
|
||||||
|
hasPinned = true
|
||||||
|
memoFind.OrderByPinned = true
|
||||||
|
// Note: pinned is always DESC (true first) regardless of direction specified.
|
||||||
|
case "display_time", "create_time", "name":
|
||||||
|
// Only set if this is the first time field we encounter.
|
||||||
|
if !memoFind.OrderByUpdatedTs {
|
||||||
|
memoFind.OrderByTimeAsc = fieldDirection == "asc"
|
||||||
|
}
|
||||||
|
case "update_time":
|
||||||
|
memoFind.OrderByUpdatedTs = true
|
||||||
|
memoFind.OrderByTimeAsc = fieldDirection == "asc"
|
||||||
|
default:
|
||||||
|
return errors.Errorf("unsupported order field: %s, supported fields are: pinned, display_time, create_time, update_time, name", fieldName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch field {
|
// If only pinned was specified, still need to set a default time ordering.
|
||||||
case "display_time", "create_time", "name":
|
if hasPinned && !memoFind.OrderByUpdatedTs && len(fields) == 1 {
|
||||||
memoFind.OrderByTimeAsc = direction == "asc"
|
memoFind.OrderByTimeAsc = false // default to desc
|
||||||
case "update_time":
|
|
||||||
memoFind.OrderByUpdatedTs = true
|
|
||||||
memoFind.OrderByTimeAsc = direction == "asc"
|
|
||||||
default:
|
|
||||||
return errors.Errorf("unsupported order field: %s, supported fields are: display_time, create_time, update_time, name", field)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
||||||
|
|
@ -106,6 +106,9 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo
|
||||||
order = "ASC"
|
order = "ASC"
|
||||||
}
|
}
|
||||||
orderBy := []string{}
|
orderBy := []string{}
|
||||||
|
if find.OrderByPinned {
|
||||||
|
orderBy = append(orderBy, "`pinned` DESC")
|
||||||
|
}
|
||||||
if find.OrderByUpdatedTs {
|
if find.OrderByUpdatedTs {
|
||||||
orderBy = append(orderBy, "`updated_ts` "+order)
|
orderBy = append(orderBy, "`updated_ts` "+order)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,9 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo
|
||||||
order = "ASC"
|
order = "ASC"
|
||||||
}
|
}
|
||||||
orderBy := []string{}
|
orderBy := []string{}
|
||||||
|
if find.OrderByPinned {
|
||||||
|
orderBy = append(orderBy, "pinned DESC")
|
||||||
|
}
|
||||||
if find.OrderByUpdatedTs {
|
if find.OrderByUpdatedTs {
|
||||||
orderBy = append(orderBy, "updated_ts "+order)
|
orderBy = append(orderBy, "updated_ts "+order)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,9 @@ func (d *DB) ListMemos(ctx context.Context, find *store.FindMemo) ([]*store.Memo
|
||||||
order = "ASC"
|
order = "ASC"
|
||||||
}
|
}
|
||||||
orderBy := []string{}
|
orderBy := []string{}
|
||||||
|
if find.OrderByPinned {
|
||||||
|
orderBy = append(orderBy, "`pinned` DESC")
|
||||||
|
}
|
||||||
if find.OrderByUpdatedTs {
|
if find.OrderByUpdatedTs {
|
||||||
orderBy = append(orderBy, "`updated_ts` "+order)
|
orderBy = append(orderBy, "`updated_ts` "+order)
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@ type FindMemo struct {
|
||||||
Offset *int
|
Offset *int
|
||||||
|
|
||||||
// Ordering
|
// Ordering
|
||||||
|
OrderByPinned bool
|
||||||
OrderByUpdatedTs bool
|
OrderByUpdatedTs bool
|
||||||
OrderByTimeAsc bool
|
OrderByTimeAsc bool
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -64,7 +64,7 @@ const (
|
||||||
// Before 0.22, migration history had inconsistent versioning that needed normalization.
|
// Before 0.22, migration history had inconsistent versioning that needed normalization.
|
||||||
migrationHistoryNormalizedVersion = "0.22"
|
migrationHistoryNormalizedVersion = "0.22"
|
||||||
|
|
||||||
// Mode constants for profile mode
|
// Mode constants for profile mode.
|
||||||
modeProd = "prod"
|
modeProd = "prod"
|
||||||
modeDemo = "demo"
|
modeDemo = "demo"
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -34,14 +34,19 @@ const Archived = observer(() => {
|
||||||
listSort={(memos: Memo[]) =>
|
listSort={(memos: Memo[]) =>
|
||||||
memos
|
memos
|
||||||
.filter((memo) => memo.state === State.ARCHIVED)
|
.filter((memo) => memo.state === State.ARCHIVED)
|
||||||
.sort((a, b) =>
|
.sort((a, b) => {
|
||||||
viewStore.state.orderByTimeAsc
|
// First, sort by pinned status (pinned memos first)
|
||||||
|
if (a.pinned !== b.pinned) {
|
||||||
|
return b.pinned ? 1 : -1;
|
||||||
|
}
|
||||||
|
// Then sort by display time
|
||||||
|
return viewStore.state.orderByTimeAsc
|
||||||
? dayjs(a.displayTime).unix() - dayjs(b.displayTime).unix()
|
? dayjs(a.displayTime).unix() - dayjs(b.displayTime).unix()
|
||||||
: dayjs(b.displayTime).unix() - dayjs(a.displayTime).unix(),
|
: dayjs(b.displayTime).unix() - dayjs(a.displayTime).unix();
|
||||||
)
|
})
|
||||||
}
|
}
|
||||||
state={State.ARCHIVED}
|
state={State.ARCHIVED}
|
||||||
orderBy={viewStore.state.orderByTimeAsc ? "display_time asc" : "display_time desc"}
|
orderBy={viewStore.state.orderByTimeAsc ? "pinned desc, display_time asc" : "pinned desc, display_time desc"}
|
||||||
filter={memoFitler}
|
filter={memoFitler}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -63,13 +63,18 @@ const Home = observer(() => {
|
||||||
listSort={(memos: Memo[]) =>
|
listSort={(memos: Memo[]) =>
|
||||||
memos
|
memos
|
||||||
.filter((memo) => memo.state === State.NORMAL)
|
.filter((memo) => memo.state === State.NORMAL)
|
||||||
.sort((a, b) =>
|
.sort((a, b) => {
|
||||||
viewStore.state.orderByTimeAsc
|
// First, sort by pinned status (pinned memos first)
|
||||||
|
if (a.pinned !== b.pinned) {
|
||||||
|
return b.pinned ? 1 : -1;
|
||||||
|
}
|
||||||
|
// Then sort by display time
|
||||||
|
return viewStore.state.orderByTimeAsc
|
||||||
? dayjs(a.displayTime).unix() - dayjs(b.displayTime).unix()
|
? dayjs(a.displayTime).unix() - dayjs(b.displayTime).unix()
|
||||||
: dayjs(b.displayTime).unix() - dayjs(a.displayTime).unix(),
|
: dayjs(b.displayTime).unix() - dayjs(a.displayTime).unix();
|
||||||
)
|
})
|
||||||
}
|
}
|
||||||
orderBy={viewStore.state.orderByTimeAsc ? "display_time asc" : "display_time desc"}
|
orderBy={viewStore.state.orderByTimeAsc ? "pinned desc, display_time asc" : "pinned desc, display_time desc"}
|
||||||
filter={memoFilter}
|
filter={memoFilter}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -96,13 +96,18 @@ const UserProfile = observer(() => {
|
||||||
listSort={(memos: Memo[]) =>
|
listSort={(memos: Memo[]) =>
|
||||||
memos
|
memos
|
||||||
.filter((memo) => memo.state === State.NORMAL)
|
.filter((memo) => memo.state === State.NORMAL)
|
||||||
.sort((a, b) =>
|
.sort((a, b) => {
|
||||||
viewStore.state.orderByTimeAsc
|
// First, sort by pinned status (pinned memos first)
|
||||||
|
if (a.pinned !== b.pinned) {
|
||||||
|
return b.pinned ? 1 : -1;
|
||||||
|
}
|
||||||
|
// Then sort by display time
|
||||||
|
return viewStore.state.orderByTimeAsc
|
||||||
? dayjs(a.displayTime).unix() - dayjs(b.displayTime).unix()
|
? dayjs(a.displayTime).unix() - dayjs(b.displayTime).unix()
|
||||||
: dayjs(b.displayTime).unix() - dayjs(a.displayTime).unix(),
|
: dayjs(b.displayTime).unix() - dayjs(a.displayTime).unix();
|
||||||
)
|
})
|
||||||
}
|
}
|
||||||
orderBy={viewStore.state.orderByTimeAsc ? "display_time asc" : "display_time desc"}
|
orderBy={viewStore.state.orderByTimeAsc ? "pinned desc, display_time asc" : "pinned desc, display_time desc"}
|
||||||
filter={memoFilter}
|
filter={memoFilter}
|
||||||
/>
|
/>
|
||||||
</>
|
</>
|
||||||
|
|
|
||||||
|
|
@ -195,7 +195,9 @@ export interface ListMemosRequest {
|
||||||
/**
|
/**
|
||||||
* Optional. The order to sort results by.
|
* Optional. The order to sort results by.
|
||||||
* Default to "display_time desc".
|
* Default to "display_time desc".
|
||||||
* Example: "display_time desc" or "create_time asc"
|
* Supports comma-separated list of fields following AIP-132.
|
||||||
|
* Example: "pinned desc, display_time desc" or "create_time asc"
|
||||||
|
* Supported fields: pinned, display_time, create_time, update_time, name
|
||||||
*/
|
*/
|
||||||
orderBy: string;
|
orderBy: string;
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue