mirror of
https://github.com/portainer/portainer.git
synced 2025-08-04 21:35:23 +02:00
fix(kube): improve dashboard load speed [EE-4941] (#8572)
* apply changes from EE * clear query cache when logging out * Text transitions in smoother
This commit is contained in:
parent
5f0af62521
commit
89194405ee
36 changed files with 569 additions and 210 deletions
|
@ -1,3 +0,0 @@
|
|||
.dashboard-grid {
|
||||
@apply grid grid-cols-2 gap-3;
|
||||
}
|
|
@ -1,7 +1,5 @@
|
|||
import { PropsWithChildren } from 'react';
|
||||
|
||||
import './DashboardGrid.css';
|
||||
|
||||
export function DashboardGrid({ children }: PropsWithChildren<unknown>) {
|
||||
return <div className="dashboard-grid">{children}</div>;
|
||||
return <div className="grid grid-cols-2 gap-3">{children}</div>;
|
||||
}
|
||||
|
|
|
@ -1,25 +1,62 @@
|
|||
import { ReactNode } from 'react';
|
||||
import clsx from 'clsx';
|
||||
import { Loader2 } from 'lucide-react';
|
||||
|
||||
import { Icon, IconProps } from '@/react/components/Icon';
|
||||
import { pluralize } from '@/portainer/helpers/strings';
|
||||
|
||||
import { Link } from '@@/Link';
|
||||
|
||||
interface Props extends IconProps {
|
||||
value?: number;
|
||||
type: string;
|
||||
pluralType?: string; // in case the pluralise function isn't suitable
|
||||
isLoading?: boolean;
|
||||
isRefetching?: boolean;
|
||||
value?: number;
|
||||
to?: string;
|
||||
children?: ReactNode;
|
||||
dataCy?: string;
|
||||
}
|
||||
|
||||
export function DashboardItem({ value, icon, type, children }: Props) {
|
||||
return (
|
||||
export function DashboardItem({
|
||||
icon,
|
||||
type,
|
||||
pluralType,
|
||||
isLoading,
|
||||
isRefetching,
|
||||
value,
|
||||
to,
|
||||
children,
|
||||
dataCy,
|
||||
}: Props) {
|
||||
const Item = (
|
||||
<div
|
||||
className={clsx(
|
||||
'rounded-lg border border-solid p-3',
|
||||
'relative rounded-lg border border-solid p-3',
|
||||
'border-gray-5 bg-gray-2 hover:border-blue-7 hover:bg-blue-2',
|
||||
'th-dark:border-gray-neutral-8 th-dark:bg-gray-iron-10 th-dark:hover:border-blue-8 th-dark:hover:bg-gray-10',
|
||||
'th-highcontrast:border-white th-highcontrast:bg-black th-highcontrast:hover:border-blue-8 th-highcontrast:hover:bg-gray-11'
|
||||
)}
|
||||
data-cy={dataCy}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
'text-muted absolute top-2 right-2 flex items-center transition-opacity',
|
||||
isRefetching ? 'opacity-100' : 'opacity-0'
|
||||
)}
|
||||
>
|
||||
Refreshing total
|
||||
<Loader2 className="h-4 animate-spin-slow" />
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
'text-muted absolute top-2 right-2 flex items-center transition-opacity',
|
||||
isLoading ? 'opacity-100' : 'opacity-0'
|
||||
)}
|
||||
>
|
||||
Loading total
|
||||
<Loader2 className="h-4 animate-spin-slow" />
|
||||
</div>
|
||||
<div className="flex items-center" aria-label={type}>
|
||||
<div
|
||||
className={clsx(
|
||||
|
@ -42,7 +79,7 @@ export function DashboardItem({ value, icon, type, children }: Props) {
|
|||
)}
|
||||
aria-label="value"
|
||||
>
|
||||
{typeof value !== 'undefined' ? value : '-'}
|
||||
{typeof value === 'undefined' ? '-' : value}
|
||||
</div>
|
||||
<div
|
||||
className={clsx(
|
||||
|
@ -53,7 +90,7 @@ export function DashboardItem({ value, icon, type, children }: Props) {
|
|||
)}
|
||||
aria-label="resourceType"
|
||||
>
|
||||
{pluralize(value || 0, type)}
|
||||
{pluralize(value || 0, type, pluralType)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -61,4 +98,13 @@ export function DashboardItem({ value, icon, type, children }: Props) {
|
|||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
if (to) {
|
||||
return (
|
||||
<Link to={to} className="!no-underline">
|
||||
{Item}
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
return Item;
|
||||
}
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
.reloadButton {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
|
@ -7,7 +7,6 @@ import { Breadcrumbs } from './Breadcrumbs';
|
|||
import { Crumb } from './Breadcrumbs/Breadcrumbs';
|
||||
import { HeaderContainer } from './HeaderContainer';
|
||||
import { HeaderTitle } from './HeaderTitle';
|
||||
import styles from './PageHeader.module.css';
|
||||
|
||||
interface Props {
|
||||
id?: string;
|
||||
|
@ -42,7 +41,7 @@ export function PageHeader({
|
|||
color="none"
|
||||
size="large"
|
||||
onClick={onClickedRefresh}
|
||||
className={styles.reloadButton}
|
||||
className="m-0 p-0 focus:text-inherit"
|
||||
disabled={loading}
|
||||
>
|
||||
<RefreshCw className="icon" />
|
||||
|
|
|
@ -8,6 +8,7 @@ import { UISrefProps, useSref } from '@uirouter/react';
|
|||
import clsx from 'clsx';
|
||||
import { User, ChevronDown } from 'lucide-react';
|
||||
|
||||
import { queryClient } from '@/react-tools/react-query';
|
||||
import { AutomationTestingProps } from '@/types';
|
||||
import { useUser } from '@/react/hooks/useUser';
|
||||
|
||||
|
@ -78,7 +79,10 @@ function MenuLink({
|
|||
return (
|
||||
<ReachMenuLink
|
||||
href={anchorProps.href}
|
||||
onClick={anchorProps.onClick}
|
||||
onClick={(e) => {
|
||||
queryClient.clear();
|
||||
anchorProps.onClick(e);
|
||||
}}
|
||||
className={styles.menuLink}
|
||||
aria-label={label}
|
||||
data-cy={dataCy}
|
||||
|
|
|
@ -19,10 +19,12 @@ test('should show the selected tags', async () => {
|
|||
{
|
||||
ID: 1,
|
||||
Name: 'tag1',
|
||||
Endpoints: {},
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
Name: 'tag2',
|
||||
Endpoints: {},
|
||||
},
|
||||
];
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue