Skip to content

Conversation

@artemmufazalov
Copy link
Member

@artemmufazalov artemmufazalov commented Jan 30, 2024

Issue: #659

Charts should be hidden, if they are not enabled. Since charts dashboard is quite big and causes layout shifts, it should be hidden under loader together with other content until charts data loads and it's clear, whether to show dashboard or not

Node, where charts are not enabled: https://nda.ya.ru/t/OnrxodIe74UwCV

Node, where charts enabled: https://nda.ya.ru/t/7w84LYSB74UwDE

@artemmufazalov artemmufazalov linked an issue Jan 30, 2024 that may be closed by this pull request
@artemmufazalov artemmufazalov marked this pull request as ready for review January 30, 2024 15:25
const [chartDataStatus, setChartDataStatus] = useState<ChartDataStatus>('loading');

// Update status in useEffect instead of fetchChartData, so data won't be fetched on callback update
useEffect(() => {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should resolve problem with changable callback. It seems that such a combination of useState and useEffect may cause a lot of unneeded re-renders. Let's try to fix it.

Copy link
Member Author

Choose a reason for hiding this comment

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

Replaced it with useEffect, dependant on chart state. It should not cause additional rerenders, since component already rerenders on reducer state change

charts={cpuDashboardConfig}
onDashboardLoad={() => setDashboardLoading(false)}
/>
<TopNodesByLoad path={path} additionalNodesProps={additionalNodesProps} />
Copy link
Contributor

Choose a reason for hiding this comment

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

Why are all this components in one LoadingContainer and their visibility depends on dashboardLoading ?
I would better move loading logic to TenantDashboard. If you do so, you won't need LoadingContainer at all.

Copy link
Member Author

Choose a reason for hiding this comment

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

uplot charts don't render correctly in components with display:none. Fixed this issue with a hack, removed additional containers

// Use visibility:hidden to preserve loading content size
// Also it helps to properly render charts and virtualized elements
// that didn't render properly with display:none since they need parent container sizes
export const LoadingContainer = ({
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure that this additional wrapper above Loader is really essential. I would better stick to basic library component without wrappers.


export const TenantDashboard = ({charts, onDashboardLoad}: TenantDashboardProps) => {
const [dashboardStatus, setDashboardStatus] = useState<TenantDashboardStatus>();
const chartsStatuses = useRef<DashboardsChartsStatuses>({});
Copy link
Contributor

Choose a reason for hiding this comment

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

It seem a bit redundant: you need to know if at least one chart is succeed. So, no need to check charts id's:

const [showDashboard, setShowDashboard] = useState(false);
... one chart was loaded => setShowDashboard(true) ...
... no chats was loaded => do nothing ...
if (!showDashboard) {
  return null;
}

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep, updated it. Didn't figured out in the beginning, that we can prevent charts refetches with autorefresh variable

* @link https://github.com/ydb-platform/ydb-embedded-ui/issues/659
* @todo disable only for specific errors ('GraphShard is not enabled') after ydb-stable-24 is generally used
*/
const handleChartDataStatusChange = (chartStatus: ChartDataStatus) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems that you are interested only in success finish. So, lets rename this to let's say handleChartLoadingSucceeded and execute it only in one case - if chart was successfully loaded.

Copy link
Member Author

Choose a reason for hiding this comment

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

I made quite a universal solution, to make it possible to extend it later - hide charts only on specific errors.

Currently they are hidden on every error, including timeouts when node is not healthy, some internal problems, etc. The reason - versions without render endpoint don't return specific error.

Further charts should be hidden only on specific errors, when GraphShard is not enabled - added todo not to forger.

observer.current?.unobserve(el);
}
};
}, [ref]);
Copy link
Contributor

Choose a reason for hiding this comment

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

Ref can't be a dependency.

// uplot has the issue, that it doesn't render correctly inside not visible elements
// so if chart is used inside component with display:none, it will be empty, when visibility change
const containerRef = useRef<HTMLDivElement>(null);
const isChartVisible = useIsElementVisible(containerRef);
Copy link
Contributor

Choose a reason for hiding this comment

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

It looks much more straightforward to pass isChartVisible property from parent.

Copy link
Member Author

Choose a reason for hiding this comment

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

It's more straightforward, but it makes you to pass visible prop whenever you want to hide some component, that has charts inside. For example, if I'd want to add NotRenderUntilFirstVisible logic to tenant diagnostics tabs, it won't be possible without props drilling to ensure charts properly hidden and shown

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, but it seems to be fair. If you want to hide component - you should do it explicitly. Logic with ResizeObserver is more complicated and hidden.

@artemmufazalov artemmufazalov merged commit fe0cad4 into main Feb 7, 2024
@artemmufazalov artemmufazalov deleted the hide-disabled-charts branch February 7, 2024 14:21
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.

Hide diagnostics charts if they are not enabled

3 participants