Skip to content

Commit

Permalink
Render new topics in following, while not allowing following to be set
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonz-dfinity committed Jul 17, 2024
1 parent e41fcd4 commit 0913c21
Show file tree
Hide file tree
Showing 7 changed files with 55 additions and 25 deletions.
5 changes: 5 additions & 0 deletions frontend/src/lib/constants/neurons.constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ const FIRST_TOPICS = [
Topic.SnsAndCommunityFund,
];
const LAST_TOPICS = [Topic.ExchangeRate];

// Topics that neurons cannot yet set following for.
// TODO: Remove this list when the NNS Governance supports following on those topics.
export const TOPICS_WITH_FOLLOWING_DISABLED = [Topic.ProtocolCanisterManagement, Topic.ServiceNervousSystemManagement];

// This list should include ALL topics ordered as we want.
// Filtering out topics is done in the utils.
export const TOPICS_TO_FOLLOW_NNS = [
Expand Down
10 changes: 7 additions & 3 deletions frontend/src/lib/i18n/en.governance.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
"SubnetReplicaVersionManagement": "IC OS Version Deployment",
"SnsAndCommunityFund": "SNS & Neurons' Fund",
"ApiBoundaryNodeManagement": "API Boundary Node Management",
"SubnetRental": "Subnet Rental"
"SubnetRental": "Subnet Rental",
"ProtocolCanisterManagement": "Protocol Canister Management",
"ServiceNervousSystemManagement": "Service Nervous System Management"
},
"topics_description": {
"Unspecified": "",
Expand All @@ -42,7 +44,9 @@
"SubnetReplicaVersionManagement": "Proposals handling deployments of IC OS versions.",
"SnsAndCommunityFund": "Proposals relating to service nervous systems (SNS) and Neurons' Fund.",
"ApiBoundaryNodeManagement": "Proposals related to the management of API boundary nodes.",
"SubnetRental": "All proposals related to renting a subnet — for example a subnet rental request."
"SubnetRental": "Proposals related to renting a subnet — for example a subnet rental request.",
"ProtocolCanisterManagement": "Proposals related to managing canisters that are considered as part of the IC protocol.",
"ServiceNervousSystemManagement": "All proposals related to managing the service nervous system (SNS)."
},
"rewards": {
"Unknown": "Unknown",
Expand Down Expand Up @@ -208,4 +212,4 @@
"DeployHostosToSomeNodes": "Deploy a HostOS version to a given set of nodes. The proposal changes the HostOS version that is used on the specified nodes.",
"SubnetRentalRequest": "A proposal to rent a subnet on the Internet Computer.<br/><br/>The Subnet Rental Canister is called when this proposal is executed, and the rental request is stored there. The user specified in the proposal needs to make a sufficient upfront payment in ICP in order for the proposal to be valid, and the subnet must be available for rent. The available rental conditions can be checked by calling the Subnet Rental Canister."
}
}
}
6 changes: 5 additions & 1 deletion frontend/src/lib/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,10 @@
"topic_15_subtitle": "Proposals related to the management of API boundary nodes",
"topic_16_title": "Subnet Rental",
"topic_16_subtitle": "All proposals related to renting a subnet, for example a subnet rental request.",
"topic_17_title": "Protocol Canister Management",
"topic_17_subtitle": "Proposals related to managing canisters that are considered as part of the IC protocol.",
"topic_18_title": "Service Nervous System Management",
"topic_18_subtitle": "Proposals related to managing the service nervous system (SNS).",
"current_followees": "Currently Following",
"add": "Add Followee"
},
Expand Down Expand Up @@ -1028,4 +1032,4 @@
"show_all": "Show all",
"import_token": "Import Token"
}
}
}
8 changes: 8 additions & 0 deletions frontend/src/lib/types/i18n.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,10 @@ interface I18nFollow_neurons {
topic_15_subtitle: string;
topic_16_title: string;
topic_16_subtitle: string;
topic_17_title: string;
topic_17_subtitle: string;
topic_18_title: string;
topic_18_subtitle: string;
current_followees: string;
add: string;
}
Expand Down Expand Up @@ -1114,6 +1118,8 @@ interface I18nTopics {
SnsAndCommunityFund: string;
ApiBoundaryNodeManagement: string;
SubnetRental: string;
ProtocolCanisterManagement: string;
ServiceNervousSystemManagement: string;
}

interface I18nTopics_description {
Expand All @@ -1134,6 +1140,8 @@ interface I18nTopics_description {
SnsAndCommunityFund: string;
ApiBoundaryNodeManagement: string;
SubnetRental: string;
ProtocolCanisterManagement: string;
ServiceNervousSystemManagement: string;
}

interface I18nRewards {
Expand Down
38 changes: 22 additions & 16 deletions frontend/src/lib/utils/neuron.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
MAX_NEURONS_MERGED,
MIN_NEURON_STAKE,
TOPICS_TO_FOLLOW_NNS,
TOPICS_WITH_FOLLOWING_DISABLED,
} from "$lib/constants/neurons.constants";
import { DEPRECATED_TOPICS } from "$lib/constants/proposals.constants";
import type { IcpAccountsStoreData } from "$lib/derived/icp-accounts.derived";
Expand Down Expand Up @@ -207,26 +208,26 @@ export const bonusMultiplier = ({
}): number =>
1 +
multiplier *
(Math.min(Number(amount), max) /
// to avoid NaN
(max === 0 ? 1 : max));
(Math.min(Number(amount), max) /
// to avoid NaN
(max === 0 ? 1 : max));

// TODO: Do we need this? What does it mean to have a valid stake?
// TODO: https://dfinity.atlassian.net/browse/L2-507
export const hasValidStake = (neuron: NeuronInfo): boolean =>
// Ignore if we can't validate the stake
nonNullish(neuron.fullNeuron)
? neuron.fullNeuron.cachedNeuronStake +
neuron.fullNeuron.maturityE8sEquivalent >
BigInt(DEFAULT_TRANSACTION_FEE_E8S)
neuron.fullNeuron.maturityE8sEquivalent >
BigInt(DEFAULT_TRANSACTION_FEE_E8S)
: false;

export const getDissolvingTimestampSeconds = (
neuron: NeuronInfo
): bigint | undefined =>
neuron.state === NeuronState.Dissolving &&
neuron.fullNeuron?.dissolveState !== undefined &&
"WhenDissolvedTimestampSeconds" in neuron.fullNeuron.dissolveState
neuron.fullNeuron?.dissolveState !== undefined &&
"WhenDissolvedTimestampSeconds" in neuron.fullNeuron.dissolveState
? neuron.fullNeuron.dissolveState.WhenDissolvedTimestampSeconds
: undefined;

Expand Down Expand Up @@ -282,7 +283,7 @@ export const formattedMaturity = ({ fullNeuron }: NeuronInfo): string =>
export const formattedTotalMaturity = ({ fullNeuron }: NeuronInfo): string =>
formatMaturity(
(fullNeuron?.maturityE8sEquivalent ?? 0n) +
(fullNeuron?.stakedMaturityE8sEquivalent ?? 0n)
(fullNeuron?.stakedMaturityE8sEquivalent ?? 0n)
);

/**
Expand Down Expand Up @@ -368,7 +369,7 @@ export const isNeuronControllable = ({
fullNeuron?.controller !== undefined &&
(fullNeuron.controller === identity?.getPrincipal().toText() ||
getAccountByPrincipal({ principal: fullNeuron.controller, accounts }) !==
undefined);
undefined);

export const isNeuronControlledByHardwareWallet = ({
neuron,
Expand Down Expand Up @@ -734,12 +735,12 @@ export const canBeMerged = (
}
return sameManageNeuronFollowees(neurons)
? {
isValid: true,
}
isValid: true,
}
: {
isValid: false,
messageKey: "error.merge_neurons_not_same_manage_neuron_followees",
};
isValid: false,
messageKey: "error.merge_neurons_not_same_manage_neuron_followees",
};
};

export const mapNeuronIds = ({
Expand Down Expand Up @@ -814,7 +815,7 @@ export const topicsToFollow = (neuron: NeuronInfo): Topic[] =>
(followeesByTopic({ neuron, topic: Topic.ManageNeuron }) === undefined
? TOPICS_TO_FOLLOW_NNS.filter((topic) => topic !== Topic.ManageNeuron)
: TOPICS_TO_FOLLOW_NNS
).filter((topic) => !DEPRECATED_TOPICS.includes(topic));
).filter((topic) => !DEPRECATED_TOPICS.includes(topic) && !TOPICS_WITH_FOLLOWING_DISABLED.includes(topic));

// NeuronInfo is public info.
// fullNeuron is only for users with access.
Expand Down Expand Up @@ -972,7 +973,7 @@ export const maturityLastDistribution = ({
return (
actual_timestamp_seconds -
(fromNullable(rounds_since_last_distribution) ?? 1n) *
BigInt(SECONDS_IN_DAY)
BigInt(SECONDS_IN_DAY)
);
};

Expand Down Expand Up @@ -1004,6 +1005,8 @@ export const getTopicTitle = ({
[Topic.SnsAndCommunityFund]: i18n.follow_neurons.topic_14_title,
[Topic.ApiBoundaryNodeManagement]: i18n.follow_neurons.topic_15_title,
[Topic.SubnetRental]: i18n.follow_neurons.topic_16_title,
[Topic.ProtocolCanisterManagement]: i18n.follow_neurons.topic_17_title,
[Topic.ServiceNervousSystemManagement]: i18n.follow_neurons.topic_18_title,
};
return mapper[topic];
};
Expand Down Expand Up @@ -1034,6 +1037,9 @@ export const getTopicSubtitle = ({
[Topic.SnsAndCommunityFund]: i18n.follow_neurons.topic_14_subtitle,
[Topic.ApiBoundaryNodeManagement]: i18n.follow_neurons.topic_15_subtitle,
[Topic.SubnetRental]: i18n.follow_neurons.topic_16_subtitle,
[Topic.ProtocolCanisterManagement]: i18n.follow_neurons.topic_17_subtitle,
[Topic.ServiceNervousSystemManagement]:
i18n.follow_neurons.topic_18_subtitle,
};
return mapper[topic];
};
2 changes: 2 additions & 0 deletions frontend/src/tests/lib/utils/enum.utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ describe("enum-utils", () => {
Topic.SnsAndCommunityFund,
Topic.ApiBoundaryNodeManagement,
Topic.SubnetRental,
Topic.ProtocolCanisterManagement,
Topic.ServiceNervousSystemManagement,
];

expect(
Expand Down
11 changes: 6 additions & 5 deletions frontend/src/tests/lib/utils/neuron.utils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
MAX_NEURONS_MERGED,
MIN_NEURON_STAKE,
TOPICS_TO_FOLLOW_NNS,
TOPICS_WITH_FOLLOWING_DISABLED,
} from "$lib/constants/neurons.constants";
import { DEPRECATED_TOPICS } from "$lib/constants/proposals.constants";
import type { IcpAccountsStoreData } from "$lib/derived/icp-accounts.derived";
Expand Down Expand Up @@ -2166,30 +2167,30 @@ describe("neuron-utils", () => {
},
};

it("should not return deprecated topics", () => {
it("should not return deprecated or disabled topics", () => {
expect(topicsToFollow(neuronWithoutManageNeuron)).toEqual(
TOPICS_TO_FOLLOW_NNS.filter(
(topic) =>
topic !== Topic.ManageNeuron && !DEPRECATED_TOPICS.includes(topic)
topic !== Topic.ManageNeuron && !DEPRECATED_TOPICS.includes(topic) && !TOPICS_WITH_FOLLOWING_DISABLED.includes(topic)
)
);
expect(topicsToFollow(neuronWithoutFollowees)).toEqual(
TOPICS_TO_FOLLOW_NNS.filter(
(topic) =>
topic !== Topic.ManageNeuron && !DEPRECATED_TOPICS.includes(topic)
topic !== Topic.ManageNeuron && !DEPRECATED_TOPICS.includes(topic) && !TOPICS_WITH_FOLLOWING_DISABLED.includes(topic)
)
);
expect(topicsToFollow(neuronWithManageNeuron)).toEqual(
TOPICS_TO_FOLLOW_NNS.filter(
(topic) => !DEPRECATED_TOPICS.includes(topic)
(topic) => !DEPRECATED_TOPICS.includes(topic) && !TOPICS_WITH_FOLLOWING_DISABLED.includes(topic)
)
);
});

it("should return topics with ManageNeuron if neuron follows some neuron on the ManageNeuron topic", () => {
expect(topicsToFollow(neuronWithManageNeuron)).toEqual(
TOPICS_TO_FOLLOW_NNS.filter(
(topic) => !DEPRECATED_TOPICS.includes(topic)
(topic) => !DEPRECATED_TOPICS.includes(topic) && !TOPICS_WITH_FOLLOWING_DISABLED.includes(topic)
)
);
});
Expand Down

0 comments on commit 0913c21

Please sign in to comment.