From cc241f38b3d73e56007d44283fc0bbdd1c30ad66 Mon Sep 17 00:00:00 2001 From: Dirk McCormick Date: Fri, 9 Jun 2023 16:43:10 +0200 Subject: [PATCH] feat: split flagged pieces page into flagged / flagged because unsealed --- gql/resolver_piece.go | 14 ++++ gql/schema.graphql | 3 + react/src/App.js | 6 +- react/src/LID.css | 4 ++ react/src/LID.js | 155 +++++++++++++++++++++++++++++++++++++----- react/src/gql.js | 11 ++- 6 files changed, 172 insertions(+), 21 deletions(-) diff --git a/gql/resolver_piece.go b/gql/resolver_piece.go index 4e585e675..22729c5c6 100644 --- a/gql/resolver_piece.go +++ b/gql/resolver_piece.go @@ -141,6 +141,20 @@ func (r *resolver) PiecesFlagged(ctx context.Context, args piecesFlaggedArgs) (* }, nil } +type piecesFlaggedCountArgs struct { + HasUnsealedCopy graphql.NullBool +} + +func (r *resolver) PiecesFlaggedCount(ctx context.Context, args piecesFlaggedCountArgs) (int32, error) { + var filter *types.FlaggedPiecesListFilter + if args.HasUnsealedCopy.Set && args.HasUnsealedCopy.Value != nil { + filter = &types.FlaggedPiecesListFilter{HasUnsealedCopy: *args.HasUnsealedCopy.Value} + } + + count, err := r.piecedirectory.FlaggedPiecesCount(ctx, filter) + return int32(count), err +} + func (r *resolver) PiecesWithPayloadCid(ctx context.Context, args struct{ PayloadCid string }) ([]string, error) { payloadCid, err := cid.Parse(args.PayloadCid) if err != nil { diff --git a/gql/schema.graphql b/gql/schema.graphql index 70860119b..77f11f4c6 100644 --- a/gql/schema.graphql +++ b/gql/schema.graphql @@ -485,6 +485,9 @@ type RootQuery { """Get a list of pieces that have been flagged as having problems""" piecesFlagged(hasUnsealedCopy: Boolean, cursor: BigInt, offset: Int, limit: Int): FlaggedPiecesList! + """Get the number of pieces that have been flagged as having problems""" + piecesFlaggedCount(hasUnsealedCopy: Boolean): Int! + """Get information about a piece from the piece store, DAG store and database""" pieceStatus(pieceCid: String!): PieceStatus! diff --git a/react/src/App.js b/react/src/App.js index 0cfab419e..298fd713c 100644 --- a/react/src/App.js +++ b/react/src/App.js @@ -18,7 +18,7 @@ import {LegacyDealDetail} from "./LegacyDealDetail" import {SettingsPage} from "./Settings"; import {Banner} from "./Banner"; import {ProposalLogsPage} from "./ProposalLogs"; -import {PieceDoctorPage, InspectPiecePage, LIDPage} from "./LID"; +import {PieceDoctorPage, InspectPiecePage, LIDPage, NoUnsealedSectorPieces, NoUnsealedSectorPage} from "./LID"; import {RetrievalLogsPage} from "./RetrievalLogs"; import {RetrievalLogDetail} from "./RetrievalLogDetail"; @@ -56,9 +56,11 @@ function App(props) { } /> } /> } /> - } /> } /> } /> + } /> + } /> + } /> } /> diff --git a/react/src/LID.css b/react/src/LID.css index 165b0920b..8bb645eff 100644 --- a/react/src/LID.css +++ b/react/src/LID.css @@ -1,3 +1,7 @@ +.nav-link { + margin-left: 1em; +} + .block-stats th { text-align: left; } diff --git a/react/src/LID.js b/react/src/LID.js index 986d37039..f9018fdc1 100644 --- a/react/src/LID.js +++ b/react/src/LID.js @@ -3,7 +3,7 @@ import {useMutation, useQuery} from "@apollo/react-hooks"; import { LIDQuery, FlaggedPiecesQuery, PieceBuildIndexMutation, - PieceStatusQuery, PiecesWithPayloadCidQuery, PiecesWithRootPayloadCidQuery + PieceStatusQuery, PiecesWithPayloadCidQuery, PiecesWithRootPayloadCidQuery, FlaggedPiecesCountQuery } from "./gql"; import moment from "moment"; import {DebounceInput} from 'react-debounce-input'; @@ -225,6 +225,7 @@ function FlaggedPieces({setSearchQuery}) { cursor: queryCursor, offset: listOffset, limit: rowsPerPage, + hasUnsealedCopy: true, }, fetchPolicy: 'network-only', }) @@ -258,14 +259,17 @@ function FlaggedPieces({setSearchQuery}) { } return
-

Flagged pieces

+ + +

+ Flagged pieces ({totalCount}) +

- @@ -283,26 +287,30 @@ function FlaggedPieces({setSearchQuery}) { } -function FlaggedPieceRow({piece}) { - // Lookup the piece by piece CID. - // We do this asynchronously instead of as part of the list query so that - // checking for unseal status of each piece doesn't block the whole page. - const { loading, error, data } = useQuery(PieceStatusQuery, { +function NoUnsealedSectorLink() { + const {loading, error, data} = useQuery(FlaggedPiecesCountQuery, { + pollInterval: 10000, variables: { - pieceCid: piece.PieceCid, + hasUnsealedCopy: false, }, + fetchPolicy: 'network-only', }) - var isUnsealedMsg + if (error) return
Error: {error.message}
if (loading) { - isUnsealedMsg = '...' - } else if (error) { - isUnsealedMsg = error.Message - } else if (data && data.pieceStatus) { - const isUnsealed = hasUnsealedCopy(data.pieceStatus) - isUnsealedMsg = isUnsealed ? 'Yes' : 'No' + return
 
} + if (!data.piecesFlaggedCount) { + return null + } + + return
+ See {data.piecesFlaggedCount} pieces with no unsealed copy ➜ +
+} + +function FlaggedPieceRow({piece}) { return - } @@ -324,6 +331,120 @@ function hasUnsealedCopy(piece) { return false } +export function NoUnsealedSectorPage(props) { + return + + +} + +function NoUnsealedSectorPieces() { + const navigate = useNavigate() + const params = useParams() + const pageNum = (params.pageNum && parseInt(params.pageNum)) || 1 + + var [rowsPerPage, setRowsPerPage] = useState(RowsPerPage.load) + const onRowsPerPageChange = (e) => { + const val = parseInt(e.target.value) + RowsPerPage.save(val) + setRowsPerPage(val) + navigate(lidBasePath) + scrollTop() + } + + // Fetch rows on this page + const listOffset = (pageNum-1) * rowsPerPage + const queryCursor = (pageNum === 1) ? null : params.cursor + const {loading, error, data} = useQuery(FlaggedPiecesQuery, { + pollInterval: 10000, + variables: { + cursor: queryCursor, + offset: listOffset, + limit: rowsPerPage, + hasUnsealedCopy: false, + }, + fetchPolicy: 'network-only', + }) + + if (error) return
Error: {error.message + " - check connection to Boost server"}
+ if (loading) return
Loading...
+ + var res = data.piecesFlagged + var rows = res.pieces + const totalCount = data.piecesFlagged.totalCount + const moreRows = data.piecesFlagged.more + + if (!totalCount) { + return
+ Boost doctor did not find any pieces that were flagged because there is no unsealed copy of the sector +
+ } + + var cursor = params.cursor + if (pageNum === 1 && rows.length) { + cursor = rows[0].CreatedAt.getTime() + } + + const paginationParams = { + basePath: '/no-unsealed', + cursor, pageNum, totalCount, + rowsPerPage: rowsPerPage, + moreRows: moreRows, + onRowsPerPageChange: onRowsPerPageChange, + onLinkClick: scrollTop, + } + + return
+ + +

+ Pieces with no unsealed sector ({totalCount}) +

+ +
Piece CID IndexUnsealed Copy Deals
@@ -310,7 +318,6 @@ function FlaggedPieceRow({piece}) { {piece.IndexStatus.Status}{isUnsealedMsg} {piece.Deals.length}
+ + + + + + + + {rows.map(piece => ( + + ))} + +
Piece CIDIndexDeals
+ + +
+} + +function FlaggedPiecesLink() { + const {loading, error, data} = useQuery(FlaggedPiecesCountQuery, { + pollInterval: 10000, + variables: { + hasUnsealedCopy: true, + }, + fetchPolicy: 'network-only', + }) + + if (error) return
Error: {error.message}
+ if (loading) { + return
 
+ } + + if (!data.piecesFlaggedCount) { + return null + } + + return
+ See {data.piecesFlaggedCount} flagged pieces ➜ +
+} + + // Page showing information about a particular piece export function InspectPiecePage(props) { const params = useParams() diff --git a/react/src/gql.js b/react/src/gql.js index f78eb3403..30d8fc933 100644 --- a/react/src/gql.js +++ b/react/src/gql.js @@ -398,8 +398,8 @@ const PiecesWithPayloadCidQuery = gql` `; const FlaggedPiecesQuery = gql` - query AppFlaggedPiecesQuery($cursor: BigInt, $offset: Int, $limit: Int) { - piecesFlagged(cursor: $cursor, offset: $offset, limit: $limit) { + query AppFlaggedPiecesQuery($hasUnsealedCopy: Boolean, $cursor: BigInt, $offset: Int, $limit: Int) { + piecesFlagged(hasUnsealedCopy: $hasUnsealedCopy, cursor: $cursor, offset: $offset, limit: $limit) { pieces { CreatedAt Piece { @@ -424,6 +424,12 @@ const FlaggedPiecesQuery = gql` } `; +const FlaggedPiecesCountQuery = gql` + query AppFlaggedPiecesCountQuery($hasUnsealedCopy: Boolean) { + piecesFlaggedCount(hasUnsealedCopy: $hasUnsealedCopy) + } +`; + const PieceBuildIndexMutation = gql` mutation AppPieceBuildIndexMutation($pieceCid: String!) { pieceBuildIndex(pieceCid: $pieceCid) @@ -738,6 +744,7 @@ export { PieceBuildIndexMutation, PieceStatusQuery, FlaggedPiecesQuery, + FlaggedPiecesCountQuery, LIDQuery, StorageQuery, LegacyStorageQuery,