Skip to content

Commit

Permalink
fix: Proposal diff bugs.
Browse files Browse the repository at this point in the history
* Fix: after clicking on version button, duplicate request are sent to
  the server.
* Fix: Hide the version button when the proposal is cencered or when
  the proposal is unvetted and the user is not admin or author.
* Fix: Title text is overlap in the mobile screen.
  • Loading branch information
vibros68 committed Oct 21, 2021
1 parent 146dfc1 commit a75198c
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 76 deletions.
16 changes: 4 additions & 12 deletions src/components/ModalDiff/DiffProposal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,15 @@ const DiffProposal = ({ latest, initVersion, token, ...props }) => {
const {
baseVersion,
compareVersion,
baseLoading,
compareLoading,
changedVersion,
baseProposal,
compareProposal
compareProposal,
loading
} = useCompareVersionSelector(initVersion, token);

const isDiffAvailable = useMemo(() => {
return (
!!baseProposal.details &&
!!compareProposal.details &&
!baseLoading &&
!compareLoading
);
}, [baseProposal, compareProposal, baseLoading, compareLoading]);
return !!baseProposal.details && !!compareProposal.details && !loading;
}, [baseProposal, compareProposal, loading]);

const [activeTabIndex, setActiveTabIndex] = useState(0);
useEffect(() => {
Expand All @@ -54,8 +48,6 @@ const DiffProposal = ({ latest, initVersion, token, ...props }) => {
onChange={changedVersion}
base={baseVersion}
compare={compareVersion}
baseLoading={baseLoading}
compareLoading={compareLoading}
/>
{isDiffAvailable ? (
<>
Expand Down
148 changes: 87 additions & 61 deletions src/components/ModalDiff/hooks.js
Original file line number Diff line number Diff line change
@@ -1,46 +1,97 @@
import { useState, useCallback, useEffect } from "react";
import { useState, useMemo } from "react";
import { COMPARE, BASE } from "./constants";
import * as act from "src/actions";
import { useAction } from "src/redux";
import drop from "lodash/drop";
import { getAttachmentsFiles, parseRawProposal } from "src/helpers";
import useFetchMachine, {
FETCH,
REJECT,
RESOLVE,
START
} from "src/hooks/utils/useFetchMachine";

const parseProposal = (proposal) => {
if (!proposal) {
// Return empty data for case: proposal = undefined.
return {
details: {},
files: [],
text: "",
title: ""
};
}
// Parse current version.
const { description, name } = parseRawProposal(proposal);
return {
details: proposal,
files: getAttachmentsFiles(proposal.files),
text: description,
title: name
};
};

export function useCompareVersionSelector(initVersion, token) {
const [versionsQueue, setVersionsQueue] = useState([
initVersion,
initVersion - 1
]);
const [fetchedProposals, setFetchedProposals] = useState({});
const [baseVersion, setBaseVersion] = useState(initVersion - 1);
const [compareVersion, setCompareVersion] = useState(initVersion);
const [baseLoading, setBaseLoading] = useState(false);
const [compareLoading, setCompareLoading] = useState(false);
const [compareProposal, setCompareProposal] = useState({});
const [baseProposal, setBaseProposal] = useState({});
const [error, setError] = useState();

const baseProposal = useMemo(() => {
const proposal = fetchedProposals[baseVersion];
return parseProposal(proposal);
}, [baseVersion, fetchedProposals]);
const compareProposal = useMemo(() => {
const proposal = fetchedProposals[compareVersion];
return parseProposal(proposal);
}, [compareVersion, fetchedProposals]);
const onFetchProposalDetailsWithoutState = useAction(
act.onFetchProposalDetailsWithoutState
);

const fetchProposalVersions = useCallback(
async (token, version) => {
if (!version) {
// Return empty data for case: version = 0.
return {
details: {},
files: [],
text: "",
title: ""
};
}
// Fetch provided version.
const proposal = await onFetchProposalDetailsWithoutState(token, version);
// Parse current version.
const { description, name } = parseRawProposal(proposal);
return {
details: proposal,
files: getAttachmentsFiles(proposal.files),
text: description,
title: name
};
const [state, send] = useFetchMachine({
actions: {
initial: () => {
if (versionsQueue.length) {
return send(START);
}
return send(RESOLVE);
},
start: () => {
if (!versionsQueue.length) {
return send(RESOLVE);
}
const version = versionsQueue[0];
if (version <= 0) {
setVersionsQueue(drop(versionsQueue));
return send(START);
}
onFetchProposalDetailsWithoutState(token, version)
.then((proposal) => {
setFetchedProposals({
...fetchedProposals,
[version]: proposal
});
setVersionsQueue(drop(versionsQueue));
if (setVersionsQueue.length) {
return send(START);
}
return send(RESOLVE);
})
.catch((e) => send(REJECT, e));

return send(FETCH);
},
done: () => {}
},
[onFetchProposalDetailsWithoutState]
);
initialValues: {
status: "idle",
loading: true,
verifying: true
}
});

const changedVersion = (versionType, v) => {
if (versionType === COMPARE) {
Expand All @@ -49,44 +100,19 @@ export function useCompareVersionSelector(initVersion, token) {
if (versionType === BASE) {
setBaseVersion(v);
}
if (!fetchedProposals[v]) {
setVersionsQueue([v, ...versionsQueue]);
send(START);
}
};

useEffect(() => {
setBaseLoading(true);
setError(null);
fetchProposalVersions(token, baseVersion)
.then((proposal) => {
setBaseLoading(false);
setBaseProposal(proposal);
})
.catch((e) => {
setError(e);
setBaseLoading(false);
});
}, [token, baseVersion, fetchProposalVersions]);

useEffect(() => {
setCompareLoading(true);
setError(null);
fetchProposalVersions(token, compareVersion)
.then((proposal) => {
setCompareLoading(false);
setCompareProposal(proposal);
})
.catch((e) => {
setError(e);
setCompareLoading(false);
});
}, [token, compareVersion, fetchProposalVersions]);
const fetchingNotDone = state.loading || state.status !== "success";

return {
baseVersion,
compareVersion,
baseLoading,
compareLoading,
changedVersion,
baseProposal,
compareProposal,
error
loading: fetchingNotDone
};
}
13 changes: 11 additions & 2 deletions src/components/Proposal/Proposal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ import {
getLegacyProposalStatusTagProps,
getStatusBarData
} from "./helpers";
import { PROPOSAL_TYPE_RFP, PROPOSAL_TYPE_RFP_SUBMISSION } from "src/constants";
import {
PROPOSAL_TYPE_RFP,
PROPOSAL_TYPE_RFP_SUBMISSION,
PROPOSAL_STATE_VETTED
} from "src/constants";
import {
getMarkdownContent,
getVotesReceived,
Expand Down Expand Up @@ -56,6 +60,8 @@ import useModalContext from "src/hooks/utils/useModalContext";
import { useRouter } from "src/components/Router";
import { shortRecordToken, isEmpty, getKeyByValue } from "src/helpers";
import { usdFormatter } from "src/utils";
import * as sel from "src/selectors";
import { useSelector } from "../../redux";

/**
* replaceImgDigestWithPayload uses a regex to parse images
Expand Down Expand Up @@ -152,6 +158,8 @@ const Proposal = React.memo(function Proposal({
startDate,
endDate
} = proposal;
const isAdmin = useSelector(sel.currentUserIsAdmin);
const isVetted = state === PROPOSAL_STATE_VETTED;
const isRfp = !!linkby || type === PROPOSAL_TYPE_RFP;
const isRfpSubmission = !!linkto || type === PROPOSAL_TYPE_RFP_SUBMISSION;
const isRfpActive = isRfp && isActiveRfp(linkby);
Expand Down Expand Up @@ -198,7 +206,8 @@ const Proposal = React.memo(function Proposal({
const mobile = useMediaQuery("(max-width: 560px)");
const showEditedDate = version > 1 && timestamp !== publishedat && !mobile;
const showPublishedDate = publishedat && !mobile && !showEditedDate;
const showExtendedVersionPicker = extended && version > 1;
const showExtendedVersionPicker =
extended && version > 1 && !isCensored && (isVetted || isAuthor || isAdmin);
const showVersionAsText = !extended && !mobile;
const showVoteEnd =
(isVoteActive || isVotingFinished) && !isAbandoned && !isCensored;
Expand Down
2 changes: 1 addition & 1 deletion src/components/RecordWrapper/RecordWrapper.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export const Subtitle = ({ children, separatorSymbol = "•" }) => (

export const JoinTitle = ({ children, className, separatorSymbol = "•" }) => (
<Join
className={classNames(className, styles.subtitleWrapper)}
className={classNames(className, styles.flexWrap)}
SeparatorComponent={() => (
<span className="text-secondary-color margin-left-s margin-right-s">
{separatorSymbol}
Expand Down
4 changes: 4 additions & 0 deletions src/components/RecordWrapper/RecordWrapper.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
flex-wrap: wrap;
}

.flexWrap {
flex-wrap: wrap;
}

.eventTooltip {
color: var(--text-secondary-color) !important;
}
Expand Down

0 comments on commit a75198c

Please sign in to comment.