Fix material react table theming
This commit is contained in:
@@ -16,6 +16,7 @@ import Backdrop from 'components/Backdrop';
|
||||
import BangRedirect from 'components/router/BangRedirect';
|
||||
import { createRouterHistory } from 'components/router/routerHistory';
|
||||
import appTheme from 'themes/themes';
|
||||
import { ThemeStorageManager } from 'themes/themeStorageManager';
|
||||
|
||||
const layoutMode = localStorage.getItem('layout');
|
||||
const isExperimentalLayout = layoutMode === 'experimental';
|
||||
@@ -54,8 +55,7 @@ function RootAppLayout() {
|
||||
<ThemeProvider
|
||||
theme={appTheme}
|
||||
defaultMode='dark'
|
||||
// Disable mui's default saving to local storage
|
||||
storageManager={null}
|
||||
storageManager={ThemeStorageManager}
|
||||
>
|
||||
<Backdrop />
|
||||
<AppHeader isHidden={isExperimentalLayout || isNewLayoutPath} />
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import Box from '@mui/material/Box/Box';
|
||||
import Stack from '@mui/material/Stack/Stack';
|
||||
import type {} from '@mui/material/themeCssVarsAugmentation';
|
||||
import Typography from '@mui/material/Typography/Typography';
|
||||
import { type MRT_RowData, type MRT_TableInstance, MaterialReactTable } from 'material-react-table';
|
||||
import { type MRT_RowData, type MRT_TableInstance, type MRT_TableOptions, MaterialReactTable } from 'material-react-table';
|
||||
import React from 'react';
|
||||
|
||||
import Page, { type PageProps } from 'components/Page';
|
||||
@@ -12,7 +13,7 @@ interface TablePageProps<T extends MRT_RowData> extends PageProps {
|
||||
table: MRT_TableInstance<T>
|
||||
}
|
||||
|
||||
export const DEFAULT_TABLE_OPTIONS = {
|
||||
export const DEFAULT_TABLE_OPTIONS: Partial<MRT_TableOptions<MRT_RowData>> = {
|
||||
// Enable custom features
|
||||
enableColumnPinning: true,
|
||||
enableColumnResizing: true,
|
||||
|
||||
@@ -2,9 +2,10 @@ import parseISO from 'date-fns/parseISO';
|
||||
import React, { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import type { ActivityLogEntry } from '@jellyfin/sdk/lib/generated-client/models/activity-log-entry';
|
||||
import { LogLevel } from '@jellyfin/sdk/lib/generated-client/models/log-level';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import ToggleButton from '@mui/material/ToggleButton';
|
||||
import ToggleButtonGroup from '@mui/material/ToggleButtonGroup';
|
||||
import { type MRT_ColumnDef, useMaterialReactTable } from 'material-react-table';
|
||||
import { type MRT_ColumnDef, type MRT_Theme, useMaterialReactTable } from 'material-react-table';
|
||||
import { useSearchParams } from 'react-router-dom';
|
||||
|
||||
import DateTimeCell from 'apps/dashboard/components/table/DateTimeCell';
|
||||
@@ -53,6 +54,8 @@ export const Component = () => {
|
||||
|
||||
const { usersById: users, names: userNames, isLoading: isUsersLoading } = useUsersDetails();
|
||||
|
||||
const theme = useTheme();
|
||||
|
||||
const UserCell = getUserCell(users);
|
||||
|
||||
const activityParams = useMemo(() => ({
|
||||
@@ -156,8 +159,15 @@ export const Component = () => {
|
||||
}
|
||||
}, [ activityView, searchParams, setSearchParams ]);
|
||||
|
||||
// NOTE: We need to provide a custom theme due to a MRT bug causing the initial theme to always be used
|
||||
// https://github.com/KevinVandy/material-react-table/issues/1429
|
||||
const mrtTheme = useMemo<Partial<MRT_Theme>>(() => ({
|
||||
baseBackgroundColor: theme.palette.background.paper
|
||||
}), [ theme ]);
|
||||
|
||||
const table = useMaterialReactTable({
|
||||
...DEFAULT_TABLE_OPTIONS,
|
||||
mrtTheme,
|
||||
|
||||
columns,
|
||||
data: logEntries,
|
||||
|
||||
@@ -6,7 +6,7 @@ import Button from '@mui/material/Button/Button';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import Tooltip from '@mui/material/Tooltip/Tooltip';
|
||||
import parseISO from 'date-fns/parseISO';
|
||||
import { type MRT_ColumnDef, useMaterialReactTable } from 'material-react-table';
|
||||
import { type MRT_ColumnDef, type MRT_Theme, useMaterialReactTable } from 'material-react-table';
|
||||
import React, { useCallback, useMemo, useState } from 'react';
|
||||
|
||||
import DateTimeCell from 'apps/dashboard/components/table/DateTimeCell';
|
||||
@@ -21,6 +21,8 @@ import ConfirmDialog from 'components/ConfirmDialog';
|
||||
import { useApi } from 'hooks/useApi';
|
||||
import { type UsersRecords, useUsersDetails } from 'hooks/useUsers';
|
||||
import globalize from 'lib/globalize';
|
||||
import { COLOR_SCHEMES } from 'themes/themes';
|
||||
import { useColorScheme, useTheme } from '@mui/material';
|
||||
|
||||
const getUserCell = (users: UsersRecords) => function UserCell({ renderedCellValue, row }: DeviceInfoCell) {
|
||||
return (
|
||||
@@ -41,6 +43,8 @@ export const Component = () => {
|
||||
data?.Items || []
|
||||
), [ data ]);
|
||||
const { usersById: users, names: userNames, isLoading: isUsersLoading } = useUsersDetails();
|
||||
const { colorScheme } = useColorScheme();
|
||||
const theme = useTheme();
|
||||
|
||||
const [ isDeleteConfirmOpen, setIsDeleteConfirmOpen ] = useState(false);
|
||||
const [ isDeleteAllConfirmOpen, setIsDeleteAllConfirmOpen ] = useState(false);
|
||||
@@ -137,8 +141,13 @@ export const Component = () => {
|
||||
}
|
||||
], [ UserCell, userNames ]);
|
||||
|
||||
const mrtTheme = useMemo<Partial<MRT_Theme>>(() => ({
|
||||
baseBackgroundColor: theme.palette.background.paper
|
||||
}), [ theme ]);
|
||||
|
||||
const mrTable = useMaterialReactTable({
|
||||
...DEFAULT_TABLE_OPTIONS,
|
||||
mrtTheme,
|
||||
|
||||
columns,
|
||||
data: devices,
|
||||
@@ -190,10 +199,18 @@ export const Component = () => {
|
||||
renderRowActions: ({ row, table }) => {
|
||||
const isDeletable = api && row.original.Id && api.deviceInfo.id === row.original.Id;
|
||||
return (
|
||||
<Box sx={{ display: 'flex', gap: 1 }}>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
gap: 1,
|
||||
'&&': {
|
||||
backgroundColor: 'transparent !important'
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Tooltip title={globalize.translate('Edit')}>
|
||||
<IconButton
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
// eslint-disable-next-line react/jsx-no-bind
|
||||
onClick={() => table.setEditingRow(row)}
|
||||
>
|
||||
<Edit />
|
||||
|
||||
@@ -2,11 +2,12 @@ import type { AuthenticationInfo } from '@jellyfin/sdk/lib/generated-client/mode
|
||||
import Box from '@mui/material/Box';
|
||||
import Button from '@mui/material/Button';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import Tooltip from '@mui/material/Tooltip';
|
||||
import AddIcon from '@mui/icons-material/Add';
|
||||
import DeleteIcon from '@mui/icons-material/Delete';
|
||||
import parseISO from 'date-fns/parseISO';
|
||||
import { type MRT_ColumnDef, useMaterialReactTable } from 'material-react-table';
|
||||
import { type MRT_ColumnDef, type MRT_Theme, useMaterialReactTable } from 'material-react-table';
|
||||
import React, { useCallback, useMemo } from 'react';
|
||||
|
||||
import DateTimeCell from 'apps/dashboard/components/table/DateTimeCell';
|
||||
@@ -27,6 +28,7 @@ export const Component = () => {
|
||||
), [ data ]);
|
||||
const revokeKey = useRevokeKey();
|
||||
const createKey = useCreateKey();
|
||||
const theme = useTheme();
|
||||
|
||||
const columns = useMemo<MRT_ColumnDef<AuthenticationInfo>[]>(() => [
|
||||
{
|
||||
@@ -49,8 +51,15 @@ export const Component = () => {
|
||||
}
|
||||
], []);
|
||||
|
||||
// NOTE: We need to provide a custom theme due to a MRT bug causing the initial theme to always be used
|
||||
// https://github.com/KevinVandy/material-react-table/issues/1429
|
||||
const mrtTheme = useMemo<Partial<MRT_Theme>>(() => ({
|
||||
baseBackgroundColor: theme.palette.background.paper
|
||||
}), [ theme ]);
|
||||
|
||||
const table = useMaterialReactTable({
|
||||
...DEFAULT_TABLE_OPTIONS,
|
||||
mrtTheme,
|
||||
|
||||
columns,
|
||||
data: keys,
|
||||
|
||||
@@ -7,10 +7,11 @@ import Stack from '@mui/material/Stack';
|
||||
import Typography from '@mui/material/Typography';
|
||||
import AddIcon from '@mui/icons-material/Add';
|
||||
import IconButton from '@mui/material/IconButton';
|
||||
import { useTheme } from '@mui/material/styles';
|
||||
import Tooltip from '@mui/material/Tooltip';
|
||||
import RemoveCircleIcon from '@mui/icons-material/RemoveCircle';
|
||||
import Loading from 'components/loading/LoadingComponent';
|
||||
import { MRT_ColumnDef, MRT_Table, useMaterialReactTable } from 'material-react-table';
|
||||
import { type MRT_ColumnDef, MRT_Table, type MRT_Theme, useMaterialReactTable } from 'material-react-table';
|
||||
import type { TaskTriggerInfo } from '@jellyfin/sdk/lib/generated-client/models/task-trigger-info';
|
||||
import globalize from '../../../../lib/globalize';
|
||||
import { useTask } from 'apps/dashboard/features/tasks/api/useTask';
|
||||
@@ -26,6 +27,7 @@ export const Component = () => {
|
||||
const [ isAddTriggerDialogOpen, setIsAddTriggerDialogOpen ] = useState(false);
|
||||
const [ isRemoveConfirmOpen, setIsRemoveConfirmOpen ] = useState(false);
|
||||
const [ pendingDeleteTrigger, setPendingDeleteTrigger ] = useState<TaskTriggerInfo | null>(null);
|
||||
const theme = useTheme();
|
||||
|
||||
const onCloseRemoveConfirmDialog = useCallback(() => {
|
||||
setPendingDeleteTrigger(null);
|
||||
@@ -80,7 +82,15 @@ export const Component = () => {
|
||||
}
|
||||
], []);
|
||||
|
||||
// NOTE: We need to provide a custom theme due to a MRT bug causing the initial theme to always be used
|
||||
// https://github.com/KevinVandy/material-react-table/issues/1429
|
||||
const mrtTheme = useMemo<Partial<MRT_Theme>>(() => ({
|
||||
baseBackgroundColor: theme.palette.background.paper
|
||||
}), [ theme ]);
|
||||
|
||||
const table = useMaterialReactTable({
|
||||
mrtTheme,
|
||||
|
||||
columns,
|
||||
data: task?.Triggers || [],
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import Events from 'utils/events';
|
||||
import { EventType } from 'types/eventType';
|
||||
|
||||
import { getDefaultTheme, getThemes as getConfiguredThemes } from './settings/webSettings';
|
||||
|
||||
let currentThemeId;
|
||||
@@ -44,6 +47,8 @@ function setTheme(id) {
|
||||
|
||||
// set the meta theme color
|
||||
document.getElementById('themeColor').content = info.color;
|
||||
|
||||
Events.trigger(document, EventType.THEME_CHANGE, [ info.id ]);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
21
src/themes/themeStorageManager.ts
Normal file
21
src/themes/themeStorageManager.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { StorageManager } from '@mui/material/styles';
|
||||
|
||||
import Events, { type Event } from 'utils/events';
|
||||
import { EventType } from 'types/eventType';
|
||||
|
||||
/**
|
||||
* A custom MUI StorageManager.
|
||||
*
|
||||
* Since we switch the theme based on the current page, we handle getting/setting the current theme via autoTheme +
|
||||
* themeManager. We need to implement `subscribe` so MUI is aware of theme changes though otherwise the `useTheme` hook
|
||||
* will always return the default theme.
|
||||
*/
|
||||
export const ThemeStorageManager: StorageManager = () => ({
|
||||
get: defaultValue => defaultValue,
|
||||
set: () => { /* no-op */ },
|
||||
subscribe: handler => {
|
||||
const wrappedHandler = (_e: Event, value: string) => handler(value);
|
||||
Events.on(document, EventType.THEME_CHANGE, wrappedHandler);
|
||||
return () => Events.off(document, EventType.THEME_CHANGE, wrappedHandler);
|
||||
}
|
||||
});
|
||||
@@ -4,5 +4,6 @@
|
||||
export enum EventType {
|
||||
HEADER_RENDERED = 'HEADER_RENDERED',
|
||||
SET_TABS = 'SET_TABS',
|
||||
SHOW_VIDEO_OSD = 'SHOW_VIDEO_OSD'
|
||||
SHOW_VIDEO_OSD = 'SHOW_VIDEO_OSD',
|
||||
THEME_CHANGE = 'THEME_CHANGE'
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user