Migrate paths dashboard widget to react and add storage metrics
This commit is contained in:
@@ -0,0 +1,22 @@
|
||||
import { describe, expect, it } from 'vitest';
|
||||
import { getReadableSize } from './file';
|
||||
|
||||
describe('getReadableSize()', () => {
|
||||
it('should return the correct units', () => {
|
||||
expect(getReadableSize(5)).toBe('5.0 Bytes');
|
||||
expect(getReadableSize(1024)).toBe('1.0 KiB');
|
||||
expect(getReadableSize(1024 * 1024)).toBe('1.0 MiB');
|
||||
expect(getReadableSize(1024 * 1024 * 1024)).toBe('1.0 GiB');
|
||||
expect(getReadableSize(1024 * 1024 * 1024 * 1024)).toBe('1.0 TiB');
|
||||
expect(getReadableSize(1024 * 1024 * 1024 * 1024 * 1024)).toBe('1.0 PiB');
|
||||
expect(getReadableSize(1024 * 1024 * 1024 * 1024 * 1024 * 1024)).toBe('1.0 EiB');
|
||||
expect(getReadableSize(1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024)).toBe('1.0 ZiB');
|
||||
expect(getReadableSize(1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024)).toBe('1.0 YiB');
|
||||
});
|
||||
|
||||
it('should return the correct precision', () => {
|
||||
expect(getReadableSize(12345, 0)).toBe('12 KiB');
|
||||
expect(getReadableSize(12345, 2)).toBe('12.06 KiB');
|
||||
expect(getReadableSize(12345, 3)).toBe('12.056 KiB');
|
||||
});
|
||||
});
|
||||
@@ -28,3 +28,11 @@ export function readFileAsText(file: File): Promise<string> {
|
||||
reader.readAsText(file);
|
||||
});
|
||||
}
|
||||
|
||||
/** Gets a human readable string representing a file size in bytes */
|
||||
export function getReadableSize(value: number, precision = 1) {
|
||||
let d = Math.log(value) / Math.log(1024) | 0;
|
||||
|
||||
return (value / Math.pow(1024, d)).toFixed(precision)
|
||||
+ ' ' + (d ? 'KMGTPEZY'[--d] + 'iB' : 'Bytes');
|
||||
}
|
||||
|
||||
+17
-19
@@ -1,36 +1,34 @@
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import * as React from 'react';
|
||||
import { ThemeProvider } from '@mui/material/styles';
|
||||
import { QueryClientProvider } from '@tanstack/react-query';
|
||||
import * as React from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
|
||||
import { ApiProvider } from 'hooks/useApi';
|
||||
import { UserSettingsProvider } from 'hooks/useUserSettings';
|
||||
import { WebConfigProvider } from 'hooks/useWebConfig';
|
||||
import appTheme from 'themes/themes';
|
||||
import { queryClient } from 'utils/query/queryClient';
|
||||
import { useUserTheme } from 'hooks/useUserTheme';
|
||||
import { ThemeProvider } from '@mui/material/styles';
|
||||
import { getTheme } from 'themes/themes';
|
||||
|
||||
export const attachReactElement = (Element: (props: object) => React.ReactNode, props: object, element: HTMLElement, replace = false) => {
|
||||
const domNode = document.createElement('div');
|
||||
const root = createRoot(replace ? domNode : element);
|
||||
root.render(
|
||||
<RootContext>
|
||||
<Element {...props} />
|
||||
</RootContext>
|
||||
);
|
||||
|
||||
if (replace) {
|
||||
element.replaceWith(domNode);
|
||||
}
|
||||
export const renderComponent = <P extends object> (
|
||||
Component: React.FC<P>,
|
||||
props: P,
|
||||
element: HTMLElement
|
||||
) => {
|
||||
createRoot(element)
|
||||
.render(
|
||||
<RootContext>
|
||||
<Component {...props} />
|
||||
</RootContext>
|
||||
);
|
||||
};
|
||||
|
||||
const RootContext: React.FC<React.PropsWithChildren> = ({ children }) => {
|
||||
const { theme } = useUserTheme();
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<ApiProvider>
|
||||
<UserSettingsProvider>
|
||||
<WebConfigProvider>
|
||||
<ThemeProvider theme={getTheme(theme)}>
|
||||
<ThemeProvider theme={appTheme} defaultMode='dark'>
|
||||
{children}
|
||||
</ThemeProvider>
|
||||
</WebConfigProvider>
|
||||
|
||||
Reference in New Issue
Block a user