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
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { render } from '@testing-library/react';
import React from 'react';
import GroupCreateTDH from '@/components/groups/page/create/config/GroupCreateTDH';
import { ApiGroupTdhInclusionStrategy } from '@/generated/models/ApiGroupTdhInclusionStrategy';

jest.mock('@/components/groups/page/create/config/common/GroupCreateNumericValue', () => ({
__esModule: true,
Expand All @@ -13,7 +14,7 @@ let mockProps: any = null;
describe('GroupCreateTDH', () => {
it('passes value and setValue to GroupCreateNumericValue', () => {
const setTDH = jest.fn();
const tdh = { min: 3 } as any;
const tdh = { min: 3, inclusion_strategy: ApiGroupTdhInclusionStrategy.Tdh } as any;
const { getByTestId } = render(<GroupCreateTDH tdh={tdh} setTDH={setTDH} />);
expect(getByTestId('numeric')).toBeInTheDocument();
expect(mockProps.value).toBe(3);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,10 @@ describe('useWaveConfig', () => {
expect(result.current.config.dates.isRolling).toBe(false);
});

it('should initialize voting with TDH configuration', () => {
it('should initialize voting with TDH + XTDH configuration', () => {
const { result } = renderHook(() => useWaveConfig());

expect(result.current.config.voting.type).toBe(ApiWaveCreditType.Tdh);
expect(result.current.config.voting.type).toBe(ApiWaveCreditType.TdhPlusXtdh);
expect(result.current.config.voting.category).toBeNull();
expect(result.current.config.voting.profileId).toBeNull();
expect(result.current.config.voting.timeWeighted).toEqual({
Expand Down Expand Up @@ -638,4 +638,4 @@ describe('useWaveConfig', () => {
expect(result.current.config.overview.type).toBe(ApiWaveType.Rank);
});
});
});
});
5 changes: 4 additions & 1 deletion components/drops/view/DropsList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ interface DropsListProps {
readonly location?: DropLocation;
}



const MemoizedDrop = memo(Drop);
const MemoizedLightDrop = memo(LightDrop);
const DropsList = memo(function DropsList({
Expand All @@ -58,6 +60,7 @@ const DropsList = memo(function DropsList({
dropViewDropId,
location = DropLocation.WAVE,
}: DropsListProps) {

const handleReply = useCallback<DropActionHandler>(
({ drop, partId }) => onReply({ drop, partId }),
[onReply]
Expand Down Expand Up @@ -168,7 +171,7 @@ const DropsList = memo(function DropsList({
</HighlightDropWrapper>
);
}),
[orderedDrops, getItemData] // Only depends on orderedDrops array and the memoized item data
[orderedDrops, getItemData, location]
);

return memoizedDrops;
Expand Down
2 changes: 1 addition & 1 deletion components/groups/page/create/GroupCreate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export default function GroupCreate({
tdh: {
min: null,
max: null,
inclusion_strategy: ApiGroupTdhInclusionStrategy.Tdh,
inclusion_strategy: ApiGroupTdhInclusionStrategy.Both,
},
rep: {
min: null,
Expand Down
17 changes: 7 additions & 10 deletions components/groups/page/create/config/GroupCreateTDH.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,18 @@ export default function GroupCreateTDH({
readonly setTDH: (tdh: ApiCreateGroupDescription["tdh"]) => void;
}) {
const modes: CommonSelectItem<ApiGroupTdhInclusionStrategy>[] = [
{
label: "TDH + xTDH",
value: ApiGroupTdhInclusionStrategy.Both,
key: ApiGroupTdhInclusionStrategy.Both,
},
{
label: "TDH",
value: ApiGroupTdhInclusionStrategy.Tdh,
key: ApiGroupTdhInclusionStrategy.Tdh,
},
{
label: "xTDH",
value: ApiGroupTdhInclusionStrategy.Xtdh,
key: ApiGroupTdhInclusionStrategy.Xtdh,
},
{
label: "Both",
value: ApiGroupTdhInclusionStrategy.Both,
key: ApiGroupTdhInclusionStrategy.Both,
},


];

return (
Expand Down
2 changes: 1 addition & 1 deletion components/waves/create-wave/hooks/useWaveConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ export function useWaveConfig() {
adminCanDeleteDrops: false,
},
voting: {
type: ApiWaveCreditType.Tdh,
type: ApiWaveCreditType.TdhPlusXtdh,
category: null,
profileId: null,
timeWeighted: {
Expand Down
13 changes: 11 additions & 2 deletions components/waves/create-wave/voting/CreateWaveVoting.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,13 @@ import NegativeVotingToggle from "./NegativeVotingToggle";
import TimeWeightedVoting from "./TimeWeightedVoting";
import { TimeWeightedVotingConfig } from "./types";

const VOTING_TYPES_ORDER: Record<ApiWaveCreditType, number | undefined> = {
[ApiWaveCreditType.TdhPlusXtdh]: 0,
[ApiWaveCreditType.Tdh]: 1,
[ApiWaveCreditType.Rep]: 2,
[ApiWaveCreditType.Xtdh]: undefined,
};

export default function CreateWaveVoting({
waveType,
selectedType,
Expand Down Expand Up @@ -55,13 +62,15 @@ export default function CreateWaveVoting({
{TITLES[waveType]}
</p>
<div className="tw-mt-3 tw-grid lg:tw-grid-cols-3 tw-gap-x-4 tw-gap-y-4">
{Object.values(ApiWaveCreditType).map((votingType) => (
{(
Object.keys(VOTING_TYPES_ORDER) as ApiWaveCreditType[]
).filter((votingType) => VOTING_TYPES_ORDER[votingType] !== undefined).map((votingType) => (
<CommonBorderedRadioButton
key={votingType}
type={votingType}
selected={selectedType}
disabled={false}
label={WAVE_VOTING_LABELS[votingType]}
label={`By ${WAVE_VOTING_LABELS[votingType]}`}
onChange={onTypeChange}
/>
))}
Expand Down
25 changes: 11 additions & 14 deletions components/waves/drop/SingleWaveDropLog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
} from "@/helpers/Helpers";
import Link from "next/link";
import { ApiWaveCreditType } from "@/generated/models/ApiWaveCreditType";
import { WAVE_VOTING_LABELS } from "@/helpers/waves/waves.constants";
import { SystemAdjustmentPill } from "@/components/common/SystemAdjustmentPill";
import useIsMobileScreen from "@/hooks/isMobileScreen";
import Image from "next/image";
Expand Down Expand Up @@ -41,9 +42,8 @@ export const SingleWaveDropLog: React.FC<SingleWaveDropLogProps> = ({
/>
) : (
<div
className={`tw-rounded-md tw-ring-1 tw-ring-white/10 tw-bg-iron-800 tw-flex-shrink-0 ${
isMobile ? "tw-size-7" : "tw-size-6"
}`}
className={`tw-rounded-md tw-ring-1 tw-ring-white/10 tw-bg-iron-800 tw-flex-shrink-0 ${isMobile ? "tw-size-7" : "tw-size-6"
}`}
/>
);

Expand All @@ -54,9 +54,8 @@ export const SingleWaveDropLog: React.FC<SingleWaveDropLogProps> = ({
className="tw-no-underline tw-group desktop-hover:hover:tw-opacity-80 tw-transition-all tw-duration-300"
>
<span
className={`tw-inline-block${
shouldLimit ? " tw-truncate tw-max-w-[8rem]" : ""
}`}
className={`tw-inline-block${shouldLimit ? " tw-truncate tw-max-w-[8rem]" : ""
}`}
>
<span className="tw-text-sm tw-font-medium tw-text-iron-50 tw-transition-all tw-duration-300 desktop-hover:group-hover:tw-text-iron-300">
{log.invoker.handle}
Expand Down Expand Up @@ -110,11 +109,10 @@ export const SingleWaveDropLog: React.FC<SingleWaveDropLogProps> = ({
</span>
)}
<span
className={`tw-text-sm tw-font-semibold tw-whitespace-nowrap ${
log.contents.newVote > 0 ? "tw-text-green" : "tw-text-red"
}`}
className={`tw-text-sm tw-font-semibold tw-whitespace-nowrap ${log.contents.newVote > 0 ? "tw-text-green" : "tw-text-red"
}`}
>
{formatNumberWithCommas(log.contents.newVote)} {creditType}
{formatNumberWithCommas(log.contents.newVote)} {WAVE_VOTING_LABELS[creditType]}
</span>
{log.contents?.reason === "CREDIT_OVERSPENT" && (
<SystemAdjustmentPill />
Expand All @@ -138,11 +136,10 @@ export const SingleWaveDropLog: React.FC<SingleWaveDropLogProps> = ({
</span>
)}
<span
className={`tw-text-sm tw-font-semibold tw-whitespace-nowrap ${
log.contents.newVote > 0 ? "tw-text-green" : "tw-text-red"
}`}
className={`tw-text-sm tw-font-semibold tw-whitespace-nowrap ${log.contents.newVote > 0 ? "tw-text-green" : "tw-text-red"
}`}
>
{formatNumberWithCommas(log.contents.newVote)} {creditType}
{formatNumberWithCommas(log.contents.newVote)} {WAVE_VOTING_LABELS[creditType]}
</span>
{log.contents?.reason === "CREDIT_OVERSPENT" && (
<SystemAdjustmentPill />
Expand Down
25 changes: 16 additions & 9 deletions components/waves/drop/SingleWaveDropVoteContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { SingleWaveDropVoteInput } from "./SingleWaveDropVoteInput";
import { SingleWaveDropVoteStats } from "./SingleWaveDropVoteStats";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faExchange } from "@fortawesome/free-solid-svg-icons";
import { WAVE_VOTING_LABELS } from "@/helpers/waves/waves.constants";
import { ApiWaveCreditType } from "@/generated/models/ApiWaveCreditType";

interface SingleWaveDropVoteContentProps {
readonly drop: ApiDrop;
Expand All @@ -21,15 +23,20 @@ interface SingleWaveDropVoteContentProps {
export const SingleWaveDropVoteContent: React.FC<
SingleWaveDropVoteContentProps
> = ({ drop, size, onVoteSuccess }) => {

const currentVoteValue = drop.context_profile_context?.rating ?? 0;
const minRating = drop.context_profile_context?.min_rating ?? 0;
const maxRating = drop.context_profile_context?.max_rating ?? 0;
const [voteValue, setVoteValue] = useState<number | string>(currentVoteValue);
const [isSliderMode, setIsSliderMode] = useState(size !== SingleWaveDropVoteSize.MINI);

const voteLabel =
WAVE_VOTING_LABELS[drop.wave.voting_credit_type as ApiWaveCreditType] ||
"votes";

useEffect(() => {
setVoteValue(currentVoteValue);
}, [drop.context_profile_context?.rating]);
}, [currentVoteValue]);

const submitRef = useRef<SingleWaveDropVoteSubmitHandles | null>(null);

Expand All @@ -42,7 +49,7 @@ export const SingleWaveDropVoteContent: React.FC<
// MINI layout uses single horizontal row, others use existing responsive layout
if (size === SingleWaveDropVoteSize.MINI) {
return (

<div
className="tw-bg-iron-900 tw-border tw-border-iron-800 tw-border-solid tw-rounded-lg tw-px-2 tw-py-1.5"
onClick={(e) => e.stopPropagation()}
Expand Down Expand Up @@ -71,7 +78,7 @@ export const SingleWaveDropVoteContent: React.FC<
voteValue={voteValue}
minValue={minRating}
maxValue={maxRating}
creditType={drop.wave.voting_credit_type}
label={voteLabel}
setVoteValue={setVoteValue}
rank={drop.rank}
size={size}
Expand All @@ -83,7 +90,7 @@ export const SingleWaveDropVoteContent: React.FC<
maxValue={maxRating}
setVoteValue={setVoteValue}
onSubmit={handleSubmit}
creditType={drop.wave.voting_credit_type}
label={voteLabel}
size={size}
/>
)}
Expand All @@ -100,13 +107,13 @@ export const SingleWaveDropVoteContent: React.FC<
/>
</div>
</div>

{/* Stats below the controls */}
<div className="tw-mt-3">
<SingleWaveDropVoteStats
currentRating={drop.context_profile_context?.rating ?? 0}
maxRating={maxRating}
creditType={drop.wave.voting_credit_type}
label={voteLabel}
/>
</div>
</div>
Expand Down Expand Up @@ -146,7 +153,7 @@ export const SingleWaveDropVoteContent: React.FC<
<SingleWaveDropVoteStats
currentRating={drop.context_profile_context?.rating ?? 0}
maxRating={maxRating}
creditType={drop.wave.voting_credit_type}
label={voteLabel}
/>
</div>

Expand All @@ -157,9 +164,9 @@ export const SingleWaveDropVoteContent: React.FC<
voteValue={voteValue}
minValue={minRating}
maxValue={maxRating}
creditType={drop.wave.voting_credit_type}
setVoteValue={setVoteValue}
rank={drop.rank}
label={voteLabel}
/>
) : (
<SingleWaveDropVoteInput
Expand All @@ -168,7 +175,7 @@ export const SingleWaveDropVoteContent: React.FC<
maxValue={maxRating}
setVoteValue={setVoteValue}
onSubmit={handleSubmit}
creditType={drop.wave.voting_credit_type}
label={voteLabel}
/>
)}
</div>
Expand Down
Loading