Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Handle uninstalled Staged Expenditure extension #3402

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions amplify/backend/api/colonycdapp/schema/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -3733,6 +3733,14 @@ type Expenditure @model {
Hash of the first transaction that contained ExpenditurePayoutSet event
"""
firstEditTransactionHash: String
"""
Address of StagedExpenditure extension which set the expenditure as staged, if applicable
"""
stagedExpenditureAddress: ID
"""
Address of StakedExpenditure extension which created the expenditure, if applicable
"""
stakedExpenditureAddress: ID
}

"""
Expand Down
2 changes: 1 addition & 1 deletion docker/colony-cdapp-dev-env-block-ingestor
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
FROM colony-cdapp-dev-env/base:latest

ENV BLOCK_INGESTOR_HASH=001056dbc5a0e572e0dc09016dc320a019508d01
ENV BLOCK_INGESTOR_HASH=0b9de0c70356dd91aa6931d82e5dc051d2805af2

# Declare volumes to set up metadata
VOLUME [ "/colonyCDapp/amplify/mock-data" ]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import useHasNoDecisionMethods from '~v5/common/ActionSidebar/hooks/permissions/
import Table from '~v5/common/Table/Table.tsx';
import Button from '~v5/shared/Button/Button.tsx';

import { useStagedPaymentTableColumns } from './hooks.tsx';
import { useStagedPaymentRecipientsTableColumns } from './hooks.tsx';
import {
type StagedPaymentRecipientsTableModel,
type StagedPaymentRecipientsFieldProps,
Expand All @@ -35,7 +35,7 @@ const StagedPaymentRecipientsField: FC<StagedPaymentRecipientsFieldProps> = ({
key: id,
}));
const value: StagedPaymentRecipientsFieldModel[] = useWatch({ name }) || [];
const columns = useStagedPaymentTableColumns(name, value);
const columns = useStagedPaymentRecipientsTableColumns(name, value);
const { getFieldState } = useFormContext();
const fieldState = getFieldState(name);
const getMenuProps = ({ index }) => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import {
type StagedPaymentRecipientsFieldModel,
} from './types.ts';

export const useStagedPaymentTableColumns = (
export const useStagedPaymentRecipientsTableColumns = (
name: string,
data: StagedPaymentRecipientsFieldModel[],
) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -218,8 +218,7 @@ const PaymentBuilder = ({ action }: PaymentBuilderProps) => {
/>
<StagedPaymentTable
finalizedAt={finalizedAt || 0}
stages={expenditure.metadata?.stages || []}
slots={slots}
expenditure={expenditure}
isLoading={!expenditure.metadata?.stages?.length}
isPaymentStep={expenditureStep === ExpenditureStep.Payment}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ const PaymentBuilderWidget: FC<PaymentBuilderWidgetProps> = ({ action }) => {
});
const { user } = useAppContext();
const { walletAddress } = user || {};
const { isStagedExtensionInstalled } = useEnabledExtensions();
const { stagedExpenditureAddress } = useEnabledExtensions();

const {
isFundingModalOpen,
Expand Down Expand Up @@ -170,8 +170,14 @@ const PaymentBuilderWidget: FC<PaymentBuilderWidgetProps> = ({ action }) => {
(motion) =>
!motion.isFinalized && !motion.motionStateHistory.hasFailedNotFinalizable,
);
const hasUninstalledExtension =
expenditure?.stagedExpenditureAddress &&
stagedExpenditureAddress !== expenditure.stagedExpenditureAddress;

const shouldShowFundingButton =
!isAnyFundingMotionInProgress && !isExpenditureFunded;
!isAnyFundingMotionInProgress &&
!isExpenditureFunded &&
!hasUninstalledExtension;

const {
motionState: releaseMotionState,
Expand Down Expand Up @@ -282,7 +288,7 @@ const PaymentBuilderWidget: FC<PaymentBuilderWidgetProps> = ({ action }) => {
content:
expenditureStep === ExpenditureStep.Review ? (
<>
{!isStagedExtensionInstalled && isStagedExpenditure ? (
{hasUninstalledExtension ? (
<UninstalledExtensionBox />
) : (
<StepDetailsBlock
Expand Down Expand Up @@ -344,71 +350,68 @@ const PaymentBuilderWidget: FC<PaymentBuilderWidgetProps> = ({ action }) => {
) : null,
},
content: (
<>
{!isStagedExtensionInstalled && isStagedExpenditure ? (
<UninstalledExtensionBox />
) : (
<div className="flex flex-col gap-2">
{sortedFundingActions.length > 0 && (
<FundingRequests actions={sortedFundingActions} />
)}
<div className="flex flex-col gap-2">
{hasUninstalledExtension &&
expenditureStep === ExpenditureStep.Funding && (
<UninstalledExtensionBox />
)}

{selectedFundingMotion && (
<MotionBox
transactionId={selectedFundingMotion.transactionHash}
/>
)}
{sortedFundingActions.length > 0 && (
<FundingRequests actions={sortedFundingActions} />
)}

{selectedFundingAction && !selectedFundingMotion && (
<ActionWithPermissionsInfo action={selectedFundingAction} />
)}
{selectedFundingMotion && (
<MotionBox transactionId={selectedFundingMotion.transactionHash} />
)}

{shouldShowFundingButton && (
<StepDetailsBlock
text={formatText({
id: 'expenditure.fundingStage.info',
})}
content={
<>
{expectedStepKey === ExpenditureStep.Release ? (
<IconButton
className="w-full"
rounded="s"
text={{ id: 'button.pending' }}
icon={
<span className="ml-1.5 flex shrink-0">
<SpinnerGap className="animate-spin" size={14} />
</span>
}
/>
) : (
<Button
className="w-full"
onClick={showFundingModal}
text={formatText({
id: 'expenditure.fundingStage.button',
})}
/>
)}
</>
}
/>
)}
</div>
{selectedFundingAction && !selectedFundingMotion && (
<ActionWithPermissionsInfo action={selectedFundingAction} />
)}
</>

{shouldShowFundingButton && (
<StepDetailsBlock
text={formatText({
id: 'expenditure.fundingStage.info',
})}
content={
<>
{expectedStepKey === ExpenditureStep.Release ? (
<IconButton
className="w-full"
rounded="s"
text={{ id: 'button.pending' }}
icon={
<span className="ml-1.5 flex shrink-0">
<SpinnerGap className="animate-spin" size={14} />
</span>
}
/>
) : (
<Button
className="w-full"
onClick={showFundingModal}
text={formatText({
id: 'expenditure.fundingStage.button',
})}
/>
)}
</>
}
/>
)}
</div>
),
},
{
key: ExpenditureStep.Release,
heading: { label: formatText({ id: 'expenditure.releaseStage.label' }) },
content: (
<>
{!isStagedExtensionInstalled && isStagedExpenditure ? (
<UninstalledExtensionBox />
) : (
{expenditureStep === ExpenditureStep.Release ? (
<>
{expenditureStep === ExpenditureStep.Release ? (
{hasUninstalledExtension ? (
<UninstalledExtensionBox />
) : (
<StepDetailsBlock
text={formatText({
id: 'expenditure.releaseStage.info',
Expand All @@ -424,25 +427,25 @@ const PaymentBuilderWidget: FC<PaymentBuilderWidgetProps> = ({ action }) => {
/>
}
/>
) : (
)}
</>
) : (
<>
{finalizedAt ? (
<>
{finalizedAt ? (
<>
{finalizingActions?.items[0]?.initiatorAddress ===
ownerAddress ? (
<FinalizeByPaymentCreatorInfo
userAdddress={expenditure?.ownerAddress}
/>
) : (
<ActionWithPermissionsInfo
action={finalizingActions?.items[0]}
/>
)}
</>
{finalizingActions?.items[0]?.initiatorAddress ===
ownerAddress ? (
<FinalizeByPaymentCreatorInfo
userAdddress={expenditure?.ownerAddress}
/>
) : (
<div />
<ActionWithPermissionsInfo
action={finalizingActions?.items[0]}
/>
)}
</>
) : (
<div />
)}
</>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ const StagedPaymentStep: FC<StagedPaymentStepProps> = ({
setSelectedMilestones,
selectedReleaseAction,
} = usePaymentBuilderContext();
const { isStagedExtensionInstalled } = useEnabledExtensions();
const { stagedExpenditureAddress } = useEnabledExtensions();
const [isWaitingForStagesRelease, setIsWaitingForStagesRelease] =
useState(false);

Expand Down Expand Up @@ -139,25 +139,29 @@ const StagedPaymentStep: FC<StagedPaymentStepProps> = ({
slot.payouts?.every((payout) => payout.isClaimed),
);

const isCorrectExtensionInstalled =
!!expenditure.stagedExpenditureAddress &&
stagedExpenditureAddress === expenditure.stagedExpenditureAddress;

const shouldShowReleaseButton =
isStagedExtensionInstalled &&
isCorrectExtensionInstalled &&
!isAnyReleaseStagesMotionInProgress &&
!allStagesReleased;

return (
<>
{!isStagedExtensionInstalled && (
<StepDetailsBlock
text={formatText(MSG.extensionUninstalled)}
content={
<div className="-m-[1.125rem] bg-negative-100 p-[1.125rem] text-sm text-negative-400">
{formatText(MSG.extensionDescription)}
</div>
}
/>
)}

<div className="flex flex-col gap-2">
{!isCorrectExtensionInstalled && (
<StepDetailsBlock
text={formatText(MSG.extensionUninstalled)}
content={
<div className="-m-[1.125rem] bg-negative-100 p-[1.125rem] text-sm text-negative-400">
{formatText(MSG.extensionDescription)}
</div>
}
/>
)}

{releaseActions.length > 0 && (
<ReleaseActions expenditure={expenditure} actions={releaseActions} />
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { defineMessages } from 'react-intl';

import ActionBadge from '~common/ColonyActionsTable/partials/ActionBadge/ActionBadge.tsx';
import { usePaymentBuilderContext } from '~context/PaymentBuilderContext/PaymentBuilderContext.ts';
import useEnabledExtensions from '~hooks/useEnabledExtensions.ts';
import { type Expenditure, type ExpenditureAction } from '~types/graphql.ts';
import { formatText } from '~utils/intl.ts';
import useGetColonyAction from '~v5/common/ActionSidebar/hooks/useGetColonyAction.ts';
Expand Down Expand Up @@ -32,7 +31,6 @@ const ReleaseActionItem: FC<ReleaseActionItemProps> = ({
}) => {
const { setSelectedReleaseAction, selectedReleaseAction } =
usePaymentBuilderContext();
const { isStagedExtensionInstalled } = useEnabledExtensions();
const { motionState, loadingAction } = useGetColonyAction(
action?.transactionHash,
);
Expand All @@ -47,10 +45,6 @@ const ReleaseActionItem: FC<ReleaseActionItemProps> = ({
className="group flex w-full items-center justify-between gap-2"
type="button"
onClick={() => {
if (!isStagedExtensionInstalled) {
return;
}

setSelectedReleaseAction(action);
}}
>
Expand Down
Loading
Loading