mirror of
https://github.com/usememos/memos.git
synced 2025-03-15 18:20:09 +01:00
chore: add time filter to timeline
This commit is contained in:
parent
7de3de5610
commit
d426f89cf0
@ -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
|
||||
CreatedTsBefore *int64
|
||||
CreatedTsAfter *int64
|
||||
Creator *string
|
||||
RowStatus *store.RowStatus
|
||||
ContentSearch []string
|
||||
Visibilities []store.Visibility
|
||||
OrderByPinned bool
|
||||
DisplayTimeBefore *int64
|
||||
DisplayTimeAfter *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" {
|
||||
createdTsBefore := callExpr.Args[1].GetConstExpr().GetInt64Value()
|
||||
filter.CreatedTsBefore = &createdTsBefore
|
||||
} else if idExpr.Name == "created_ts_after" {
|
||||
createdTsAfter := callExpr.Args[1].GetConstExpr().GetInt64Value()
|
||||
filter.CreatedTsAfter = &createdTsAfter
|
||||
} else if idExpr.Name == "display_time_before" {
|
||||
displayTimeBefore := callExpr.Args[1].GetConstExpr().GetInt64Value()
|
||||
filter.DisplayTimeBefore = &displayTimeBefore
|
||||
} else if idExpr.Name == "display_time_after" {
|
||||
displayTimeAfter := callExpr.Args[1].GetConstExpr().GetInt64Value()
|
||||
filter.DisplayTimeAfter = &displayTimeAfter
|
||||
} else if idExpr.Name == "creator" {
|
||||
creator := callExpr.Args[1].GetConstExpr().GetStringValue()
|
||||
filter.Creator = &creator
|
||||
|
@ -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+"%")
|
||||
|
@ -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))
|
||||
|
@ -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))
|
||||
|
@ -54,6 +54,8 @@ type FindMemo struct {
|
||||
CreatorID *int32
|
||||
CreatedTsAfter *int64
|
||||
CreatedTsBefore *int64
|
||||
UpdatedTsAfter *int64
|
||||
UpdatedTsBefore *int64
|
||||
|
||||
// Domain specific fields
|
||||
ContentSearch []string
|
||||
|
@ -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>
|
||||
) : (
|
||||
|
@ -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 { DAILY_TIMESTAMP, DEFAULT_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")}>
|
||||
|
Loading…
x
Reference in New Issue
Block a user