diff --git a/src/components/ModalDiff/ModalDiffInvoice.jsx b/src/components/ModalDiff/ModalDiffInvoice.jsx index 4274c09b6..bf629dd2a 100644 --- a/src/components/ModalDiff/ModalDiffInvoice.jsx +++ b/src/components/ModalDiff/ModalDiffInvoice.jsx @@ -16,10 +16,13 @@ import styles from "./ModalDiff.module.css"; import { presentationalInvoiceName } from "src/containers/Invoice/helpers"; import uniq from "lodash/uniq"; import useApprovedProposals from "src/hooks/api/useApprovedProposals"; +import usePolicy from "src/hooks/api/usePolicy"; const ModalDiffInvoice = ({ onClose, invoice, prevInvoice, ...props }) => { const prevInput = prevInvoice && prevInvoice.input ? prevInvoice.input : []; - + const { + policyTicketVote: { summariespagesize: proposalPageSize } + } = usePolicy(); const proposalsTokens = useMemo(() => { const prevTokens = prevInput.lineitems ? prevInput.lineitems.map(({ proposaltoken }) => proposaltoken) @@ -30,7 +33,10 @@ const ModalDiffInvoice = ({ onClose, invoice, prevInvoice, ...props }) => { return uniq([...prevTokens, ...tokens]).filter((t) => t !== ""); }, [invoice.input.lineitems, prevInput]); - const { proposalsByToken, error } = useApprovedProposals(proposalsTokens); + const { proposalsByToken, error } = useApprovedProposals( + proposalPageSize, + proposalsTokens + ); return ( { + const { + policyTicketVote: { summariespagesize: proposalPageSize } + } = usePolicy(); const tokenFromUrl = get("params.token", match); - const { proposal, loading, error } = useProposal(tokenFromUrl); + const { proposal, loading, error } = useProposal( + tokenFromUrl, + proposalPageSize + ); const rawMarkdown = proposal ? getMarkdownContent(proposal.files) : null; return !loading && !error ? (
diff --git a/src/components/RecordsView/RecordsView.jsx b/src/components/RecordsView/RecordsView.jsx index b44c21666..cba1bef21 100644 --- a/src/components/RecordsView/RecordsView.jsx +++ b/src/components/RecordsView/RecordsView.jsx @@ -6,11 +6,7 @@ import { getRecordsByTabOption } from "./helpers"; import HelpMessage from "src/components/HelpMessage"; import { useConfig } from "src/containers/Config"; import { shortRecordToken } from "src/helpers"; -import { - NOJS_ROUTE_PREFIX, - PROPOSAL_STATUS_CENSORED, - PROPOSAL_PAGE_SIZE -} from "src/constants"; +import { NOJS_ROUTE_PREFIX, PROPOSAL_STATUS_CENSORED } from "src/constants"; const LoadingPlaceholders = ({ numberOfItems, placeholder }) => { const Item = placeholder; @@ -65,7 +61,7 @@ const RecordsView = ({ onSetIndex, hasMore, filterCensored, - pageSize = PROPOSAL_PAGE_SIZE, + pageSize, sort }) => { const [loadingItems, setLoadingItems] = useState(pageSize); diff --git a/src/constants.js b/src/constants.js index a1661a0de..b97083722 100644 --- a/src/constants.js +++ b/src/constants.js @@ -100,10 +100,6 @@ export const PROPOSAL_APPROVED = 8; export const PROPOSAL_COMMENT_UPVOTE = 1; export const PROPOSAL_COMMENT_DOWNVOTE = -1; -export const PROPOSAL_PAGE_SIZE = 5; -export const BILLING_STATUS_CHANGES_PAGE_SIZE = 5; -export const INVENTORY_PAGE_SIZE = 20; - // Proposals presentational statuses returned by the 'voteinv' & // 'proposalinv' endpoints from the API. export const UNREVIEWED = "unreviewed"; diff --git a/src/containers/Comments/Download/DownloadCommentsTimestamps.jsx b/src/containers/Comments/Download/DownloadCommentsTimestamps.jsx index 22972a639..3031efc67 100644 --- a/src/containers/Comments/Download/DownloadCommentsTimestamps.jsx +++ b/src/containers/Comments/Download/DownloadCommentsTimestamps.jsx @@ -3,6 +3,7 @@ import DownloadJSON from "src/components/DownloadJSON"; import { useDownloadCommentsTimestamps } from "./hooks"; import { Spinner, Link } from "pi-ui"; import { loadCommentsTimestamps } from "src/lib/local_storage"; +import { usePolicy } from "src/hooks"; const DownloadCommentsTimestampsWrapper = ({ label, @@ -23,8 +24,11 @@ const DownloadCommentsTimestampsWrapper = ({ }; const DownloadCommentsTimestamps = ({ recordToken }) => { + const { + policyComments: { timestampspagesize: timestampsPageSize } + } = usePolicy(); const { loading, progress, timestamps, multiPage } = - useDownloadCommentsTimestamps(recordToken); + useDownloadCommentsTimestamps(recordToken, timestampsPageSize); return loading ? ( <> diff --git a/src/containers/Comments/Download/hooks.js b/src/containers/Comments/Download/hooks.js index 939db8a1e..cbacf2e41 100644 --- a/src/containers/Comments/Download/hooks.js +++ b/src/containers/Comments/Download/hooks.js @@ -35,8 +35,7 @@ export function useDownloadComments(token) { return { comments, onFetchCommentsTimestamps }; } -const TIMESTAMPS_PAGE_SIZE = 100; -export function useDownloadCommentsTimestamps(recordToken) { +export function useDownloadCommentsTimestamps(recordToken, timestampsPageSize) { const [timestamps, setTimestamps] = useState(null); const [remaining, setRemaining] = useState([]); const [progress, setProgress] = useState(0); @@ -50,7 +49,7 @@ export function useDownloadCommentsTimestamps(recordToken) { [allCommentsBySection] ); const commentsLength = comments?.length || 0; - const multiPage = commentsLength > TIMESTAMPS_PAGE_SIZE; + const multiPage = commentsLength > timestampsPageSize; const onFetchCommentsTimestamps = useAction(act.onFetchCommentsTimestamps); useEffect(() => { @@ -59,8 +58,8 @@ export function useDownloadCommentsTimestamps(recordToken) { }, [comments]); const getCommentIdsForPagination = (commentIds) => [ - take(TIMESTAMPS_PAGE_SIZE)(commentIds), - takeRight(commentIds.length - TIMESTAMPS_PAGE_SIZE)(commentIds) + take(timestampsPageSize)(commentIds), + takeRight(commentIds.length - timestampsPageSize)(commentIds) ]; const getProgressPercentage = useCallback( diff --git a/src/containers/Invoice/Edit/Edit.jsx b/src/containers/Invoice/Edit/Edit.jsx index 9a98fd8cf..29f772768 100644 --- a/src/containers/Invoice/Edit/Edit.jsx +++ b/src/containers/Invoice/Edit/Edit.jsx @@ -9,11 +9,15 @@ import { useEditInvoice } from "./hooks"; import { fromUSDCentsToUSDUnits } from "src/helpers"; import InvoiceLoader from "src/components/Invoice/InvoiceLoader"; import InvoiceForm from "src/components/InvoiceForm"; +import usePolicy from "src/hooks/api/usePolicy"; const EditInvoice = ({ match }) => { const tokenFromUrl = get("params.token", match); const { onEditInvoice } = useEditInvoice(); const { invoice, loading, error } = useInvoice(tokenFromUrl); + const { + policyTicketVote: { summariespagesize: proposalPageSize } + } = usePolicy(); const isInvoiceLoaded = !loading && !!invoice; @@ -37,7 +41,7 @@ const EditInvoice = ({ match }) => { : null; const { proposalsNotRFP: proposals, error: proposalsError } = - useApprovedProposals(); + useApprovedProposals(proposalPageSize); return ( {error ? ( diff --git a/src/containers/Invoice/New/New.jsx b/src/containers/Invoice/New/New.jsx index 16a57680e..958ea08f8 100644 --- a/src/containers/Invoice/New/New.jsx +++ b/src/containers/Invoice/New/New.jsx @@ -3,10 +3,15 @@ import { Card } from "pi-ui"; import InvoiceForm from "src/components/InvoiceForm"; import { useNewInvoice } from "./hooks"; import useApprovedProposals from "src/hooks/api/useApprovedProposals"; +import usePolicy from "src/hooks/api/usePolicy"; const NewInvoice = () => { + const { + policyTicketVote: { summariespagesize: proposalPageSize } + } = usePolicy(); const { onSubmitInvoice } = useNewInvoice(); - const { proposalsNotRFP: proposals, error } = useApprovedProposals(); + const { proposalsNotRFP: proposals, error } = + useApprovedProposals(proposalPageSize); return ( diff --git a/src/containers/Proposal/Admin/Admin.jsx b/src/containers/Proposal/Admin/Admin.jsx index 4bb9203d4..d90c945d9 100644 --- a/src/containers/Proposal/Admin/Admin.jsx +++ b/src/containers/Proposal/Admin/Admin.jsx @@ -5,6 +5,7 @@ import ProposalLoader from "src/components/Proposal/ProposalLoader"; import useQueryStringWithIndexValue from "src/hooks/utils/useQueryStringWithIndexValue"; import { tabValues, statusByTab } from "./helpers"; import { mapProposalsTokensByTab } from "src/containers/Proposal/helpers"; +import usePolicy from "src/hooks/api/usePolicy"; import { UnvettedActionsProvider, PublicActionsProvider @@ -24,6 +25,12 @@ const AdminProposals = ({ TopBanner, PageDetails, Main }) => { 0, tabLabels ); + const { + policyTicketVote: { + summariespagesize: proposalPageSize, + inventorypagesize: inventoryPageSize + } + } = usePolicy(); const { proposals, proposalsTokens, @@ -37,7 +44,9 @@ const AdminProposals = ({ TopBanner, PageDetails, Main }) => { fetchVoteSummary: false, fetchProposalSummary: true, unvetted: true, - proposalStatus: statusByTab[tabLabels[tabIndex]] + proposalStatus: statusByTab[tabLabels[tabIndex]], + proposalPageSize: proposalPageSize, + inventoryPageSize: inventoryPageSize }); const getEmptyMessage = useCallback((tab) => { @@ -70,6 +79,7 @@ const AdminProposals = ({ TopBanner, PageDetails, Main }) => { onFetchMoreProposals={onFetchMoreProposals} dropdownTabsForMobile={true} hasMore={hasMoreProposals} + pageSize={proposalPageSize} isLoading={loading || verifying} getEmptyMessage={getEmptyMessage}> {({ tabs, content }) => ( diff --git a/src/containers/Proposal/Detail/Detail.jsx b/src/containers/Proposal/Detail/Detail.jsx index 11820c54a..7538e409f 100644 --- a/src/containers/Proposal/Detail/Detail.jsx +++ b/src/containers/Proposal/Detail/Detail.jsx @@ -9,7 +9,8 @@ import { usePaywall, useIdentity, useDocumentTitle, - useModalContext + useModalContext, + usePolicy } from "src/hooks"; import Comments from "src/containers/Comments"; import ProposalLoader from "src/components/Proposal/ProposalLoader"; @@ -49,6 +50,9 @@ const SetPageTitle = ({ title }) => { const ProposalDetail = ({ Main, match, history }) => { const tokenFromUrl = shortRecordToken(get("params.token", match)); const threadParentCommentID = get("params.commentid", match); + const { + policyTicketVote: { summariespagesize: proposalPageSize } + } = usePolicy(); const { proposal, loading, @@ -64,7 +68,7 @@ const ProposalDetail = ({ Main, match, history }) => { commentsLoading, onReloadProposalDetails, billingStatusChangeUsername - } = useProposal(tokenFromUrl, threadParentCommentID); + } = useProposal(tokenFromUrl, proposalPageSize, threadParentCommentID); const { userid } = currentUser || {}; const isSingleThread = !!threadParentID; const proposalToken = getProposalToken(proposal); diff --git a/src/containers/Proposal/Detail/hooks.js b/src/containers/Proposal/Detail/hooks.js index 55f75cec2..4fe2b127c 100644 --- a/src/containers/Proposal/Detail/hooks.js +++ b/src/containers/Proposal/Detail/hooks.js @@ -50,7 +50,7 @@ const getProposalRfpLinksTokens = (proposal) => { return isSubmission ? [proposal.linkto] : proposal.linkedfrom; }; -export function useProposal(token, threadParentID) { +export function useProposal(token, proposalPageSize, threadParentID) { const tokenShort = shortRecordToken(token); const onFetchProposalDetails = useAction(act.onFetchProposalDetails); const onFetchProposalsBatch = useAction(act.onFetchProposalsBatch); @@ -191,8 +191,10 @@ export function useProposal(token, threadParentID) { }, verify: () => { if (hasRemainingTokens) { - const [tokensBatch, next] = - getTokensForProposalsPagination(remainingTokens); + const [tokensBatch, next] = getTokensForProposalsPagination( + remainingTokens, + proposalPageSize + ); // Fetch vote & proposal summaries only if the proposal is a RFP. // If it is a submission, just grab the records info. onFetchProposalsBatch({ diff --git a/src/containers/Proposal/Download/DownloadVotesTimestamps.jsx b/src/containers/Proposal/Download/DownloadVotesTimestamps.jsx index 2810921f3..eb0e3dee7 100644 --- a/src/containers/Proposal/Download/DownloadVotesTimestamps.jsx +++ b/src/containers/Proposal/Download/DownloadVotesTimestamps.jsx @@ -4,6 +4,7 @@ import DownloadJSON from "src/components/DownloadJSON"; import { useDownloadVoteTimestamps } from "./hooks"; import { Spinner, Link } from "pi-ui"; import { loadVotesTimestamps } from "src/lib/local_storage"; +import { usePolicy } from "src/hooks"; const DownloadVotesTimestampsWrapper = ({ label, recordToken, votesCount }) => { const [start, setStart] = useState(false); @@ -26,8 +27,13 @@ const DownloadVotesTimestampsWrapper = ({ label, recordToken, votesCount }) => { }; const DownloadVotesTimestamps = ({ recordToken, votesCount }) => { + const { + policy: { + policyTicketVote: { timestampspagesize: timestampsPageSize } + } + } = usePolicy(); const { timestamps, progress, loading, error, multiPage } = - useDownloadVoteTimestamps(recordToken, votesCount); + useDownloadVoteTimestamps(recordToken, votesCount, timestampsPageSize); return loading ? ( <> diff --git a/src/containers/Proposal/Download/hooks.js b/src/containers/Proposal/Download/hooks.js index 4ca051934..0d6b2cd61 100644 --- a/src/containers/Proposal/Download/hooks.js +++ b/src/containers/Proposal/Download/hooks.js @@ -8,22 +8,25 @@ import { loadVotesTimestamps } from "src/lib/local_storage"; -const TIMESTAMPS_PAGE_SIZE = 100; -export function useDownloadVoteTimestamps(token, votesCount) { +export function useDownloadVoteTimestamps( + token, + votesCount, + timestampsPageSize +) { const [votes, setVotes] = useState(null); const [auths, setAuths] = useState(null); const [details, setDetails] = useState(null); const [page, setPage] = useState(1); const [progress, setProgress] = useState(0); - const multiPage = votesCount > TIMESTAMPS_PAGE_SIZE; + const multiPage = votesCount > timestampsPageSize; const onFetchTicketVoteTimestamps = useAction( act.onFetchTicketVoteTimestamps ); const getProgressPercentage = useCallback( (total) => - total ? ((total * TIMESTAMPS_PAGE_SIZE) / votesCount).toFixed(0) : 0, - [votesCount] + total ? ((total * timestampsPageSize) / votesCount).toFixed(0) : 0, + [votesCount, timestampsPageSize] ); useEffect(() => { diff --git a/src/containers/Proposal/Edit/Edit.jsx b/src/containers/Proposal/Edit/Edit.jsx index 6128419b9..3bfffc670 100644 --- a/src/containers/Proposal/Edit/Edit.jsx +++ b/src/containers/Proposal/Edit/Edit.jsx @@ -20,10 +20,14 @@ import { getMarkdownContent, isPublicProposal } from "../helpers"; import { formatUnixTimestampToObj } from "src/utils"; import { getAttachmentsFiles } from "src/helpers"; import { usdFormatter } from "src/utils"; +import usePolicy from "src/hooks/api/usePolicy"; const EditProposal = ({ match }) => { const tokenFromUrl = get("params.token", match); - const { proposal, loading } = useProposal(tokenFromUrl); + const { + policyTicketVote: { summariespagesize: proposalPageSize } + } = usePolicy(); + const { proposal, loading } = useProposal(tokenFromUrl, proposalPageSize); const isPublic = isPublicProposal(proposal); const { onEditProposal, currentUser } = useEditProposal(); const { userid } = currentUser || {}; diff --git a/src/containers/Proposal/User/Submitted.jsx b/src/containers/Proposal/User/Submitted.jsx index c7c03c683..3843744ac 100644 --- a/src/containers/Proposal/User/Submitted.jsx +++ b/src/containers/Proposal/User/Submitted.jsx @@ -9,8 +9,7 @@ import { import LazyList from "src/components/LazyList"; import LoadingPlaceholders from "src/components/LoadingPlaceholders"; import HelpMessage from "src/components/HelpMessage"; - -const PAGE_SIZE = 20; +import usePolicy from "src/hooks/api/usePolicy"; const Proposals = (props) => { const renderProposal = (record) => { @@ -20,8 +19,11 @@ const Proposals = (props) => { const [hasMoreToLoad, setHasMore] = useState(false); const { userID } = props; + const { + policyTicketVote: { summariespagesize: proposalPageSize } + } = usePolicy(); const { proposals, loading, numOfUserProposals, onFetchMoreProposals } = - useUserProposals({ userID }); + useUserProposals({ proposalPageSize, userID }); const amountOfProposalsFetched = proposals ? proposals.length : 0; @@ -53,7 +55,9 @@ const Proposals = (props) => { const amountOfMissingProposals = numOfUserProposals - amountOfProposalsFetched; const itemsToBeLoaded = - amountOfMissingProposals > PAGE_SIZE ? PAGE_SIZE : amountOfMissingProposals; + amountOfMissingProposals > proposalPageSize + ? proposalPageSize + : amountOfMissingProposals; return ( diff --git a/src/containers/Proposal/User/hooks.js b/src/containers/Proposal/User/hooks.js index cb0b915fc..b5f346fa4 100644 --- a/src/containers/Proposal/User/hooks.js +++ b/src/containers/Proposal/User/hooks.js @@ -21,7 +21,6 @@ import isEmpty from "lodash/fp/isEmpty"; import keys from "lodash/fp/keys"; import difference from "lodash/fp/difference"; import assign from "lodash/fp/assign"; -import { PROPOSAL_PAGE_SIZE } from "src/constants"; import { getRfpLinkedProposals, getTokensForProposalsPagination @@ -81,7 +80,7 @@ const getUnfetchedTokens = (proposals, tokens) => difference(tokens)(keys(proposals)); export function useUserProposals({ - proposalPageSize = PROPOSAL_PAGE_SIZE, + proposalPageSize, fetchRfpLinks = true, fetchVoteSummary = true, fetchProposalSummary = true, diff --git a/src/containers/Proposal/Vetted/Vetted.jsx b/src/containers/Proposal/Vetted/Vetted.jsx index 270b8013b..c22a364fd 100644 --- a/src/containers/Proposal/Vetted/Vetted.jsx +++ b/src/containers/Proposal/Vetted/Vetted.jsx @@ -1,4 +1,5 @@ import React, { useCallback, useMemo } from "react"; +import get from "lodash/get"; import isEmpty from "lodash/fp/isEmpty"; import styles from "./VettedProposals.module.css"; import { tabValues, statusByTab, sortByTab } from "./helpers"; @@ -13,6 +14,7 @@ import ProposalLoader from "src/components/Proposal/ProposalLoader"; import { PublicActionsProvider } from "src/containers/Proposal/Actions"; import RecordsView from "src/components/RecordsView"; import { LIST_HEADER_VETTED, INELIGIBLE } from "src/constants"; +import usePolicy from "src/hooks/api/usePolicy"; const renderProposal = (record) => ( @@ -29,6 +31,16 @@ const VettedProposals = ({ TopBanner, PageDetails, Sidebar, Main }) => { const [index, onSetIndex] = useQueryStringWithIndexValue("tab", 0, tabLabels); const statuses = statusByTab[tabLabels[index]]; const sort = sortByTab[tabLabels[index]]; + const policy = usePolicy(); + const proposalPageSize = get(policy, [ + "policyTicketVote", + "summariespagesize" + ]); + const inventoryPageSize = get(policy, [ + "policyTicketVote", + "inventorypagesize" + ]); + const { proposals, proposalsTokens, @@ -40,9 +52,12 @@ const VettedProposals = ({ TopBanner, PageDetails, Sidebar, Main }) => { isProposalsBatchComplete } = useProposalsBatch({ fetchRfpLinks: true, + fetchVoteSummaries: true, + statuses: statuses, + proposalPageSize: proposalPageSize, + inventoryPageSize: inventoryPageSize, fetchVoteSummary: true, - fetchProposalSummary: true, - statuses: statuses + fetchProposalSummary: true }); // TODO: remove legacy @@ -124,6 +139,7 @@ const VettedProposals = ({ TopBanner, PageDetails, Sidebar, Main }) => { onFetchMoreProposals={onFetchMoreProposals} dropdownTabsForMobile hasMore={hasMoreProposals} + pageSize={proposalPageSize} isLoading={loading || verifying} sort={sort}> {content} diff --git a/src/containers/Proposal/helpers.js b/src/containers/Proposal/helpers.js index ad3e979c6..ad4ed40e4 100644 --- a/src/containers/Proposal/helpers.js +++ b/src/containers/Proposal/helpers.js @@ -30,7 +30,6 @@ import { PROPOSAL_VOTING_REJECTED, PROPOSAL_VOTING_INELIGIBLE, INELIGIBLE, - PROPOSAL_PAGE_SIZE, UNAUTHORIZED } from "src/constants"; import { getTextFromIndexMd, shortRecordToken } from "src/helpers"; @@ -453,10 +452,10 @@ export const getProposalLink = (proposal, isJsEnabled) => * @param {*} tokens * @param {*} pageSize */ -export const getTokensForProposalsPagination = ( - tokens, - pageSize = PROPOSAL_PAGE_SIZE -) => [take(pageSize)(tokens), takeRight(tokens.length - pageSize)(tokens)]; +export const getTokensForProposalsPagination = (tokens, pageSize) => [ + take(pageSize)(tokens), + takeRight(tokens.length - pageSize)(tokens) +]; /** * Returns the proposal tokens by status from an inventory of tokens diff --git a/src/containers/User/Detail/ManageContractor/ManageDccForm.jsx b/src/containers/User/Detail/ManageContractor/ManageDccForm.jsx index b05d2d128..92213c679 100644 --- a/src/containers/User/Detail/ManageContractor/ManageDccForm.jsx +++ b/src/containers/User/Detail/ManageContractor/ManageDccForm.jsx @@ -39,8 +39,10 @@ const ManageDccForm = ({ onUpdate, user }) => { proposalsowned = [] } = user; const { - policy: { supporteddomains } + policy: { supporteddomains }, + policyTicketVote: { summariespagesize: proposalPageSize } } = usePolicy(); + const contractorDomains = getContractorDomains(supporteddomains); const [updated, setUpdated] = useState(false); @@ -58,7 +60,7 @@ const ManageDccForm = ({ onUpdate, user }) => { proposals, isLoading: loadingOwnedProposals, error: approvedProposalsError - } = useApprovedProposals(); + } = useApprovedProposals(proposalPageSize); const { proposalsOptions, initialOwnedProposals } = getInitialAndOptionsProposals(proposals, proposalsowned); diff --git a/src/containers/User/Detail/ManageContractor/UserView.jsx b/src/containers/User/Detail/ManageContractor/UserView.jsx index c15d86bb3..70d253058 100644 --- a/src/containers/User/Detail/ManageContractor/UserView.jsx +++ b/src/containers/User/Detail/ManageContractor/UserView.jsx @@ -15,11 +15,14 @@ const UserDccInfo = ({ onToggleDccEdit, supervisorsError }) => { + const { + policyTicketVote: { summariespagesize: proposalPageSize } + } = usePolicy(); const { proposalsByToken, isLoading, error: proposalsError - } = useApprovedProposals(proposalsOwned); + } = useApprovedProposals(proposalsOwned, proposalPageSize); const ownedProposals = getOwnedProposals(proposalsOwned, proposalsByToken); diff --git a/src/containers/User/Detail/ProposalsOwned/ProposalsOwned.jsx b/src/containers/User/Detail/ProposalsOwned/ProposalsOwned.jsx index 2f1f2d2d7..91fae52c9 100644 --- a/src/containers/User/Detail/ProposalsOwned/ProposalsOwned.jsx +++ b/src/containers/User/Detail/ProposalsOwned/ProposalsOwned.jsx @@ -4,10 +4,16 @@ import useApprovedProposals from "src/hooks/api/useApprovedProposals"; import { Spinner, H3, Message } from "pi-ui"; import isEmpty from "lodash/fp/isEmpty"; import styles from "./ProposalsOwned.module.css"; +import usePolicy from "src/hooks/api/usePolicy"; const ProposalsOwned = ({ proposalsOwned }) => { - const { proposalsByToken, isLoading, error } = - useApprovedProposals(proposalsOwned); + const { + policyTicketVote: { summariespagesize: proposalPageSize } + } = usePolicy(); + const { proposalsByToken, isLoading, error } = useApprovedProposals( + proposalsOwned, + proposalPageSize + ); const loading = (isLoading || isEmpty(proposalsByToken)) && !error; return loading ? ( diff --git a/src/containers/User/Search/Search.jsx b/src/containers/User/Search/Search.jsx index b8ad0f7b9..bde93a691 100644 --- a/src/containers/User/Search/Search.jsx +++ b/src/containers/User/Search/Search.jsx @@ -22,6 +22,7 @@ import Link from "src/components/Link"; import { usePolicy } from "src/hooks"; import { searchSchema } from "./validation"; import { getContractorDomains, getDomainName } from "src/helpers"; +import get from "lodash/get"; const getFormattedSearchResults = (users = [], isCMS, supporteddomains) => users.map((u) => @@ -52,10 +53,8 @@ const UserSearch = ({ TopBanner, PageDetails, Main, Title }) => { const [searchError, setSearchError] = useState(null); const [foundUsers, setFoundUsers] = useState([]); const [filterValue, setFilterValue] = useState(); // filters on the client-side - const { - policy: { supporteddomains } - } = usePolicy(); - const contractorDomains = isCMS ? getContractorDomains(supporteddomains) : []; + const supportedDomains = get(usePolicy(), ["policyPi", "domains"]); + const contractorDomains = isCMS ? getContractorDomains(supportedDomains) : []; const searchOptions = useMemo(() => { if (isCMS) { return [ @@ -112,11 +111,11 @@ const UserSearch = ({ TopBanner, PageDetails, Main, Title }) => { const filteredResult = filterUserResult(searchResult, filterValue); if (filteredResult) { setFoundUsers( - getFormattedSearchResults(filteredResult, isCMS, supporteddomains) + getFormattedSearchResults(filteredResult, isCMS, supportedDomains) ); } }, - [searchResult, isCMS, supporteddomains, filterValue] + [searchResult, isCMS, filterValue, supportedDomains] ); return ( diff --git a/src/hooks/api/useApprovedProposals.js b/src/hooks/api/useApprovedProposals.js index 9a71bb33d..ea6669af8 100644 --- a/src/hooks/api/useApprovedProposals.js +++ b/src/hooks/api/useApprovedProposals.js @@ -2,9 +2,7 @@ import { useEffect, useState, useMemo } from "react"; import useProposalsBatch from "./useProposalsBatch"; import { difference, keys } from "lodash"; -const PAGE_SIZE = 20; - -export default function useApprovedProposals(initialTokens) { +export default function useApprovedProposals(proposalPageSize, initialTokens) { const [remainingTokens, setRemainingTokens] = useState(initialTokens); const { proposals, proposalsTokens, loading, verifying } = useProposalsBatch( remainingTokens, @@ -22,11 +20,11 @@ export default function useApprovedProposals(initialTokens) { proposalsTokens.approved && difference(proposalsTokens.approved, keys(proposals)).splice( 0, - PAGE_SIZE + proposalPageSize ); setRemainingTokens(tokens); } - }, [proposals, proposalsTokens.approved, isLoading]); + }, [proposals, proposalsTokens.approved, isLoading, proposalPageSize]); const proposalsNotRFP = useMemo( () => proposals && Object.values(proposals).filter((p) => !p.linkby), diff --git a/src/hooks/api/useProposalsBatch.js b/src/hooks/api/useProposalsBatch.js index 51cfebb33..5a211768c 100644 --- a/src/hooks/api/useProposalsBatch.js +++ b/src/hooks/api/useProposalsBatch.js @@ -1,4 +1,4 @@ -import { useCallback, useMemo, useState } from "react"; +import { useCallback, useMemo, useState, useEffect } from "react"; import * as sel from "src/selectors"; import * as act from "src/actions"; import { or } from "src/lib/fp"; @@ -23,8 +23,6 @@ import keys from "lodash/fp/keys"; import difference from "lodash/fp/difference"; import assign from "lodash/fp/assign"; import { - INVENTORY_PAGE_SIZE, - PROPOSAL_PAGE_SIZE, PROPOSAL_STATE_UNVETTED, PROPOSAL_STATE_VETTED, PROPOSAL_STATUS_UNREVIEWED, @@ -58,10 +56,6 @@ const getUnfetchedTokens = (proposals, tokens) => keys(proposals).map((token) => shortRecordToken(token)) ); -const getCurrentPage = (tokens) => { - return tokens ? Math.floor(+tokens.length / INVENTORY_PAGE_SIZE) : 0; -}; - const cacheVoteStatus = {}; const updateCacheVoteStatusMap = (voteSummaries, isRefresh) => { @@ -94,7 +88,8 @@ export default function useProposalsBatch({ unvetted = false, proposalStatus, statuses, - proposalPageSize = PROPOSAL_PAGE_SIZE + proposalPageSize, + inventoryPageSize }) { const [remainingTokens, setRemainingTokens] = useState([]); const [voteStatuses, setStatuses] = useState(statuses); @@ -132,7 +127,9 @@ export default function useProposalsBatch({ () => allByStatus[status] || [], [allByStatus, status] ); - const page = useMemo(() => getCurrentPage(tokens), [tokens]); + const page = useMemo(() => { + return tokens ? Math.floor(+tokens.length / inventoryPageSize) : 0; + }, [tokens, inventoryPageSize]); const errorSelector = useMemo( () => or(sel.apiProposalsBatchError, sel.apiPropsVoteSummaryError), [] @@ -169,6 +166,7 @@ export default function useProposalsBatch({ actions: { initial: () => send(START), start: () => { + if (!proposalPageSize) return send(RESOLVE); if (remainingTokens.length > proposalPageSize) return send(VERIFY); // If remaining tokens length is smaller than proposal page size. // Find more tokens from inventory or scan from the next status @@ -177,7 +175,7 @@ export default function useProposalsBatch({ // there are no tokens to be fetched from the next page const scanNextStatus = initializedInventory && - (!(tokens.length % INVENTORY_PAGE_SIZE === 0 && tokens.length > 0) || + (!(tokens.length % inventoryPageSize === 0 && tokens.length > 0) || remainingTokens.length === proposalPageSize); if (scanNextStatus) { const { index, tokens } = scanNextStatusTokens( @@ -357,7 +355,7 @@ export default function useProposalsBatch({ !getUnfetchedTokens(proposals, tokens).length; const isAnotherTokensScanningRequired = - tokens && tokens.length && tokens.length % INVENTORY_PAGE_SIZE === 0; + tokens && tokens.length && tokens.length % inventoryPageSize === 0; const onFetchMoreProposals = useCallback(() => { if (remainingTokens.length < proposalPageSize) return send(START); @@ -368,6 +366,13 @@ export default function useProposalsBatch({ const anyError = error || state.error; useThrowError(anyError); + // Recall fetch machine when proposalPageSize is changed. Since it is + // not hard code and be fetched from policy and will be undefined when + // the policy is not fetched yet. + useEffect(() => { + send(START); + }, [proposalPageSize, send]); + return { proposals: getRfpLinkedProposals( proposalWithCacheVotetatus(proposals), diff --git a/teste2e/cypress/e2e/proposal/edit.js b/teste2e/cypress/e2e/proposal/edit.js index 7faef42e1..fdad9e247 100644 --- a/teste2e/cypress/e2e/proposal/edit.js +++ b/teste2e/cypress/e2e/proposal/edit.js @@ -108,7 +108,7 @@ describe("Proposal Edit", () => { }) => { cy.approveProposal(censorshiprecord); cy.visit(`record/${shortRecordToken(censorshiprecord.token)}`); - cy.wait(1000); + cy.wait(3000); cy.findByTestId(/record-edit-button/i).click(); cy.findByRole("button", { name: /submit/i }).should("be.disabled"); } diff --git a/teste2e/cypress/utils.js b/teste2e/cypress/utils.js index dff67b124..b96c027c1 100644 --- a/teste2e/cypress/utils.js +++ b/teste2e/cypress/utils.js @@ -31,6 +31,7 @@ const PROPOSAL_STATUS_UNREVIEWED = 1; const PROPOSAL_STATUS_PUBLIC = 2; const PROPOSAL_STATUS_CENSORED = 3; const PROPOSAL_STATUS_ARCHIVED = 4; + export const PROPOSAL_SUMMARY_STATUS_UNVETTED = "unvetted"; export const PROPOSAL_SUMMARY_STATUS_UNVETTED_ABANDONED = "unvetted-abandoned"; export const PROPOSAL_SUMMARY_STATUS_UNVETTED_CENSORED = "unvetted-censored";