mirror of https://github.com/buster-so/buster.git
Merge pull request #1179 from buster-so/big-nate-bus-1964-background-color-for-public-url-dashboard-is-wrong
change embed page background
This commit is contained in:
commit
d7b25435d6
|
@ -0,0 +1,359 @@
|
|||
import { fireEvent, render, screen } from '@testing-library/react';
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import '@testing-library/jest-dom';
|
||||
import type { ShareMenuContentBodyProps } from './ShareMenuContentBody';
|
||||
import { ShareMenuContentPublish } from './ShareMenuContentPublish';
|
||||
|
||||
// Mock all external dependencies
|
||||
const mockOnShareMetric = vi.fn();
|
||||
const mockOnShareDashboard = vi.fn();
|
||||
const mockOnShareCollection = vi.fn();
|
||||
const mockOnShareReport = vi.fn();
|
||||
const mockOnShareChat = vi.fn();
|
||||
const mockOnCopyLink = vi.fn();
|
||||
const mockTimeout = vi.fn().mockResolvedValue(true);
|
||||
|
||||
// Mock the timeout utility
|
||||
vi.mock('@/lib/timeout', () => ({
|
||||
timeout: (time?: number) => mockTimeout(time),
|
||||
}));
|
||||
|
||||
describe('onTogglePublish', () => {
|
||||
const baseProps = {
|
||||
assetId: 'test-asset-id',
|
||||
password: 'test-password',
|
||||
publicly_accessible: false,
|
||||
onCopyLink: mockOnCopyLink,
|
||||
publicExpirationDate: null,
|
||||
embedLinkURL: 'https://example.com/embed',
|
||||
} satisfies Partial<ShareMenuContentBodyProps>;
|
||||
|
||||
const baseDate = new Date('2023-12-25T10:00:00Z');
|
||||
const linkExpiry = baseDate;
|
||||
|
||||
// Helper function to create the onTogglePublish function with mocked dependencies
|
||||
const createOnTogglePublish = (
|
||||
assetType: ShareMenuContentBodyProps['assetType'],
|
||||
_password = 'test-password',
|
||||
linkExpiryParam: Date | null = null
|
||||
) => {
|
||||
return async (v?: boolean) => {
|
||||
const linkExp = linkExpiryParam ? linkExpiryParam.toISOString() : null;
|
||||
const payload = {
|
||||
id: baseProps.assetId,
|
||||
params: {
|
||||
publicly_accessible: v === undefined ? true : !!v,
|
||||
public_password: _password || undefined,
|
||||
public_expiry_date: linkExp || undefined,
|
||||
},
|
||||
};
|
||||
|
||||
if (assetType === 'metric_file') {
|
||||
await mockOnShareMetric(payload);
|
||||
} else if (assetType === 'dashboard_file') {
|
||||
await mockOnShareDashboard(payload);
|
||||
} else if (assetType === 'collection') {
|
||||
await mockOnShareCollection(payload);
|
||||
} else if (assetType === 'report_file') {
|
||||
await mockOnShareReport(payload);
|
||||
} else if (assetType === 'chat') {
|
||||
await mockOnShareChat(payload);
|
||||
} else {
|
||||
const _exhaustiveCheck: never = assetType;
|
||||
}
|
||||
await mockTimeout(100);
|
||||
if (v) mockOnCopyLink(true);
|
||||
};
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should call onShareMetric for metric_file asset type with default publicly_accessible true', async () => {
|
||||
const onTogglePublish = createOnTogglePublish('metric_file');
|
||||
|
||||
await onTogglePublish();
|
||||
|
||||
expect(mockOnShareMetric).toHaveBeenCalledWith({
|
||||
id: 'test-asset-id',
|
||||
params: {
|
||||
publicly_accessible: true,
|
||||
public_password: 'test-password',
|
||||
public_expiry_date: undefined,
|
||||
},
|
||||
});
|
||||
expect(mockTimeout).toHaveBeenCalledWith(100);
|
||||
expect(mockOnCopyLink).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call onShareDashboard for dashboard_file asset type with explicit true value', async () => {
|
||||
const onTogglePublish = createOnTogglePublish(
|
||||
'dashboard_file',
|
||||
'dashboard-password',
|
||||
linkExpiry
|
||||
);
|
||||
|
||||
await onTogglePublish(true);
|
||||
|
||||
expect(mockOnShareDashboard).toHaveBeenCalledWith({
|
||||
id: 'test-asset-id',
|
||||
params: {
|
||||
publicly_accessible: true,
|
||||
public_password: 'dashboard-password',
|
||||
public_expiry_date: '2023-12-25T10:00:00.000Z',
|
||||
},
|
||||
});
|
||||
expect(mockTimeout).toHaveBeenCalledWith(100);
|
||||
expect(mockOnCopyLink).toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
it('should call onShareCollection for collection asset type with false value', async () => {
|
||||
const onTogglePublish = createOnTogglePublish('collection');
|
||||
|
||||
await onTogglePublish(false);
|
||||
|
||||
expect(mockOnShareCollection).toHaveBeenCalledWith({
|
||||
id: 'test-asset-id',
|
||||
params: {
|
||||
publicly_accessible: false,
|
||||
public_password: 'test-password',
|
||||
public_expiry_date: undefined,
|
||||
},
|
||||
});
|
||||
expect(mockTimeout).toHaveBeenCalledWith(100);
|
||||
expect(mockOnCopyLink).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should call onShareReport for report_file asset type', async () => {
|
||||
const onTogglePublish = createOnTogglePublish('report_file');
|
||||
|
||||
await onTogglePublish();
|
||||
|
||||
expect(mockOnShareReport).toHaveBeenCalledWith({
|
||||
id: 'test-asset-id',
|
||||
params: {
|
||||
publicly_accessible: true,
|
||||
public_password: 'test-password',
|
||||
public_expiry_date: undefined,
|
||||
},
|
||||
});
|
||||
expect(mockTimeout).toHaveBeenCalledWith(100);
|
||||
});
|
||||
|
||||
it('should call onShareChat for chat asset type', async () => {
|
||||
const onTogglePublish = createOnTogglePublish('chat');
|
||||
|
||||
await onTogglePublish();
|
||||
|
||||
expect(mockOnShareChat).toHaveBeenCalledWith({
|
||||
id: 'test-asset-id',
|
||||
params: {
|
||||
publicly_accessible: true,
|
||||
public_password: 'test-password',
|
||||
public_expiry_date: undefined,
|
||||
},
|
||||
});
|
||||
expect(mockTimeout).toHaveBeenCalledWith(100);
|
||||
});
|
||||
|
||||
it('should handle empty password by setting public_password to undefined', async () => {
|
||||
const onTogglePublish = createOnTogglePublish('metric_file', '');
|
||||
|
||||
await onTogglePublish();
|
||||
|
||||
expect(mockOnShareMetric).toHaveBeenCalledWith({
|
||||
id: 'test-asset-id',
|
||||
params: {
|
||||
publicly_accessible: true,
|
||||
public_password: undefined,
|
||||
public_expiry_date: undefined,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle null linkExpiry by setting public_expiry_date to null', async () => {
|
||||
const onTogglePublish = createOnTogglePublish('dashboard_file', 'password', null);
|
||||
|
||||
await onTogglePublish();
|
||||
|
||||
expect(mockOnShareDashboard).toHaveBeenCalledWith({
|
||||
id: 'test-asset-id',
|
||||
params: {
|
||||
publicly_accessible: true,
|
||||
public_password: 'password',
|
||||
public_expiry_date: undefined,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should convert linkExpiry Date to ISO string', async () => {
|
||||
const testDate = new Date('2024-01-15T15:30:00Z');
|
||||
const onTogglePublish = createOnTogglePublish('collection', 'password', testDate);
|
||||
|
||||
await onTogglePublish();
|
||||
|
||||
expect(mockOnShareCollection).toHaveBeenCalledWith({
|
||||
id: 'test-asset-id',
|
||||
params: {
|
||||
publicly_accessible: true,
|
||||
public_password: 'password',
|
||||
public_expiry_date: '2024-01-15T15:30:00.000Z',
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('should call onCopyLink when v is truthy', async () => {
|
||||
const onTogglePublish = createOnTogglePublish('metric_file');
|
||||
|
||||
await onTogglePublish(true);
|
||||
|
||||
expect(mockOnCopyLink).toHaveBeenCalledWith(true);
|
||||
});
|
||||
|
||||
it('should not call onCopyLink when v is falsy', async () => {
|
||||
const onTogglePublish = createOnTogglePublish('metric_file');
|
||||
|
||||
await onTogglePublish(false);
|
||||
|
||||
expect(mockOnCopyLink).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
// Mock all the hooks for React component tests
|
||||
vi.mock('@/api/buster_rest/chats', () => ({
|
||||
useUpdateChatShare: () => ({
|
||||
mutateAsync: mockOnShareChat,
|
||||
isPending: false,
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock('@/api/buster_rest/collections', () => ({
|
||||
useUpdateCollectionShare: () => ({
|
||||
mutateAsync: mockOnShareCollection,
|
||||
isPending: false,
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock('@/api/buster_rest/dashboards', () => ({
|
||||
useUpdateDashboardShare: () => ({
|
||||
mutateAsync: mockOnShareDashboard,
|
||||
isPending: false,
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock('@/api/buster_rest/metrics', () => ({
|
||||
useUpdateMetricShare: () => ({
|
||||
mutateAsync: mockOnShareMetric,
|
||||
isPending: false,
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock('@/api/buster_rest/reports', () => ({
|
||||
useUpdateReportShare: () => ({
|
||||
mutateAsync: mockOnShareReport,
|
||||
isPending: false,
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock('@/context/BusterNotifications', () => ({
|
||||
useBusterNotifications: () => ({
|
||||
openInfoMessage: vi.fn(),
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock('@/context/Routes/useRouteBuilder', () => ({
|
||||
useBuildLocation: () => vi.fn(),
|
||||
}));
|
||||
|
||||
describe('ShareMenuContentPublish Component', () => {
|
||||
const defaultProps: ShareMenuContentBodyProps = {
|
||||
assetType: 'metric_file',
|
||||
assetId: 'test-asset-id',
|
||||
password: '',
|
||||
publicly_accessible: false,
|
||||
onCopyLink: mockOnCopyLink,
|
||||
publicExpirationDate: null,
|
||||
className: '',
|
||||
embedLinkURL: 'https://example.com/embed/test-asset-id',
|
||||
individual_permissions: [],
|
||||
canEditPermissions: true,
|
||||
shareAssetConfig: {
|
||||
individual_permissions: [],
|
||||
publicly_accessible: false,
|
||||
public_expiry_date: null,
|
||||
public_password: '',
|
||||
permission: 'owner',
|
||||
workspace_sharing: null,
|
||||
public_enabled_by: null,
|
||||
workspace_member_count: null,
|
||||
},
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should render create public link button when not publicly accessible', () => {
|
||||
render(<ShareMenuContentPublish {...defaultProps} />);
|
||||
|
||||
expect(screen.getByText('Anyone with the link will be able to view.')).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: 'Create public link' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should render published state with link input when publicly accessible', () => {
|
||||
const props = {
|
||||
...defaultProps,
|
||||
publicly_accessible: true,
|
||||
};
|
||||
|
||||
render(<ShareMenuContentPublish {...props} />);
|
||||
|
||||
expect(screen.getByText('Live on the web')).toBeInTheDocument();
|
||||
expect(screen.getByDisplayValue('https://example.com/embed/test-asset-id')).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: 'Unpublish' })).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: 'Copy link' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should show password protection controls when publicly accessible', () => {
|
||||
const props = {
|
||||
...defaultProps,
|
||||
publicly_accessible: true,
|
||||
};
|
||||
|
||||
render(<ShareMenuContentPublish {...props} />);
|
||||
|
||||
expect(screen.getByText('Set a password')).toBeInTheDocument();
|
||||
expect(screen.getByRole('switch')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should enable password input when password protection is toggled on', async () => {
|
||||
const props = {
|
||||
...defaultProps,
|
||||
publicly_accessible: true,
|
||||
};
|
||||
|
||||
render(<ShareMenuContentPublish {...props} />);
|
||||
|
||||
const passwordSwitch = screen.getByRole('switch');
|
||||
fireEvent.click(passwordSwitch);
|
||||
|
||||
expect(screen.getByPlaceholderText('Password')).toBeInTheDocument();
|
||||
expect(screen.getByRole('button', { name: 'Save' })).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should show password input with existing password when password is provided', () => {
|
||||
const props = {
|
||||
...defaultProps,
|
||||
publicly_accessible: true,
|
||||
password: 'existing-password',
|
||||
};
|
||||
|
||||
render(<ShareMenuContentPublish {...props} />);
|
||||
|
||||
// Password switch should be checked
|
||||
expect(screen.getByRole('switch')).toBeChecked();
|
||||
// Password input should be visible with the existing password
|
||||
expect(screen.getByDisplayValue('existing-password')).toBeInTheDocument();
|
||||
});
|
||||
});
|
|
@ -15,6 +15,7 @@ import { useBusterNotifications } from '@/context/BusterNotifications';
|
|||
import { useBuildLocation } from '@/context/Routes/useRouteBuilder';
|
||||
import { cn } from '@/lib/classMerge';
|
||||
import { createDayjsDate } from '@/lib/date';
|
||||
import { timeout } from '@/lib/timeout';
|
||||
import type { ShareMenuContentBodyProps } from './ShareMenuContentBody';
|
||||
|
||||
export const ShareMenuContentPublish: React.FC<ShareMenuContentBodyProps> = React.memo(
|
||||
|
@ -73,6 +74,8 @@ export const ShareMenuContentPublish: React.FC<ShareMenuContentBodyProps> = Reac
|
|||
} else {
|
||||
const _exhaustiveCheck: never = assetType;
|
||||
}
|
||||
await timeout(100);
|
||||
if (v) onCopyLink(true);
|
||||
};
|
||||
|
||||
const onSetPasswordProtected = async (v: boolean) => {
|
||||
|
|
|
@ -0,0 +1,234 @@
|
|||
import type { ShareAssetType, ShareConfig } from '@buster/server-shared/share';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { fireEvent, render, screen } from '@testing-library/react';
|
||||
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
||||
import { ShareMenuInvite } from './ShareMenuInvite';
|
||||
|
||||
// Create mock functions
|
||||
const mockShareMetric = vi.fn();
|
||||
const mockShareDashboard = vi.fn();
|
||||
const mockShareCollection = vi.fn();
|
||||
const mockShareChat = vi.fn();
|
||||
const mockShareReport = vi.fn();
|
||||
const mockOpenErrorMessage = vi.fn();
|
||||
|
||||
// Mock hooks
|
||||
vi.mock('@/api/buster_rest/chats', () => ({
|
||||
useShareChat: () => ({
|
||||
mutateAsync: mockShareChat,
|
||||
isPending: false,
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock('@/api/buster_rest/collections', () => ({
|
||||
useShareCollection: () => ({
|
||||
mutateAsync: mockShareCollection,
|
||||
isPending: false,
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock('@/api/buster_rest/dashboards', () => ({
|
||||
useShareDashboard: () => ({
|
||||
mutateAsync: mockShareDashboard,
|
||||
isPending: false,
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock('@/api/buster_rest/metrics', () => ({
|
||||
useShareMetric: () => ({
|
||||
mutateAsync: mockShareMetric,
|
||||
isPending: false,
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock('@/api/buster_rest/reports', () => ({
|
||||
useShareReport: () => ({
|
||||
mutateAsync: mockShareReport,
|
||||
isPending: false,
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock('../../../api/buster_rest/users', () => ({
|
||||
useGetUserToOrganization: () => ({
|
||||
data: {
|
||||
data: [
|
||||
{
|
||||
id: '1',
|
||||
name: 'John Doe',
|
||||
email: 'john@example.com',
|
||||
avatarUrl: 'https://example.com/avatar.jpg',
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock('@/context/BusterNotifications', () => ({
|
||||
useBusterNotifications: () => ({
|
||||
openErrorMessage: mockOpenErrorMessage,
|
||||
}),
|
||||
}));
|
||||
|
||||
vi.mock('@/hooks/useDebounce', () => ({
|
||||
useDebounce: (value: string) => value,
|
||||
}));
|
||||
|
||||
vi.mock('@/hooks/useMemoizedFn', () => ({
|
||||
useMemoizedFn: (fn: any) => fn,
|
||||
}));
|
||||
|
||||
vi.mock('@/lib/email', () => ({
|
||||
isValidEmail: (email: string) => email.includes('@') && email.includes('.'),
|
||||
}));
|
||||
|
||||
vi.mock('@/lib/text', () => ({
|
||||
inputHasText: (text: string) => text.length > 0,
|
||||
}));
|
||||
|
||||
// Mock components
|
||||
vi.mock('../../ui/avatar/AvatarUserButton', () => ({
|
||||
AvatarUserButton: ({ username, email }: { username: string; email: string }) => (
|
||||
<div data-testid="avatar-user-button">
|
||||
{username} - {email}
|
||||
</div>
|
||||
),
|
||||
}));
|
||||
|
||||
vi.mock('./AccessDropdown', () => ({
|
||||
AccessDropdown: ({ shareLevel, onChangeShareLevel }: any) => (
|
||||
<div data-testid="access-dropdown">
|
||||
<button onClick={() => onChangeShareLevel('can_edit')} type="button">
|
||||
Change to Edit
|
||||
</button>
|
||||
<span>Current: {shareLevel}</span>
|
||||
</div>
|
||||
),
|
||||
}));
|
||||
|
||||
vi.mock('@/components/ui/inputs/InputSearchDropdown', () => ({
|
||||
InputSearchDropdown: ({ value, onChange, onPressEnter, placeholder }: any) => (
|
||||
<input
|
||||
data-testid="email-input"
|
||||
value={value}
|
||||
onChange={(e) => onChange(e.target.value)}
|
||||
onKeyDown={(e) => e.key === 'Enter' && onPressEnter()}
|
||||
placeholder={placeholder}
|
||||
/>
|
||||
),
|
||||
}));
|
||||
|
||||
vi.mock('@/components/ui/buttons', () => ({
|
||||
Button: ({ children, onClick, disabled, loading }: any) => (
|
||||
<button
|
||||
data-testid="invite-button"
|
||||
onClick={onClick}
|
||||
disabled={disabled}
|
||||
aria-label={loading ? 'Loading' : undefined}
|
||||
type="button"
|
||||
>
|
||||
{children}
|
||||
</button>
|
||||
),
|
||||
}));
|
||||
|
||||
const renderComponent = (props: {
|
||||
assetType: ShareAssetType;
|
||||
assetId: string;
|
||||
individualPermissions: ShareConfig['individual_permissions'];
|
||||
}) => {
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
queries: { retry: false },
|
||||
mutations: { retry: false },
|
||||
},
|
||||
});
|
||||
|
||||
return render(
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<ShareMenuInvite {...props} />
|
||||
</QueryClientProvider>
|
||||
);
|
||||
};
|
||||
|
||||
describe('ShareMenuInvite', () => {
|
||||
const defaultProps = {
|
||||
assetType: 'metric_file' as ShareAssetType,
|
||||
assetId: 'test-asset-id',
|
||||
individualPermissions: [] as ShareConfig['individual_permissions'],
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it('should render email input and invite button', () => {
|
||||
renderComponent(defaultProps);
|
||||
|
||||
expect(screen.getByTestId('email-input')).toBeInTheDocument();
|
||||
expect(screen.getByTestId('invite-button')).toBeInTheDocument();
|
||||
expect(screen.getByPlaceholderText('Invite others by email...')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should disable invite button when email input is empty or invalid', () => {
|
||||
renderComponent(defaultProps);
|
||||
|
||||
const inviteButton = screen.getByTestId('invite-button');
|
||||
expect(inviteButton).toBeDisabled();
|
||||
|
||||
// Type invalid email
|
||||
const emailInput = screen.getByTestId('email-input');
|
||||
fireEvent.change(emailInput, { target: { value: 'invalid-email' } });
|
||||
|
||||
expect(inviteButton).toBeDisabled();
|
||||
});
|
||||
|
||||
it('should enable invite button when valid email is entered', () => {
|
||||
renderComponent(defaultProps);
|
||||
|
||||
const emailInput = screen.getByTestId('email-input');
|
||||
const inviteButton = screen.getByTestId('invite-button');
|
||||
|
||||
fireEvent.change(emailInput, { target: { value: 'test@example.com' } });
|
||||
|
||||
expect(inviteButton).not.toBeDisabled();
|
||||
});
|
||||
|
||||
it('should show access dropdown when email is entered', () => {
|
||||
renderComponent(defaultProps);
|
||||
|
||||
const emailInput = screen.getByTestId('email-input');
|
||||
|
||||
// Initially no access dropdown
|
||||
expect(screen.queryByTestId('access-dropdown')).not.toBeInTheDocument();
|
||||
|
||||
// Type email to show dropdown
|
||||
fireEvent.change(emailInput, { target: { value: 'test@example.com' } });
|
||||
|
||||
expect(screen.getByTestId('access-dropdown')).toBeInTheDocument();
|
||||
expect(screen.getByText('Current: can_view')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('should show error when trying to invite already shared email', () => {
|
||||
const propsWithExistingPermissions = {
|
||||
...defaultProps,
|
||||
individualPermissions: [
|
||||
{
|
||||
email: 'existing@example.com',
|
||||
role: 'can_view' as const,
|
||||
name: 'Existing User',
|
||||
avatar_url: null,
|
||||
},
|
||||
] as ShareConfig['individual_permissions'],
|
||||
};
|
||||
|
||||
renderComponent(propsWithExistingPermissions);
|
||||
|
||||
const emailInput = screen.getByTestId('email-input');
|
||||
const inviteButton = screen.getByTestId('invite-button');
|
||||
|
||||
fireEvent.change(emailInput, { target: { value: 'existing@example.com' } });
|
||||
fireEvent.click(inviteButton);
|
||||
|
||||
expect(mockOpenErrorMessage).toHaveBeenCalledWith('Email already shared');
|
||||
});
|
||||
});
|
|
@ -36,8 +36,10 @@ function RouteComponent() {
|
|||
}
|
||||
|
||||
return (
|
||||
<AppAssetCheckLayout assetType={assetType}>
|
||||
<Outlet />
|
||||
</AppAssetCheckLayout>
|
||||
<main className="h-full w-full bg-page-background overflow-y-auto">
|
||||
<AppAssetCheckLayout assetType={assetType}>
|
||||
<Outlet />
|
||||
</AppAssetCheckLayout>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ pre {
|
|||
|
||||
html,
|
||||
body {
|
||||
background-color: #f3f3f3;
|
||||
background-color: var(--color-background-secondary);
|
||||
min-width: 800px;
|
||||
/* // @media (prefers-color-scheme: dark) {
|
||||
// background-color: #000000;
|
||||
|
|
Loading…
Reference in New Issue