diff --git a/frontend/src/shared/components/NotifcationPopup/index.tsx b/frontend/src/shared/components/NotifcationPopup/index.tsx index 2cc934e..4501552 100644 --- a/frontend/src/shared/components/NotifcationPopup/index.tsx +++ b/frontend/src/shared/components/NotifcationPopup/index.tsx @@ -427,7 +427,7 @@ const NotificationPopup: React.FC = ({ children }) => { onCompleted: (d) => { setData((prev) => ({ hasNextPage: d.notified.pageInfo.hasNextPage, - cursor: d.notified.pageInfo.endCursor, + cursor: d.notified.pageInfo.endCursor ?? '', nodes: [...prev.nodes, ...d.notified.notified], })); }, @@ -482,7 +482,7 @@ const NotificationPopup: React.FC = ({ children }) => { updateQuery: (prev, { fetchMoreResult }) => { if (!fetchMoreResult) return prev; setData((d) => ({ - cursor: fetchMoreResult.notified.pageInfo.endCursor, + cursor: fetchMoreResult.notified.pageInfo.endCursor ?? '', hasNextPage: fetchMoreResult.notified.pageInfo.hasNextPage, nodes: [...d.nodes, ...fetchMoreResult.notified.notified], })); diff --git a/frontend/src/shared/generated/graphql.tsx b/frontend/src/shared/generated/graphql.tsx index 97618c6..982a983 100644 --- a/frontend/src/shared/generated/graphql.tsx +++ b/frontend/src/shared/generated/graphql.tsx @@ -894,7 +894,7 @@ export type OwnersList = { export type PageInfo = { __typename?: 'PageInfo'; - endCursor: Scalars['String']; + endCursor?: Maybe; hasNextPage: Scalars['Boolean']; }; diff --git a/internal/db/notification.sql.go b/internal/db/notification.sql.go index 7e071c1..a25add8 100644 --- a/internal/db/notification.sql.go +++ b/internal/db/notification.sql.go @@ -149,15 +149,20 @@ SELECT notified_id, nn.notification_id, nn.user_id, read, read_at, n.notificatio LEFT JOIN user_account ON user_account.user_id = n.caused_by WHERE (n.created_on, n.notification_id) < ($1::timestamptz, $2::uuid) AND nn.user_id = $3::uuid + AND ($4::boolean = false OR nn.read = false) + AND ($5::boolean = false OR n.action_type = ANY($6::text[])) ORDER BY n.created_on DESC - LIMIT $4::int + LIMIT $7::int ` type GetNotificationsForUserIDCursorParams struct { - CreatedOn time.Time `json:"created_on"` - NotificationID uuid.UUID `json:"notification_id"` - UserID uuid.UUID `json:"user_id"` - LimitRows int32 `json:"limit_rows"` + CreatedOn time.Time `json:"created_on"` + NotificationID uuid.UUID `json:"notification_id"` + UserID uuid.UUID `json:"user_id"` + EnableUnread bool `json:"enable_unread"` + EnableActionType bool `json:"enable_action_type"` + ActionType []string `json:"action_type"` + LimitRows int32 `json:"limit_rows"` } type GetNotificationsForUserIDCursorRow struct { @@ -190,6 +195,9 @@ func (q *Queries) GetNotificationsForUserIDCursor(ctx context.Context, arg GetNo arg.CreatedOn, arg.NotificationID, arg.UserID, + arg.EnableUnread, + arg.EnableActionType, + pq.Array(arg.ActionType), arg.LimitRows, ) if err != nil { diff --git a/internal/db/query/notification.sql b/internal/db/query/notification.sql index 2edcd08..0aa0d76 100644 --- a/internal/db/query/notification.sql +++ b/internal/db/query/notification.sql @@ -39,5 +39,7 @@ SELECT * FROM notification_notified AS nn LEFT JOIN user_account ON user_account.user_id = n.caused_by WHERE (n.created_on, n.notification_id) < (@created_on::timestamptz, @notification_id::uuid) AND nn.user_id = @user_id::uuid + AND (@enable_unread::boolean = false OR nn.read = false) + AND (@enable_action_type::boolean = false OR n.action_type = ANY(@action_type::text[])) ORDER BY n.created_on DESC LIMIT @limit_rows::int; diff --git a/internal/graph/generated.go b/internal/graph/generated.go index 5b0be8b..28dfdc5 100644 --- a/internal/graph/generated.go +++ b/internal/graph/generated.go @@ -3295,7 +3295,7 @@ input NotifiedInput { } type PageInfo { - endCursor: String! + endCursor: String hasNextPage: Boolean! } @@ -13127,14 +13127,11 @@ func (ec *executionContext) _PageInfo_endCursor(ctx context.Context, field graph return graphql.Null } if resTmp == nil { - if !graphql.HasFieldError(ctx, fc) { - ec.Errorf(ctx, "must not be null") - } return graphql.Null } - res := resTmp.(string) + res := resTmp.(*string) fc.Result = res - return ec.marshalNString2string(ctx, field.Selections, res) + return ec.marshalOString2áš–string(ctx, field.Selections, res) } func (ec *executionContext) _PageInfo_hasNextPage(ctx context.Context, field graphql.CollectedField, obj *PageInfo) (ret graphql.Marshaler) { @@ -22809,9 +22806,6 @@ func (ec *executionContext) _PageInfo(ctx context.Context, sel ast.SelectionSet, out.Values[i] = graphql.MarshalString("PageInfo") case "endCursor": out.Values[i] = ec._PageInfo_endCursor(ctx, field, obj) - if out.Values[i] == graphql.Null { - invalids++ - } case "hasNextPage": out.Values[i] = ec._PageInfo_hasNextPage(ctx, field, obj) if out.Values[i] == graphql.Null { diff --git a/internal/graph/models_gen.go b/internal/graph/models_gen.go index ca9dd91..9bca92a 100644 --- a/internal/graph/models_gen.go +++ b/internal/graph/models_gen.go @@ -405,8 +405,8 @@ type OwnersList struct { } type PageInfo struct { - EndCursor string `json:"endCursor"` - HasNextPage bool `json:"hasNextPage"` + EndCursor *string `json:"endCursor"` + HasNextPage bool `json:"hasNextPage"` } type ProfileIcon struct { diff --git a/internal/graph/notification.resolvers.go b/internal/graph/notification.resolvers.go index ee3af53..a4b56ea 100644 --- a/internal/graph/notification.resolvers.go +++ b/internal/graph/notification.resolvers.go @@ -163,11 +163,30 @@ func (r *queryResolver) Notified(ctx context.Context, input NotifiedInput) (*Not log.WithError(err).Error("error decoding cursor") return &NotifiedResult{}, err } + enableRead := false + enableActionType := false + actionTypes := []string{} + switch input.Filter { + case NotificationFilterUnread: + enableRead = true + break + case NotificationFilterMentioned: + enableActionType = true + actionTypes = []string{"COMMENT_MENTIONED"} + break + case NotificationFilterAssigned: + enableActionType = true + actionTypes = []string{"TASK_ASSIGNED"} + break + } n, err := r.Repository.GetNotificationsForUserIDCursor(ctx, db.GetNotificationsForUserIDCursorParams{ - CreatedOn: t, - NotificationID: id, - LimitRows: int32(input.Limit + 1), - UserID: userID, + CreatedOn: t, + NotificationID: id, + LimitRows: int32(input.Limit + 1), + UserID: userID, + EnableUnread: enableRead, + EnableActionType: enableActionType, + ActionType: actionTypes, }) if err != nil { log.WithError(err).Error("error decoding fetching notifications") @@ -180,11 +199,14 @@ func (r *queryResolver) Notified(ctx context.Context, input NotifiedInput) (*Not "cursorId": id, "limit": input.Limit, }).Info("fetched notified") - endCursor := n[len(n)-1] - if len(n) == input.Limit+1 { - hasNextPage = true - n = n[:len(n)-1] - endCursor = n[len(n)-1] + var endCursor *db.GetNotificationsForUserIDCursorRow + if len(n) != 0 { + endCursor = &n[len(n)-1] + if len(n) == input.Limit+1 { + hasNextPage = true + n = n[:len(n)-1] + endCursor = &n[len(n)-1] + } } userNotifications := []Notified{} for _, notified := range n { @@ -206,9 +228,14 @@ func (r *queryResolver) Notified(ctx context.Context, input NotifiedInput) (*Not } userNotifications = append(userNotifications, n) } + var endCursorEncoded *string + if endCursor != nil { + eCur := utils.EncodeCursor(endCursor.CreatedOn, endCursor.NotificationID) + endCursorEncoded = &eCur + } pageInfo := &PageInfo{ HasNextPage: hasNextPage, - EndCursor: utils.EncodeCursor(endCursor.CreatedOn, endCursor.NotificationID), + EndCursor: endCursorEncoded, } log.WithField("pageInfo", pageInfo).Info("created page info") return &NotifiedResult{ @@ -249,11 +276,14 @@ func (r *queryResolver) Notified(ctx context.Context, input NotifiedInput) (*Not "nLen": len(n), "limit": input.Limit, }).Info("fetched notified") - endCursor := n[len(n)-1] - if len(n) == input.Limit+1 { - hasNextPage = true - n = n[:len(n)-1] - endCursor = n[len(n)-1] + var endCursor *db.GetNotificationsForUserIDPagedRow + if len(n) != 0 { + endCursor = &n[len(n)-1] + if len(n) == input.Limit+1 { + hasNextPage = true + n = n[:len(n)-1] + endCursor = &n[len(n)-1] + } } userNotifications := []Notified{} for _, notified := range n { @@ -275,9 +305,14 @@ func (r *queryResolver) Notified(ctx context.Context, input NotifiedInput) (*Not } userNotifications = append(userNotifications, n) } + var endCursorEncoded *string + if endCursor != nil { + eCur := utils.EncodeCursor(endCursor.CreatedOn, endCursor.NotificationID) + endCursorEncoded = &eCur + } pageInfo := &PageInfo{ HasNextPage: hasNextPage, - EndCursor: utils.EncodeCursor(endCursor.CreatedOn, endCursor.NotificationID), + EndCursor: endCursorEncoded, } log.WithField("pageInfo", pageInfo).Info("created page info") return &NotifiedResult{ diff --git a/internal/graph/schema/notification.gql b/internal/graph/schema/notification.gql index 7cf5fb4..9de3dae 100755 --- a/internal/graph/schema/notification.gql +++ b/internal/graph/schema/notification.gql @@ -26,7 +26,7 @@ input NotifiedInput { } type PageInfo { - endCursor: String! + endCursor: String hasNextPage: Boolean! } diff --git a/internal/graph/schema/notification/notification.gql b/internal/graph/schema/notification/notification.gql index 72e925e..f8c5534 100644 --- a/internal/graph/schema/notification/notification.gql +++ b/internal/graph/schema/notification/notification.gql @@ -26,7 +26,7 @@ input NotifiedInput { } type PageInfo { - endCursor: String! + endCursor: String hasNextPage: Boolean! }