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

Rendering and markup for statistic tab #3

Merged
merged 15 commits into from
Feb 22, 2024
Merged

Rendering and markup for statistic tab #3

merged 15 commits into from
Feb 22, 2024

Conversation

ViktoriiaNakoryk
Copy link
Contributor

created statistics tab and implemented it's rendering

@ViktoriiaNakoryk ViktoriiaNakoryk marked this pull request as draft February 15, 2024 14:18
Copy link
Collaborator

@MarcMcIntosh MarcMcIntosh left a comment

Choose a reason for hiding this comment

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

Looks good so far :)

I've left some comments about the ui and small bits of refactoring that can be done.

Once those are done, the messages for the event bus will need to be added. But I would keep the stub data, but move into a storybook story so it can be run without needing a server running.

const [isLoaded, setIsLoaded] = useState<boolean>(false);
const [refactTable, setRefactTable] = useState<RefactTableData | null>(null);
const { host, tabbed } = useConfig();
const { backFromChat } = useEventBusForChat();
Copy link
Collaborator

Choose a reason for hiding this comment

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

pass this as a prop, i've not made the event bus a context so (for now) this hook will recreate the state

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i fixed it, but because of moving backFromChat to the parent component there was a problem in test, so I mocked there useEventBusForChat

Copy link
Collaborator

Choose a reason for hiding this comment

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

Eeyup i saw, I've left a few comments, one that fixes the test and the other one which is a general question about if statistic should have it's own event bus?

import { useEventBusForChat } from "../../hooks";
import { useConfig } from "../../contexts/config-context";

const table: { data: string } = {
Copy link
Collaborator

Choose a reason for hiding this comment

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

this data stub could be added to storybook, it'll give you a visual feedback loop with out needing a backend

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

Copy link
Collaborator

Choose a reason for hiding this comment

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

src/__fixtures__ contains some data stubs, could table.data be moved there?

src/components/Chart/Chart.tsx Outdated Show resolved Hide resolved
src/components/Table/Table.tsx Outdated Show resolved Hide resolved
src/components/Table/Table.module.css Outdated Show resolved Hide resolved
src/lib/render/RenderStatistic.tsx Show resolved Hide resolved
src/services/refact.ts Show resolved Hide resolved
@@ -71,6 +71,8 @@
"@vitest/coverage-v8": "^1.1.0",
"@vitest/ui": "^1.1.0",
"classnames": "^2.3.2",
"echarts": "^5.4.3",
Copy link
Collaborator

Choose a reason for hiding this comment

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

Interesting :)... I've not seen this library before, I'll need to check the bundle size but I'd imagine it's tree shakable

Copy link
Collaborator

Choose a reason for hiding this comment

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

run npx vite-bundle-visualizer if you want check the bundle size 👍🏻

src/components/Sidebar/Sidebar.tsx Show resolved Hide resolved
Copy link
Collaborator

@MarcMcIntosh MarcMcIntosh left a comment

Choose a reason for hiding this comment

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

A couple of changes todo, and a question about the number format :)

import { useEventBusForChat } from "../../hooks";
import { useConfig } from "../../contexts/config-context";

const table: { data: string } = {
Copy link
Collaborator

Choose a reason for hiding this comment

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

src/__fixtures__ contains some data stubs, could table.data be moved there?

import React from "react";
import { Box, Text } from "@radix-ui/themes";
import { RefactTableImpactDateObj } from "../../services/refact";
import ReactEcharts from "echarts-for-react";
Copy link
Collaborator

Choose a reason for hiding this comment

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

Reading the useage guide https://github.com/hustcc/echarts-for-react?tab=readme-ov-file#usage

it looks like there's a way to manually to reduce bundle size, i think that would be a good idea to try because when I run npx vite-bundle-visualizer echarts is about 2mb and it seems not all of echarts is being used.

{isOpenedStatistic ? (
<Statistic
onCloseStatistic={handleCloseStatistic}
backFromChat={backFromChat}
Copy link
Collaborator

Choose a reason for hiding this comment

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

ahh, i see why backFromChat this is added here, it's because it also has to be rendered in the side bar.

🤔 that's a tricky one.... maybe statistic needs it's own event bus hook 🤔

is there a PR for adding this to vscode?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yeap, I also think that may be it is better to create own event bus for statistic. I am going to do it today.

I've connected rendered statistic with vscode, but pr for vscode isn't created yet because I don't have permission yet

src/components/Sidebar/Sidebar.tsx Show resolved Hide resolved
} else {
const convertedNumber = Number(
cellValue
.toLocaleString("en-US", {
Copy link
Collaborator

Choose a reason for hiding this comment

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

what's the intended format / conversion that's happening here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

numbers in table are like this: 563892, 64563 so they have a lot of digits, and to make that numbers readable I used toLocaleString to format the number so it has commas in the correct position(564731=> 56,4731) and after that rounded them to 2 digits after comma and and also added k, so the final result is 56.47k

Copy link
Collaborator

Choose a reason for hiding this comment

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

good point lots of digits would clutter the ui,
what would happen with a number with multiple commas in it? are we likely to see a number that big?

Copy link
Collaborator

@MarcMcIntosh MarcMcIntosh Feb 21, 2024

Choose a reason for hiding this comment

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

Small bug here, after 100000 the result is NaNk.

it was found it when I was trying to test/guess the result for different inputs, most of them fail so I might be misunderstanding something.

Here’s the tests i ran, add them somewhere in the project like src/Table/formatCellValue.test.tsx and run it with npm test -- src/Table/formatCellValue.test.tsx to recreate the issue :)

// src/Table/formatCellValue.test.tsx
import { describe, test, expect } from "vitest";

function formatCellValue(cellValue: number | string): string {
  const convertedNumber = Number(cellValue.toLocaleString("en-US", {style: "decimal",maximumFractionDigits: 0,minimumFractionDigits: 0,useGrouping: true,}).replace(",", "."));
  if (convertedNumber === 0) {
    return "0";
  } else if (Number.isInteger(convertedNumber)) {
    return convertedNumber + "k";
  } else {
    return `${convertedNumber}k`;
  }
}

describe("formatCellValue", () => {
  test.each<[number | string, string]>([
    ["0", "0"],
    ["10", "10"],
    ["100", "100"],
    ["1000", "1k"],
    ["10000", "10k"],
    ["564731", "56,47k"],
    ["100000", "100k"],
    ["1000000", "1000k"],
    [0, "0"],
    [10, "10"],
    [100, "100"],
    [1000, "1k"],
    [10000, "10k"],
    [564731, "56,47k"],
    [100000, "100k"],
    [1000000, "1000k"],
  ])("returns %s for %s", (cellValue, expected) => {
    expect(formatCellValue(cellValue)).toEqual(expected);
  });
});

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

@@ -5,6 +5,12 @@ import { EVENT_NAMES_TO_CHAT } from "../events";

import { ChatHistoryItem } from "../hooks/useChatHistory";

vi.mock("../hooks/useEventBusForChat", () => ({
Copy link
Collaborator

Choose a reason for hiding this comment

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

I don't think useEventBusrForChat needs to be mocked, it seems that the last call to the spy is from request caps.

It's a small update to the existing test, mock uuid and change the expected last call to postMessageSpy

  it("start new chat", async () => {
    vi.mock("uuid", () => ({ v4: () => "foo" }));
    const { user, ...app } = render(<HistorySideBar />);

    const postMessageSpy = vi.spyOn(window, "postMessage");

    const startNewChatButton = app.getByText("Start a new chat");

    await user.click(startNewChatButton);

    expect(postMessageSpy).toHaveBeenCalledWith({type: EVENT_NAMES_TO_CHAT.NEW_CHAT }, "*");

    expect(postMessageSpy).toHaveBeenLastCalledWith({ type: EVENT_NAMES_FROM_CHAT.REQUEST_CAPS, payload: { id: "foo" } }, "*")

});

…ts only with that components which are used here. fixed storybooks for chart and table because of error during build
Copy link
Collaborator

@MarcMcIntosh MarcMcIntosh left a comment

Choose a reason for hiding this comment

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

A few small changes and a small bug to fix 👍🏻

Copy link
Collaborator

Choose a reason for hiding this comment

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

nice

Copy link
Collaborator

Choose a reason for hiding this comment

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

For readability, can you save the parsed json and use JSON.stringify when it's being exported?

const json = {...}
export const TABLE = {
  data: JSON.stringify(json)
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

src/components/Chart/Chart.tsx Show resolved Hide resolved
} else {
const convertedNumber = Number(
cellValue
.toLocaleString("en-US", {
Copy link
Collaborator

Choose a reason for hiding this comment

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

good point lots of digits would clutter the ui,
what would happen with a number with multiple commas in it? are we likely to see a number that big?

Copy link
Collaborator

Choose a reason for hiding this comment

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

nice

return (
<ConfigProvider config={config}>
<Theme>
<Statistic backFromStatistic={backFromStatistic} />
Copy link
Collaborator

Choose a reason for hiding this comment

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

looks like we're heading in the right direction :)

I've been putting large components that use/call the event bus in in the src/features directory.

Then adding renderer for it in lib so it can be exported like a component :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed

} else {
const convertedNumber = Number(
cellValue
.toLocaleString("en-US", {
Copy link
Collaborator

@MarcMcIntosh MarcMcIntosh Feb 21, 2024

Choose a reason for hiding this comment

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

Small bug here, after 100000 the result is NaNk.

it was found it when I was trying to test/guess the result for different inputs, most of them fail so I might be misunderstanding something.

Here’s the tests i ran, add them somewhere in the project like src/Table/formatCellValue.test.tsx and run it with npm test -- src/Table/formatCellValue.test.tsx to recreate the issue :)

// src/Table/formatCellValue.test.tsx
import { describe, test, expect } from "vitest";

function formatCellValue(cellValue: number | string): string {
  const convertedNumber = Number(cellValue.toLocaleString("en-US", {style: "decimal",maximumFractionDigits: 0,minimumFractionDigits: 0,useGrouping: true,}).replace(",", "."));
  if (convertedNumber === 0) {
    return "0";
  } else if (Number.isInteger(convertedNumber)) {
    return convertedNumber + "k";
  } else {
    return `${convertedNumber}k`;
  }
}

describe("formatCellValue", () => {
  test.each<[number | string, string]>([
    ["0", "0"],
    ["10", "10"],
    ["100", "100"],
    ["1000", "1k"],
    ["10000", "10k"],
    ["564731", "56,47k"],
    ["100000", "100k"],
    ["1000000", "1000k"],
    [0, "0"],
    [10, "10"],
    [100, "100"],
    [1000, "1k"],
    [10000, "10k"],
    [564731, "56,47k"],
    [100000, "100k"],
    [1000000, "1000k"],
  ])("returns %s for %s", (cellValue, expected) => {
    expect(formatCellValue(cellValue)).toEqual(expected);
  });
});

setRefactTable(JSON.parse(TABLE.data) as RefactTableData);
setIsLoaded(true);
}
}, []);
Copy link
Collaborator

Choose a reason for hiding this comment

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

note: this hook will run only when the component mounts, it'll work for now since the data is always there

Copy link
Collaborator

@MarcMcIntosh MarcMcIntosh left a comment

Choose a reason for hiding this comment

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

One last thing to do be merging and that would be to hide this under a feature flag until it's complete.

I think a features property to the config context should do the trick, and the if config.features.statistics is true the statistics button can be shown.

What do you think?

@ViktoriiaNakoryk ViktoriiaNakoryk marked this pull request as ready for review February 22, 2024 11:55
Copy link
Collaborator

@MarcMcIntosh MarcMcIntosh left a comment

Choose a reason for hiding this comment

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

looks good to me 👍🏻

@ViktoriiaNakoryk ViktoriiaNakoryk merged commit b8d42a7 into main Feb 22, 2024
2 checks passed
@ViktoriiaNakoryk ViktoriiaNakoryk deleted the statistic branch February 22, 2024 13:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants