Skip to content
Merged
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
62 changes: 25 additions & 37 deletions apps/common/frontend/src/components/votes/ActionView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,16 +160,8 @@ export const ActionView: React.FC<{
voteRequestResultTableType?: VoteRequestResultTableType;
expiresAt?: Date;
effectiveAt?: Date;
expirationInDays?: number;
confirmationDialogProps?: ConfirmationDialogProps;
}> = ({
action,
voteRequestResultTableType,
expiresAt,
effectiveAt,
expirationInDays,
confirmationDialogProps,
}) => {
}> = ({ action, voteRequestResultTableType, expiresAt, effectiveAt, confirmationDialogProps }) => {
const votesHooks = useVotesHooks();
const dsoInfosQuery = votesHooks.useDsoInfos();

Expand Down Expand Up @@ -204,7 +196,7 @@ export const ActionView: React.FC<{
Member: <PartyId id="srarc_offboardsv-member" partyId={dsoAction.value.sv} />,
}}
/>
{getConfirmationDialog(confirmationDialogProps, expirationInDays)}
{getConfirmationDialog(confirmationDialogProps, expiresAt)}
</>
);
}
Expand All @@ -218,7 +210,7 @@ export const ActionView: React.FC<{
Provider: <PartyId partyId={dsoAction.value.provider} />,
}}
/>
{getConfirmationDialog(confirmationDialogProps, expirationInDays)}
{getConfirmationDialog(confirmationDialogProps, expiresAt)}
</>
);
}
Expand All @@ -232,7 +224,7 @@ export const ActionView: React.FC<{
FeatureAppRightCid: <PartyId partyId={dsoAction.value.rightCid} />,
}}
/>
{getConfirmationDialog(confirmationDialogProps, expirationInDays)}
{getConfirmationDialog(confirmationDialogProps, expiresAt)}
</>
);
}
Expand All @@ -246,10 +238,9 @@ export const ActionView: React.FC<{
dsoAction={dsoAction}
expiresAt={expiresAt}
effectiveAt={effectiveAt}
expirationInDays={expirationInDays}
voteRequestResultTableType={voteRequestResultTableType}
/>
{getConfirmationDialog(confirmationDialogProps, expirationInDays)}
{getConfirmationDialog(confirmationDialogProps, expiresAt)}
</>
);
}
Expand All @@ -274,7 +265,7 @@ export const ActionView: React.FC<{
),
}}
/>
{getConfirmationDialog(confirmationDialogProps, expirationInDays)}
{getConfirmationDialog(confirmationDialogProps, expiresAt)}
</>
);
}
Expand All @@ -292,7 +283,7 @@ export const ActionView: React.FC<{
),
}}
/>
{getConfirmationDialog(confirmationDialogProps, expirationInDays)}
{getConfirmationDialog(confirmationDialogProps, expiresAt)}
</>
);
}
Expand All @@ -307,9 +298,9 @@ export const ActionView: React.FC<{
dsoInfosQuery={dsoInfosQuery}
actionType={actionType}
amuletRulesAction={amuletRulesAction}
expiresAt={expiresAt}
voteRequestResultTableType={voteRequestResultTableType}
confirmationDialogProps={confirmationDialogProps!}
expirationInDays={expirationInDays!}
/>
);
}
Expand All @@ -320,9 +311,9 @@ export const ActionView: React.FC<{
dsoInfosQuery={dsoInfosQuery}
actionType={actionType}
amuletRulesAction={amuletRulesAction}
expiresAt={expiresAt}
voteRequestResultTableType={voteRequestResultTableType}
confirmationDialogProps={confirmationDialogProps!}
expirationInDays={expirationInDays!}
/>
);
}
Expand All @@ -333,9 +324,9 @@ export const ActionView: React.FC<{
dsoInfosQuery={dsoInfosQuery}
actionType={actionType}
amuletRulesAction={amuletRulesAction}
expiresAt={expiresAt}
voteRequestResultTableType={voteRequestResultTableType}
confirmationDialogProps={confirmationDialogProps!}
expirationInDays={expirationInDays!}
/>
);
}
Expand All @@ -349,7 +340,6 @@ export const ActionView: React.FC<{
expiresAt={expiresAt}
effectiveAt={effectiveAt}
voteRequestResultTableType={voteRequestResultTableType}
expirationInDays={expirationInDays!}
confirmationDialogProps={confirmationDialogProps!}
/>
);
Expand Down Expand Up @@ -419,17 +409,17 @@ const AddFutureConfigValueTable: React.FC<{
tag: 'CRARC_AddFutureAmuletConfigSchedule';
value: AmuletRules_AddFutureAmuletConfigSchedule;
};
expiresAt?: Date;
voteRequestResultTableType?: VoteRequestResultTableType;
confirmationDialogProps?: ConfirmationDialogProps;
expirationInDays?: number;
}> = ({
votesHooks,
dsoInfosQuery,
actionType,
amuletRulesAction,
expiresAt,
voteRequestResultTableType,
confirmationDialogProps,
expirationInDays,
}) => {
const voteRequests = votesHooks.useListDsoRulesVoteRequests();

Expand Down Expand Up @@ -525,7 +515,7 @@ const AddFutureConfigValueTable: React.FC<{
}}
/>
{confirmationDialogPropsWithDiffs &&
getConfirmationDialog(confirmationDialogPropsWithDiffs, expirationInDays)}
getConfirmationDialog(confirmationDialogPropsWithDiffs, expiresAt)}
</>
);
};
Expand All @@ -539,17 +529,17 @@ const RemoveFutureConfigValueTable: React.FC<{
tag: 'CRARC_RemoveFutureAmuletConfigSchedule';
value: AmuletRules_RemoveFutureAmuletConfigSchedule;
};
expiresAt?: Date;
voteRequestResultTableType?: VoteRequestResultTableType;
confirmationDialogProps?: ConfirmationDialogProps;
expirationInDays?: number;
}> = ({
votesHooks,
dsoInfosQuery,
actionType,
amuletRulesAction,
expiresAt,
voteRequestResultTableType,
confirmationDialogProps,
expirationInDays,
}) => {
const voteRequests = votesHooks.useListDsoRulesVoteRequests();

Expand Down Expand Up @@ -597,7 +587,7 @@ const RemoveFutureConfigValueTable: React.FC<{
}}
/>
)}
{getConfirmationDialog(confirmationDialogProps, expirationInDays)}
{getConfirmationDialog(confirmationDialogProps, expiresAt)}
</>
);
};
Expand All @@ -611,17 +601,17 @@ const UpdateFutureConfigValueTable: React.FC<{
tag: 'CRARC_UpdateFutureAmuletConfigSchedule';
value: AmuletRules_UpdateFutureAmuletConfigSchedule;
};
expiresAt?: Date;
voteRequestResultTableType?: VoteRequestResultTableType;
confirmationDialogProps?: ConfirmationDialogProps;
expirationInDays?: number;
}> = ({
votesHooks,
dsoInfosQuery,
actionType,
amuletRulesAction,
expiresAt,
voteRequestResultTableType,
confirmationDialogProps,
expirationInDays,
}) => {
const voteRequests = votesHooks.useListDsoRulesVoteRequests();

Expand Down Expand Up @@ -709,7 +699,7 @@ const UpdateFutureConfigValueTable: React.FC<{
foldedAccordions: [],
}}
/>
{getConfirmationDialog(confirmationDialogProps!, expirationInDays!)}
{getConfirmationDialog(confirmationDialogProps, expiresAt)}
</>
);
};
Expand All @@ -723,7 +713,6 @@ const SetAmuletConfigValueTable: React.FC<{
effectiveAt?: Date;
voteRequestResultTableType?: VoteRequestResultTableType; // voteRequestResultTableType is only defined for the Planned, Executed and Rejected tabs
confirmationDialogProps?: ConfirmationDialogProps;
expirationInDays?: number;
}> = ({
votesHooks,
dsoInfosQuery,
Expand All @@ -733,7 +722,6 @@ const SetAmuletConfigValueTable: React.FC<{
effectiveAt,
voteRequestResultTableType,
confirmationDialogProps,
expirationInDays,
}) => {
const voteRequests = votesHooks.useListDsoRulesVoteRequests();
if (voteRequests.isPending) {
Expand Down Expand Up @@ -823,7 +811,7 @@ const SetAmuletConfigValueTable: React.FC<{
}}
/>
{confirmationDialogPropsWithDiffs &&
getConfirmationDialog(confirmationDialogPropsWithDiffs, expirationInDays)}
getConfirmationDialog(confirmationDialogPropsWithDiffs, expiresAt)}
</>
);
};
Expand All @@ -837,7 +825,6 @@ const SetDsoConfigValueTable: React.FC<{
effectiveAt?: Date;
voteRequestResultTableType?: VoteRequestResultTableType; // voteRequestResultTableType is only defined for the Planned, Executed and Rejected tabs
confirmationDialogProps?: ConfirmationDialogProps;
expirationInDays?: number;
}> = ({
votesHooks,
dsoInfosQuery,
Expand All @@ -847,7 +834,6 @@ const SetDsoConfigValueTable: React.FC<{
effectiveAt,
voteRequestResultTableType,
confirmationDialogProps,
expirationInDays,
}) => {
const voteRequests = votesHooks.useListDsoRulesVoteRequests();
if (voteRequests.isPending) {
Expand Down Expand Up @@ -935,19 +921,21 @@ const SetDsoConfigValueTable: React.FC<{
}}
/>
{confirmationDialogPropsWithDiffs &&
getConfirmationDialog(confirmationDialogPropsWithDiffs, expirationInDays)}
getConfirmationDialog(confirmationDialogPropsWithDiffs, expiresAt)}
</>
);
};

const getConfirmationDialog = (
confirmationDialogProps?: ConfirmationDialogProps,
expirationInDays?: number
expiresAt?: Date
) => {
if (!confirmationDialogProps) {
return <></>;
}

const expireDuration = dayjs(expiresAt).fromNow();

return (
<ConfirmationDialog
showDialog={confirmationDialogProps.showDialog}
Expand All @@ -964,7 +952,7 @@ const getConfirmationDialog = (
<li>This action cannot be undone.</li>
<li>You will not be able to edit this request afterwards.</li>
<li>You may only edit your vote after creation.</li>
<li>The vote request will expire in {expirationInDays} days.</li>
<li>The vote request will expire {expireDuration}.</li>
</ul>
{confirmationDialogProps.children}
</ConfirmationDialog>
Expand Down
2 changes: 2 additions & 0 deletions apps/sv/frontend/src/__tests__/setup/setup.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
import '@testing-library/jest-dom/vitest';
import { cleanup } from '@testing-library/react';
import crypto from 'crypto';
import { SetupServer } from 'msw/node';
Expand Down Expand Up @@ -42,4 +43,5 @@ afterAll(() => {
afterEach(() => {
server.resetHandlers();
cleanup();
vi.useRealTimers();
});
45 changes: 44 additions & 1 deletion apps/sv/frontend/src/__tests__/sv.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Copyright (c) 2024 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
// SPDX-License-Identifier: Apache-2.0
import { render, screen } from '@testing-library/react';
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { rest } from 'msw';
import { mockAllIsIntersecting } from 'react-intersection-observer/test-utils';
Expand All @@ -12,6 +12,8 @@ import { SvConfigProvider } from '../utils';
import { svPartyId, voteRequests } from './mocks/constants';
import { server, svUrl } from './setup/setup';
import { changeAction } from './helpers';
import { dateTimeFormatISO } from '@lfdecentralizedtrust/splice-common-frontend-utils';
import dayjs from 'dayjs';

const AppWithConfig = () => {
return (
Expand Down Expand Up @@ -53,6 +55,47 @@ describe('SV user can', () => {

expect(await screen.findByText('Vote Requests')).toBeDefined();
});

test('see proper time format in popup', { timeout: 10000 }, async () => {
const user = userEvent.setup();
render(<AppWithConfig />);

expect(await screen.findByText('Governance')).toBeDefined();
await user.click(screen.getByText('Governance'));

const inOneWeek = dayjs().add(1, 'week').format(dateTimeFormatISO);
const expirationDate = dayjs().add(23, 'minutes').format(dateTimeFormatISO);

const dateInput = screen.getByTestId('datetime-picker-vote-request-expiration');

await waitFor(() => expect(dateInput.getAttribute('value')).toBe(inOneWeek));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add a comment here that we do this because the data from the ledger updates it to this value

await user.type(dateInput, expirationDate);
expect(dateInput.getAttribute('value')).toBe(expirationDate);

const formExpirationLabel = screen.getByTestId('vote-request-expiration-duration');
expect(formExpirationLabel).toHaveTextContent('in 23 minutes');

const options: HTMLOptionElement[] = await screen.findAllByTestId('display-members-option');

fireEvent.change(screen.getByTestId('display-members'), {
target: {
value: options[0].value,
},
});

const summaryInput = screen.getByTestId('create-reason-summary');
await user.type(summaryInput, 'summaryABC');

const urlInput = screen.getByTestId('create-reason-url');
await user.type(urlInput, 'https://vote-request.url');

const submitButton = screen.getByTestId('create-voterequest-submit-button');
await user.click(submitButton);

const submitPopup = screen.getByRole('dialog');

expect(submitPopup).toHaveTextContent('in 23 minutes');
});
});

describe('An SetConfig request', () => {
Expand Down
7 changes: 4 additions & 3 deletions apps/sv/frontend/src/components/votes/VoteRequest.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -190,8 +190,6 @@ export const CreateVoteRequest: React.FC = () => {
expiresAt = undefined;
}

const expirationInDays = dayjs(expiresAt).diff(dayjs(), 'day');

const handleConfirmationAccept = () => {
createVoteRequestMutation.mutate();
setConfirmDialogOpen(false);
Expand Down Expand Up @@ -305,13 +303,17 @@ export const CreateVoteRequest: React.FC = () => {
'data-testid': 'datetime-picker-vote-request-expiration',
},
},
openPickerButton: {
'data-testid': 'datetime-picker-vote-request-expiration-button',
} as Record<string, string>,
}}
closeOnSelect
/>
</LocalizationProvider>
<Typography variant="body2" mt={1}>
Expires{' '}
<DateWithDurationDisplay
id="vote-request-expiration-duration"
datetime={expiration?.toDate()}
enableDuration
onlyDuration
Expand Down Expand Up @@ -441,7 +443,6 @@ export const CreateVoteRequest: React.FC = () => {
}
expiresAt={new Date(expiresAt!)}
effectiveAt={effectivity?.toDate()}
expirationInDays={expirationInDays}
confirmationDialogProps={{
showDialog: confirmDialogOpen,
onAccept: handleConfirmationAccept,
Expand Down
Loading
Loading