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

NNS1-3450: New Exports NNS Neurons Snapshot Component #5813

Merged
merged 49 commits into from
Nov 26, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
e12a28c
utility function to download csv
yhabib Nov 19, 2024
93b378d
export neurons button
yhabib Nov 19, 2024
758eb4d
adds missing file
yhabib Nov 19, 2024
5507458
enables feature in devenv
yhabib Nov 19, 2024
c881da9
clean slate
yhabib Nov 21, 2024
b40cf63
Merge remote-tracking branch 'origin/main' into NNS1-3450/export-neur…
yhabib Nov 21, 2024
abdbab0
clean up
yhabib Nov 21, 2024
dc5eb4d
--wip-- [skip ci]
yhabib Nov 21, 2024
465dffd
clean up
yhabib Nov 21, 2024
fd9f3c2
wip
yhabib Nov 21, 2024
c36ac74
Merge remote-tracking branch 'origin/main' into NNS1-3450/export-neur…
yhabib Nov 21, 2024
c9f2e1b
wip
yhabib Nov 21, 2024
9ef6c80
improve test title
yhabib Nov 21, 2024
a34c975
Merge remote-tracking branch 'origin/main' into NNS1-3450/export-neur…
yhabib Nov 21, 2024
a3b82e2
--wip-- [skip ci]
yhabib Nov 22, 2024
5454f5e
more tests
yhabib Nov 22, 2024
459e7a3
Merge remote-tracking branch 'origin/main' into NNS1-3450/export-neur…
yhabib Nov 22, 2024
614ed40
new fields
yhabib Nov 22, 2024
ea1d404
extend test
yhabib Nov 22, 2024
fa8bb37
extends csv function
yhabib Nov 22, 2024
e6151a5
Merge remote-tracking branch 'origin/NNS1-3450/csv-sections' into NNS…
yhabib Nov 22, 2024
3716fb5
fix missing thigns
yhabib Nov 22, 2024
f1d66b0
Merge remote-tracking branch 'origin/NNS1-3450/csv-sections' into NNS…
yhabib Nov 22, 2024
e52edda
car
yhabib Nov 22, 2024
1f9647b
fmt
yhabib Nov 22, 2024
9c6c875
--wip-- [skip ci]
yhabib Nov 25, 2024
0faebad
Merge remote-tracking branch 'origin/main' into NNS1-3450/export-neur…
yhabib Nov 25, 2024
bd29df9
Merge remote-tracking branch 'origin/main' into NNS1-3450/export-neur…
yhabib Nov 25, 2024
88a5c94
--wip-- [skip ci]
yhabib Nov 25, 2024
c1b6430
Merge remote-tracking branch 'origin/main' into NNS1-3450/export-neur…
yhabib Nov 25, 2024
c668af2
introduce po for testing
yhabib Nov 25, 2024
2fb16c9
adds missing change
yhabib Nov 25, 2024
49f6147
fixes constant
yhabib Nov 25, 2024
01983aa
applies changes
yhabib Nov 25, 2024
662377a
Merge remote-tracking branch 'origin/main' into NNS1-3450/export-neur…
yhabib Nov 25, 2024
7439ba5
fmt
yhabib Nov 25, 2024
7b88b66
remove UI
yhabib Nov 25, 2024
e2739b1
removes old imports
yhabib Nov 25, 2024
968d9d1
removes unused translations
yhabib Nov 25, 2024
fd400d1
Merge remote-tracking branch 'origin/main' into NNS1-3450/export-neur…
yhabib Nov 25, 2024
d40d931
fix tests
yhabib Nov 25, 2024
c151a72
Merge remote-tracking branch 'origin/main' into NNS1-3450/export-neur…
yhabib Nov 25, 2024
76b194f
car
yhabib Nov 26, 2024
aa1ca86
Merge remote-tracking branch 'origin/main' into NNS1-3450/export-neur…
yhabib Nov 26, 2024
d79a547
consistent used of test asserstions
yhabib Nov 26, 2024
1d78e00
fmt
yhabib Nov 26, 2024
095c855
car
yhabib Nov 26, 2024
9c863b3
Merge remote-tracking branch 'origin/main' into NNS1-3450/export-neur…
yhabib Nov 26, 2024
a517656
adds tests and fixes bug
yhabib Nov 26, 2024
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
14 changes: 7 additions & 7 deletions frontend/src/lib/components/header/ExportNeuronsButton.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
neuronStake,
neuronStakedMaturity,
} from "$lib/utils/neuron.utils";
import { ICPToken, secondsToDuration, TokenAmountV2 } from "@dfinity/utils";
import { ICPToken, isNullish, secondsToDuration, TokenAmountV2 } from "@dfinity/utils";
import { formatTokenV2 } from "$lib/utils/token.utils";
import { NeuronState, type NeuronInfo } from "@dfinity/nns";
import {
Expand All @@ -29,16 +29,16 @@
import { authStore } from "$lib/stores/auth.store";

const dispatcher = createEventDispatcher<{
nnsExportNeuronsCSVTriggered: void;
nnsExportNeuronsCsvTriggered: void;
}>();

let isDisabled = true;
let neurons: NeuronInfo[] = [];
$: neurons = $neuronsStore?.neurons ?? [];
yhabib marked this conversation as resolved.
Show resolved Hide resolved
$: nnsAccountPrincipal = $authStore.identity?.getPrincipal().toText() ?? "";
$: isDisabled = !neurons.length || !nnsAccountPrincipal;
$: isDisabled = neurons.length === 0 || isNullish(nnsAccountPrincipal);

const neuronToHumanReadableFormat = (neuron: NeuronInfo) => {
const nnsNeuronToHumanReadableFormat = (neuron: NeuronInfo) => {
const controllerId = neuron.fullNeuron?.controller?.toString();
const neuronId = neuron.neuronId.toString();
const neuronAccountId = neuron.fullNeuron?.accountIdentifier.toString();
Expand Down Expand Up @@ -73,7 +73,7 @@
seconds: dissolveDelaySeconds,
i18n: $i18n.time,
}),
dissolveDate: dissolveDate ?? "N/A",
dissolveDate: dissolveDate ?? $i18n.core.not_applicable,
creationDate,
state: $i18n.neuron_state[getStateInfo(neuron.state).textKey],
};
Expand All @@ -83,7 +83,7 @@
if (!nnsAccountPrincipal) return;

try {
const humanFriendlyContent = neurons.map(neuronToHumanReadableFormat);
const humanFriendlyContent = neurons.map(nnsNeuronToHumanReadableFormat);
const fileName = `neurons_export_${formatDateCompact(new Date())}`;
const metadataDate = nanoSecondsToDateTime(nowInBigIntNanoSeconds());

Expand Down Expand Up @@ -168,7 +168,7 @@
});
}
} finally {
dispatcher("nnsExportNeuronsCSVTriggered");
dispatcher("nnsExportNeuronsCsvTriggered");
}
};
</script>
Expand Down
3 changes: 2 additions & 1 deletion frontend/src/lib/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@
"send_with_token": "Send $token",
"collapse_all": "Collapse All",
"or": "or",
"add": "Add"
"add": "Add",
"not_applicable": "N/A"
},
"error": {
"auth_sync": "There was an unexpected issue while syncing the status of your authentication. Try to refresh your browser.",
Expand Down
1 change: 1 addition & 0 deletions frontend/src/lib/types/i18n.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ interface I18nCore {
collapse_all: string;
or: string;
add: string;
not_applicable: string;
}

interface I18nError {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,17 @@ describe("ExportNeuronsButton", () => {
});
});

const renderComponent = () => {
const renderComponent = ({ onTrigger }: { onTrigger?: () => void } = {}) => {
const { container, component } = render(ExportNeuronsButton);

const po = ExportNeuronsButtonPo.under({
element: new JestPageObjectElement(container),
});
return { po, component };

if (onTrigger) {
component.$on("nnsExportNeuronsCsvTriggered", onTrigger);
}
return { po };
yhabib marked this conversation as resolved.
Show resolved Hide resolved
};

it("should be disabled when there are no neurons", async () => {
yhabib marked this conversation as resolved.
Show resolved Hide resolved
Expand All @@ -58,19 +62,25 @@ describe("ExportNeuronsButton", () => {

it("should name the file with the date of the export", async () => {
const { po } = renderComponent();

expect(generateCsvFileToSave).not.toHaveBeenCalled();

await po.click();

const expectedFileName = `neurons_export_20231014`;
expect(generateCsvFileToSave).toHaveBeenCalledWith(
yhabib marked this conversation as resolved.
Show resolved Hide resolved
expect.objectContaining({
fileName: expectedFileName,
})
);
expect(generateCsvFileToSave).toHaveBeenCalledOnce();
});

it("should transform neuron data correctly", async () => {
const { po } = renderComponent();
await po.click();

expect(generateCsvFileToSave).not.toHaveBeenCalled();
await po.click();
expect(generateCsvFileToSave).toHaveBeenCalledWith(
expect.objectContaining({
data: expect.arrayContaining([
Expand All @@ -91,20 +101,16 @@ describe("ExportNeuronsButton", () => {
]),
})
);
expect(generateCsvFileToSave).toHaveBeenCalledOnce();
});

it("should dispatch event after export", async () => {
const { po, component } = renderComponent();

const mockDispatch = vi.fn();
component.$on("nnsExportNeuronsCSVTriggered", mockDispatch);
it("should dispatch nnsExportNeuronsCsvTriggered event after click to close the menu", async () => {
const onTrigger = vi.fn();
const { po } = renderComponent({ onTrigger });

expect(onTrigger).not.toHaveBeenCalled();
await po.click();

expect(mockDispatch).toHaveBeenCalledTimes(1);
expect(mockDispatch.mock.calls[0][0].type).toBe(
"nnsExportNeuronsCSVTriggered"
);
expect(onTrigger).toHaveBeenCalledOnce();
});

it("should show error toast when file system access fails", async () => {
Expand All @@ -113,10 +119,13 @@ describe("ExportNeuronsButton", () => {
);

const { po } = renderComponent();

expect(toastsError).not.toHaveBeenCalled();
await po.click();
expect(toastsError).toHaveBeenCalledWith({
labelKey: "export_error.file_system_access",
});
expect(toastsError).toHaveBeenCalledOnce();
});

it("should show error toast when Csv generation fails", async () => {
Expand All @@ -125,10 +134,13 @@ describe("ExportNeuronsButton", () => {
);

const { po } = renderComponent();

expect(toastsError).not.toHaveBeenCalled();
await po.click();
expect(toastsError).toHaveBeenCalledWith({
labelKey: "export_error.csv_generation",
});
expect(toastsError).toHaveBeenCalledOnce();
});

it("should show error toast when file saving fails", async () => {
Expand All @@ -137,9 +149,12 @@ describe("ExportNeuronsButton", () => {
);

const { po } = renderComponent();

expect(toastsError).not.toHaveBeenCalled();
await po.click();
expect(toastsError).toHaveBeenCalledWith({
labelKey: "export_error.neurons",
});
expect(toastsError).toHaveBeenCalledOnce();
});
});
Loading