diff --git a/apps/sv/frontend/src/__tests__/governance/proposal-details-content.test.tsx b/apps/sv/frontend/src/__tests__/governance/proposal-details-content.test.tsx index 5a3df3f1c0..8b5ee96e51 100644 --- a/apps/sv/frontend/src/__tests__/governance/proposal-details-content.test.tsx +++ b/apps/sv/frontend/src/__tests__/governance/proposal-details-content.test.tsx @@ -24,6 +24,12 @@ import { ProposalVoteForm } from '../../components/governance/ProposalVoteForm'; import App from '../../App'; import { svPartyId } from '../mocks/constants'; import { Wrapper } from '../helpers'; +import { + PROPOSAL_LINK_LABEL, + SUPPORTING_URL_LABEL, + VOTE_PROPOSAL_CONTRACT_ID_LABEL, +} from '../../utils/constants'; +import { getProposalLink } from '../../utils/governance'; const voteRequest = { contractId: 'abc123' as ContractId, @@ -165,6 +171,10 @@ describe('Proposal Details Content', () => { const action = screen.getByTestId('proposal-details-action-value'); expect(action.textContent).toMatch(/Offboard Member/); + expect(screen.getByTestId('proposal-details-contractid-label').textContent).toBe( + VOTE_PROPOSAL_CONTRACT_ID_LABEL + ); + const offboardSection = screen.getByTestId('proposal-details-offboard-member-section'); expect(offboardSection).toBeInTheDocument(); @@ -177,9 +187,17 @@ describe('Proposal Details Content', () => { const summary = screen.getByTestId('proposal-details-summary-value'); expect(summary.textContent).toMatch(/Summary of the proposal/); + expect(screen.getByTestId('proposal-details-url-label').textContent).toBe(SUPPORTING_URL_LABEL); + const url = screen.getByTestId('proposal-details-url'); expect(url.textContent).toMatch(/https:\/\/example.com/); + expect(screen.getByTestId('proposal-details-proposal-link-label').textContent).toBe( + PROPOSAL_LINK_LABEL + ); + const proposalLink = screen.getByTestId('proposal-details-proposal-link-link'); + expect(proposalLink).toHaveAttribute('href', getProposalLink(voteRequest.contractId)); + const votingInformationSection = screen.getByTestId('proposal-details-voting-information'); expect(votingInformationSection).toBeInTheDocument(); diff --git a/apps/sv/frontend/src/__tests__/governance/proposal-summary.test.tsx b/apps/sv/frontend/src/__tests__/governance/proposal-summary.test.tsx index 6d2c17a364..dab5110554 100644 --- a/apps/sv/frontend/src/__tests__/governance/proposal-summary.test.tsx +++ b/apps/sv/frontend/src/__tests__/governance/proposal-summary.test.tsx @@ -32,7 +32,7 @@ describe('Review Proposal Component', () => { expect(screen.getByTestId('action-title').textContent).toBe('Action'); expect(screen.getByTestId('action-field').textContent).toBe(actionName); - expect(screen.getByTestId('url-title').textContent).toBe('URL'); + expect(screen.getByTestId('url-title').textContent).toBe('Supporting URL'); expect(screen.getByTestId('url-field').textContent).toBe(url); expect(screen.getByTestId('summary-title').textContent).toBe('Summary'); @@ -96,7 +96,7 @@ describe('Review Proposal Component', () => { expect(screen.getByTestId('action-title').textContent).toBe('Action'); expect(screen.getByTestId('action-field').textContent).toBe(actionName); - expect(screen.getByTestId('url-title').textContent).toBe('URL'); + expect(screen.getByTestId('url-title').textContent).toBe('Supporting URL'); expect(screen.getByTestId('url-field').textContent).toBe(url); expect(screen.getByTestId('summary-title').textContent).toBe('Summary'); @@ -136,7 +136,7 @@ describe('Review Proposal Component', () => { expect(screen.getByTestId('action-title').textContent).toBe('Action'); expect(screen.getByTestId('action-field').textContent).toBe(actionName); - expect(screen.getByTestId('url-title').textContent).toBe('URL'); + expect(screen.getByTestId('url-title').textContent).toBe('Supporting URL'); expect(screen.getByTestId('url-field').textContent).toBe(url); expect(screen.getByTestId('summary-title').textContent).toBe('Summary'); @@ -180,7 +180,7 @@ describe('Review Proposal Component', () => { expect(screen.getByTestId('action-title').textContent).toBe('Action'); expect(screen.getByTestId('action-field').textContent).toBe(actionName); - expect(screen.getByTestId('url-title').textContent).toBe('URL'); + expect(screen.getByTestId('url-title').textContent).toBe('Supporting URL'); expect(screen.getByTestId('url-field').textContent).toBe(url); expect(screen.getByTestId('summary-title').textContent).toBe('Summary'); @@ -230,7 +230,7 @@ describe('Review Proposal Component', () => { expect(screen.getByTestId('action-title').textContent).toBe('Action'); expect(screen.getByTestId('action-field').textContent).toBe(actionName); - expect(screen.getByTestId('url-title').textContent).toBe('URL'); + expect(screen.getByTestId('url-title').textContent).toBe('Supporting URL'); expect(screen.getByTestId('url-field').textContent).toBe(url); expect(screen.getByTestId('summary-title').textContent).toBe('Summary'); @@ -296,7 +296,7 @@ describe('Review Proposal Component', () => { expect(screen.getByTestId('action-title').textContent).toBe('Action'); expect(screen.getByTestId('action-field').textContent).toBe(actionName); - expect(screen.getByTestId('url-title').textContent).toBe('URL'); + expect(screen.getByTestId('url-title').textContent).toBe('Supporting URL'); expect(screen.getByTestId('url-field').textContent).toBe(url); expect(screen.getByTestId('summary-title').textContent).toBe('Summary'); @@ -368,7 +368,7 @@ describe('Review Proposal Component', () => { expect(screen.getByTestId('action-title').textContent).toBe('Action'); expect(screen.getByTestId('action-field').textContent).toBe(actionName); - expect(screen.getByTestId('url-title').textContent).toBe('URL'); + expect(screen.getByTestId('url-title').textContent).toBe('Supporting URL'); expect(screen.getByTestId('url-field').textContent).toBe(url); expect(screen.getByTestId('summary-title').textContent).toBe('Summary'); diff --git a/apps/sv/frontend/src/components/forms/CreateUnallocatedUnclaimedActivityRecordForm.tsx b/apps/sv/frontend/src/components/forms/CreateUnallocatedUnclaimedActivityRecordForm.tsx index 81f722e465..ec7c9aae25 100644 --- a/apps/sv/frontend/src/components/forms/CreateUnallocatedUnclaimedActivityRecordForm.tsx +++ b/apps/sv/frontend/src/components/forms/CreateUnallocatedUnclaimedActivityRecordForm.tsx @@ -8,7 +8,7 @@ import { useState } from 'react'; import { useDsoInfos } from '../../contexts/SvContext'; import { useAppForm } from '../../hooks/form'; import { useProposalMutation } from '../../hooks/useProposalMutation'; -import { THRESHOLD_DEADLINE_SUBTITLE } from '../../utils/constants'; +import { SUPPORTING_URL_LABEL, THRESHOLD_DEADLINE_SUBTITLE } from '../../utils/constants'; import { createProposalActions, getInitialExpiration } from '../../utils/governance'; import type { CommonProposalFormData } from '../../utils/types'; import { EffectiveDateField } from '../form-components/EffectiveDateField'; @@ -227,7 +227,7 @@ export const CreateUnallocatedUnclaimedActivityRecordForm: React.FC = _ => { > {field => ( )} diff --git a/apps/sv/frontend/src/components/forms/GrantRevokeFeaturedAppForm.tsx b/apps/sv/frontend/src/components/forms/GrantRevokeFeaturedAppForm.tsx index 98c501f330..72f7bf9436 100644 --- a/apps/sv/frontend/src/components/forms/GrantRevokeFeaturedAppForm.tsx +++ b/apps/sv/frontend/src/components/forms/GrantRevokeFeaturedAppForm.tsx @@ -13,7 +13,7 @@ import { import { dateTimeFormatISO } from '@canton-network/splice-common-frontend-utils'; import { useAppForm } from '../../hooks/form'; import { useStore } from '@tanstack/react-form'; -import { THRESHOLD_DEADLINE_SUBTITLE } from '../../utils/constants'; +import { SUPPORTING_URL_LABEL, THRESHOLD_DEADLINE_SUBTITLE } from '../../utils/constants'; import { CommonProposalFormData } from '../../utils/types'; import { ContractId } from '@daml/types'; import { FeaturedAppRight } from '@daml.js/splice-amulet/lib/Splice/Amulet'; @@ -344,7 +344,7 @@ export const GrantRevokeFeaturedAppForm: React.FC validateUrl(value), }} > - {field => } + {field => } )} diff --git a/apps/sv/frontend/src/components/forms/OffboardSvForm.tsx b/apps/sv/frontend/src/components/forms/OffboardSvForm.tsx index 722fe87d9b..a2876e24fd 100644 --- a/apps/sv/frontend/src/components/forms/OffboardSvForm.tsx +++ b/apps/sv/frontend/src/components/forms/OffboardSvForm.tsx @@ -22,7 +22,7 @@ import { EffectiveDateField } from '../form-components/EffectiveDateField'; import { ProposalSummary } from '../governance/ProposalSummary'; import { ProposalSubmissionError } from '../form-components/ProposalSubmissionError'; import { useProposalMutation } from '../../hooks/useProposalMutation'; -import { THRESHOLD_DEADLINE_SUBTITLE } from '../../utils/constants'; +import { SUPPORTING_URL_LABEL, THRESHOLD_DEADLINE_SUBTITLE } from '../../utils/constants'; interface ExtraFormFields { sv: string; @@ -175,7 +175,7 @@ export const OffboardSvForm: React.FC = _ => { onChange: ({ value }) => validateUrl(value), }} > - {field => } + {field => } )} diff --git a/apps/sv/frontend/src/components/forms/SetAmuletConfigRulesForm.tsx b/apps/sv/frontend/src/components/forms/SetAmuletConfigRulesForm.tsx index 56a7a311b9..79dd9a1f0f 100644 --- a/apps/sv/frontend/src/components/forms/SetAmuletConfigRulesForm.tsx +++ b/apps/sv/frontend/src/components/forms/SetAmuletConfigRulesForm.tsx @@ -5,7 +5,7 @@ import { ActionRequiringConfirmation, AmuletRules_ActionRequiringConfirmation, } from '@daml.js/splice-dso-governance/lib/Splice/DsoRules'; -import { THRESHOLD_DEADLINE_SUBTITLE } from '../../utils/constants'; +import { SUPPORTING_URL_LABEL, THRESHOLD_DEADLINE_SUBTITLE } from '../../utils/constants'; import { buildAmuletRulesPendingConfigFields, configFormDataToConfigChanges, @@ -288,7 +288,9 @@ export const SetAmuletConfigRulesForm: () => JSX.Element = () => { onChange: ({ value }) => validateUrl(value), }} > - {field => } + {field => ( + + )} )} diff --git a/apps/sv/frontend/src/components/forms/SetDsoConfigRulesForm.tsx b/apps/sv/frontend/src/components/forms/SetDsoConfigRulesForm.tsx index 3d9b2be85d..349a2cb57f 100644 --- a/apps/sv/frontend/src/components/forms/SetDsoConfigRulesForm.tsx +++ b/apps/sv/frontend/src/components/forms/SetDsoConfigRulesForm.tsx @@ -20,7 +20,7 @@ import { useAppForm } from '../../hooks/form'; import { useProposalMutation } from '../../hooks/useProposalMutation'; import { buildDsoConfigChanges } from '../../utils/buildDsoConfigChanges'; import { buildDsoRulesConfigFromChanges } from '../../utils/buildDsoRulesConfigFromChanges'; -import { THRESHOLD_DEADLINE_SUBTITLE } from '../../utils/constants'; +import { SUPPORTING_URL_LABEL, THRESHOLD_DEADLINE_SUBTITLE } from '../../utils/constants'; import { buildPendingConfigFields, configFormDataToConfigChanges, @@ -304,7 +304,9 @@ export const SetDsoConfigRulesForm: () => JSX.Element = () => { onChange: ({ value }) => validateUrl(value), }} > - {field => } + {field => ( + + )} )} diff --git a/apps/sv/frontend/src/components/forms/UpdateSvRewardWeightForm.tsx b/apps/sv/frontend/src/components/forms/UpdateSvRewardWeightForm.tsx index 94838d058d..5fc51f90ba 100644 --- a/apps/sv/frontend/src/components/forms/UpdateSvRewardWeightForm.tsx +++ b/apps/sv/frontend/src/components/forms/UpdateSvRewardWeightForm.tsx @@ -17,7 +17,7 @@ import { validateUrl, validateWeight, } from './formValidators'; -import { THRESHOLD_DEADLINE_SUBTITLE } from '../../utils/constants'; +import { SUPPORTING_URL_LABEL, THRESHOLD_DEADLINE_SUBTITLE } from '../../utils/constants'; import { createProposalActions, formatBasisPoints, @@ -220,7 +220,9 @@ export const UpdateSvRewardWeightForm: React.FC = _ => { onChange: ({ value }) => validateUrl(value), }} > - {field => } + {field => ( + + )} )} diff --git a/apps/sv/frontend/src/components/governance/ActionRequiredSection.tsx b/apps/sv/frontend/src/components/governance/ActionRequiredSection.tsx index 36e338bf49..9231092815 100644 --- a/apps/sv/frontend/src/components/governance/ActionRequiredSection.tsx +++ b/apps/sv/frontend/src/components/governance/ActionRequiredSection.tsx @@ -6,6 +6,7 @@ import { East } from '@mui/icons-material'; import { Alert, Box, Stack, Typography } from '@mui/material'; import { Link as RouterLink } from 'react-router'; import { CopyableIdentifier, MemberIdentifier, PageSectionHeader } from '../../components/beta'; +import { VOTE_PROPOSAL_CONTRACT_ID_LABEL } from '../../utils/constants'; import React from 'react'; import dayjs from 'dayjs'; import relativeTime from 'dayjs/plugin/relativeTime'; @@ -134,7 +135,7 @@ const ActionCard = (props: ActionCardProps) => { = pro /> = pro /> = pro } labelId="proposal-details-url-label" /> + + + } + labelId="proposal-details-proposal-link-label" + /> @@ -529,11 +549,23 @@ const VoteItem: React.FC = ({ /> {comment && ( - - {comment} - + + + {VOTE_REASON_SUMMARY_LABEL} + + + {comment} + + + )} + {url && ( + + + {VOTE_REASON_URL_LABEL} + + + )} - {url && } = pro ACTION - VOTE PROPOSAL CONTRACT ID + Vote Proposal Contract ID {showThresholdDeadline && THRESHOLD DEADLINE} EFFECTIVE AT {showStatus && STATUS} diff --git a/apps/sv/frontend/src/components/governance/ProposalSummary.tsx b/apps/sv/frontend/src/components/governance/ProposalSummary.tsx index a831205927..39d0a1c051 100644 --- a/apps/sv/frontend/src/components/governance/ProposalSummary.tsx +++ b/apps/sv/frontend/src/components/governance/ProposalSummary.tsx @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import { Box, Typography } from '@mui/material'; -import { THRESHOLD_DEADLINE_SUBTITLE } from '../../utils/constants'; +import { SUPPORTING_URL_LABEL, THRESHOLD_DEADLINE_SUBTITLE } from '../../utils/constants'; import type { ConfigChange } from '../../utils/types'; import { scrollContainerSx, scrollableIdentifierFieldSx } from '../beta/identifierStyles'; import { ConfigValuesChanges } from './ConfigValuesChanges'; @@ -71,7 +71,7 @@ export const ProposalSummary: React.FC = props => { - + diff --git a/apps/sv/frontend/src/components/governance/ProposalVoteForm.tsx b/apps/sv/frontend/src/components/governance/ProposalVoteForm.tsx index 46790d07bf..4a736b8a0d 100644 --- a/apps/sv/frontend/src/components/governance/ProposalVoteForm.tsx +++ b/apps/sv/frontend/src/components/governance/ProposalVoteForm.tsx @@ -10,6 +10,7 @@ import { ContractId } from '@daml/types'; import { VoteRequest } from '@daml.js/splice-dso-governance/lib/Splice/DsoRules'; import { ProposalVote } from '../../utils/types'; import { Alert, Box, Button, Stack, TextField, Typography } from '@mui/material'; +import { VOTE_REASON_SUMMARY_LABEL, VOTE_REASON_URL_LABEL } from '../../utils/constants'; interface CastVoteArgs { accepted: boolean; url: string; @@ -109,7 +110,7 @@ export const ProposalVoteForm: React.FC = props => { fontSize={18} lineHeight={1} > - Reason + {VOTE_REASON_SUMMARY_LABEL} = props => { fontSize={18} lineHeight={1} > - Vote Reason URL + {VOTE_REASON_URL_LABEL}