mirror of
https://github.com/strapi/strapi.git
synced 2025-11-02 02:44:55 +00:00
Merge pull request #12651 from strapi/dark-mode/admin-setup
Dark mode admin setup
This commit is contained in:
commit
e6ce78a5e1
@ -45,6 +45,7 @@ module.exports = {
|
||||
'<rootDir>/packages/admin-test-utils/lib/mocks/LocalStorageMock.js',
|
||||
'<rootDir>/packages/admin-test-utils/lib/mocks/IntersectionObserver.js',
|
||||
'<rootDir>/packages/admin-test-utils/lib/mocks/ResizeObserver.js',
|
||||
'<rootDir>/packages/admin-test-utils/lib/mocks/windowMatchMedia.js',
|
||||
],
|
||||
setupFilesAfterEnv: [
|
||||
'<rootDir>/packages/admin-test-utils/lib/setup/enzyme-setup.js',
|
||||
|
||||
3
packages/admin-test-utils/lib/mocks/windowMatchMedia.js
Normal file
3
packages/admin-test-utils/lib/mocks/windowMatchMedia.js
Normal file
@ -0,0 +1,3 @@
|
||||
'use strict';
|
||||
|
||||
global.window.matchMedia = jest.fn(() => false);
|
||||
@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import { BrowserRouter } from 'react-router-dom';
|
||||
import { lightTheme } from '@strapi/design-system/themes';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import merge from 'lodash/merge';
|
||||
import pick from 'lodash/pick';
|
||||
import isFunction from 'lodash/isFunction';
|
||||
@ -13,7 +14,6 @@ import App from './pages/App';
|
||||
import AuthLogo from './assets/images/logo_strapi_auth_v4.png';
|
||||
import MenuLogo from './assets/images/logo_strapi_menu.png';
|
||||
import Providers from './components/Providers';
|
||||
import Theme from './components/Theme';
|
||||
import languageNativeNames from './translations/languageNativeNames';
|
||||
import {
|
||||
INJECT_COLUMN_IN_TABLE,
|
||||
@ -22,6 +22,7 @@ import {
|
||||
MUTATE_SINGLE_TYPES_LINKS,
|
||||
} from './exposedHooks';
|
||||
import injectionZones from './injectionZones';
|
||||
import darkTheme from './temp-dark-theme';
|
||||
import favicon from './favicon.ico';
|
||||
|
||||
class StrapiApp {
|
||||
@ -34,7 +35,7 @@ class StrapiApp {
|
||||
locales: ['en'],
|
||||
menuLogo: MenuLogo,
|
||||
notifications: { releases: true },
|
||||
theme: lightTheme,
|
||||
themes: { light: lightTheme, dark: darkTheme, custom: null },
|
||||
translations: {},
|
||||
tutorials: true,
|
||||
};
|
||||
@ -226,7 +227,10 @@ class StrapiApp {
|
||||
}
|
||||
|
||||
if (this.customConfigurations?.theme) {
|
||||
this.configurations.theme = merge(this.configurations.theme, this.customConfigurations.theme);
|
||||
this.configurations.themes.custom = merge(
|
||||
cloneDeep(this.configurations.themes.light),
|
||||
this.customConfigurations.theme
|
||||
);
|
||||
}
|
||||
|
||||
if (this.customConfigurations?.notifications?.releases !== undefined) {
|
||||
@ -427,44 +431,43 @@ class StrapiApp {
|
||||
} = this.library;
|
||||
|
||||
return (
|
||||
<Theme theme={this.configurations.theme}>
|
||||
<Providers
|
||||
authLogo={this.configurations.authLogo}
|
||||
components={components}
|
||||
fields={fields}
|
||||
localeNames={localeNames}
|
||||
getAdminInjectedComponents={this.getAdminInjectedComponents}
|
||||
getPlugin={this.getPlugin}
|
||||
messages={this.configurations.translations}
|
||||
menu={this.menu}
|
||||
menuLogo={this.configurations.menuLogo}
|
||||
plugins={this.plugins}
|
||||
runHookParallel={this.runHookParallel}
|
||||
runHookWaterfall={(name, initialValue, async = false) => {
|
||||
return this.runHookWaterfall(name, initialValue, async, store);
|
||||
}}
|
||||
runHookSeries={this.runHookSeries}
|
||||
settings={this.settings}
|
||||
showTutorials={this.configurations.tutorials}
|
||||
showReleaseNotification={this.configurations.notifications.releases}
|
||||
store={store}
|
||||
>
|
||||
<>
|
||||
<Helmet
|
||||
link={[
|
||||
{
|
||||
rel: 'icon',
|
||||
type: 'image/png',
|
||||
href: this.configurations.head.favicon,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<BrowserRouter basename={basename}>
|
||||
<App store={store} />
|
||||
</BrowserRouter>
|
||||
</>
|
||||
</Providers>
|
||||
</Theme>
|
||||
<Providers
|
||||
authLogo={this.configurations.authLogo}
|
||||
components={components}
|
||||
fields={fields}
|
||||
localeNames={localeNames}
|
||||
getAdminInjectedComponents={this.getAdminInjectedComponents}
|
||||
getPlugin={this.getPlugin}
|
||||
messages={this.configurations.translations}
|
||||
menu={this.menu}
|
||||
menuLogo={this.configurations.menuLogo}
|
||||
plugins={this.plugins}
|
||||
runHookParallel={this.runHookParallel}
|
||||
runHookWaterfall={(name, initialValue, async = false) => {
|
||||
return this.runHookWaterfall(name, initialValue, async, store);
|
||||
}}
|
||||
runHookSeries={this.runHookSeries}
|
||||
themes={this.configurations.themes}
|
||||
settings={this.settings}
|
||||
showTutorials={this.configurations.tutorials}
|
||||
showReleaseNotification={this.configurations.notifications.releases}
|
||||
store={store}
|
||||
>
|
||||
<>
|
||||
<Helmet
|
||||
link={[
|
||||
{
|
||||
rel: 'icon',
|
||||
type: 'image/png',
|
||||
href: this.configurations.head.favicon,
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<BrowserRouter basename={basename}>
|
||||
<App store={store} />
|
||||
</BrowserRouter>
|
||||
</>
|
||||
</Providers>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ import React from 'react';
|
||||
import { render, waitFor } from '@testing-library/react';
|
||||
import { QueryClientProvider, QueryClient } from 'react-query';
|
||||
import { useGuidedTour } from '@strapi/helper-plugin';
|
||||
import { lightTheme } from '@strapi/design-system';
|
||||
import { ConfigurationsContext } from '../../../contexts';
|
||||
import {
|
||||
fetchAppInfo,
|
||||
@ -11,6 +12,7 @@ import {
|
||||
} from '../utils/api';
|
||||
import packageJSON from '../../../../../package.json';
|
||||
import Theme from '../../Theme';
|
||||
import ThemeToggleProvider from '../../ThemeToggleProvider';
|
||||
import AuthenticatedApp from '..';
|
||||
|
||||
const strapiVersion = packageJSON.version;
|
||||
@ -43,13 +45,15 @@ const queryClient = new QueryClient({
|
||||
});
|
||||
|
||||
const app = (
|
||||
<Theme>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<ConfigurationsContext.Provider value={{ showReleaseNotification: false }}>
|
||||
<AuthenticatedApp />
|
||||
</ConfigurationsContext.Provider>
|
||||
</QueryClientProvider>
|
||||
</Theme>
|
||||
<ThemeToggleProvider themes={{ light: lightTheme }}>
|
||||
<Theme>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<ConfigurationsContext.Provider value={{ showReleaseNotification: false }}>
|
||||
<AuthenticatedApp />
|
||||
</ConfigurationsContext.Provider>
|
||||
</QueryClientProvider>
|
||||
</Theme>
|
||||
</ThemeToggleProvider>
|
||||
);
|
||||
|
||||
describe('Admin | components | AuthenticatedApp', () => {
|
||||
|
||||
@ -15,6 +15,9 @@ const GlobalStyle = createGlobalStyle`
|
||||
body {
|
||||
background: ${({ theme }) => theme.colors.neutral100};
|
||||
}
|
||||
input, textarea {
|
||||
background-color: inherit;
|
||||
}
|
||||
`;
|
||||
|
||||
export default GlobalStyle;
|
||||
|
||||
@ -2,7 +2,9 @@ import React from 'react';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
import { useGuidedTour } from '@strapi/helper-plugin';
|
||||
import { lightTheme } from '@strapi/design-system';
|
||||
import Theme from '../../../Theme';
|
||||
import ThemeToggleProvider from '../../../ThemeToggleProvider';
|
||||
import GuidedTourModal from '../index';
|
||||
|
||||
jest.mock('@strapi/helper-plugin', () => ({
|
||||
@ -28,11 +30,13 @@ jest.mock('@strapi/helper-plugin', () => ({
|
||||
}));
|
||||
|
||||
const App = (
|
||||
<Theme>
|
||||
<IntlProvider locale="en" messages={{}} defaultLocale="en" textComponent="span">
|
||||
<GuidedTourModal />
|
||||
</IntlProvider>
|
||||
</Theme>
|
||||
<ThemeToggleProvider themes={{ light: lightTheme }}>
|
||||
<Theme>
|
||||
<IntlProvider locale="en" messages={{}} defaultLocale="en" textComponent="span">
|
||||
<GuidedTourModal />
|
||||
</IntlProvider>
|
||||
</Theme>
|
||||
</ThemeToggleProvider>
|
||||
);
|
||||
|
||||
describe('<GuidedTourModal />', () => {
|
||||
|
||||
@ -9,7 +9,9 @@ import { render, fireEvent, screen } from '@testing-library/react';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
import { useNotification } from '@strapi/helper-plugin';
|
||||
import { act } from 'react-dom/test-utils';
|
||||
import { lightTheme } from '@strapi/design-system';
|
||||
import Theme from '../../Theme';
|
||||
import ThemeToggleProvider from '../../ThemeToggleProvider';
|
||||
import Notifications from '../index';
|
||||
|
||||
const messages = {};
|
||||
@ -19,13 +21,15 @@ describe('<Notifications />', () => {
|
||||
const {
|
||||
container: { firstChild },
|
||||
} = render(
|
||||
<Theme>
|
||||
<IntlProvider locale="en" messages={messages} defaultLocale="en" textComponent="span">
|
||||
<Notifications>
|
||||
<div />
|
||||
</Notifications>
|
||||
</IntlProvider>
|
||||
</Theme>
|
||||
<ThemeToggleProvider themes={{ light: lightTheme }}>
|
||||
<Theme>
|
||||
<IntlProvider locale="en" messages={messages} defaultLocale="en" textComponent="span">
|
||||
<Notifications>
|
||||
<div />
|
||||
</Notifications>
|
||||
</IntlProvider>
|
||||
</Theme>
|
||||
</ThemeToggleProvider>
|
||||
);
|
||||
|
||||
expect(firstChild).toMatchInlineSnapshot(`
|
||||
@ -80,13 +84,15 @@ describe('<Notifications />', () => {
|
||||
};
|
||||
|
||||
render(
|
||||
<Theme>
|
||||
<IntlProvider locale="en" defaultLocale="en" messages={messages} textComponent="span">
|
||||
<Notifications>
|
||||
<Button />
|
||||
</Notifications>
|
||||
</IntlProvider>
|
||||
</Theme>
|
||||
<ThemeToggleProvider themes={{ light: lightTheme }}>
|
||||
<Theme>
|
||||
<IntlProvider locale="en" defaultLocale="en" messages={messages} textComponent="span">
|
||||
<Notifications>
|
||||
<Button />
|
||||
</Notifications>
|
||||
</IntlProvider>
|
||||
</Theme>
|
||||
</ThemeToggleProvider>
|
||||
);
|
||||
|
||||
// Click button
|
||||
@ -121,13 +127,15 @@ describe('<Notifications />', () => {
|
||||
};
|
||||
|
||||
render(
|
||||
<Theme>
|
||||
<IntlProvider locale="en" defaultLocale="en" messages={messages} textComponent="span">
|
||||
<Notifications>
|
||||
<Button />
|
||||
</Notifications>
|
||||
</IntlProvider>
|
||||
</Theme>
|
||||
<ThemeToggleProvider themes={{ light: lightTheme }}>
|
||||
<Theme>
|
||||
<IntlProvider locale="en" defaultLocale="en" messages={messages} textComponent="span">
|
||||
<Notifications>
|
||||
<Button />
|
||||
</Notifications>
|
||||
</IntlProvider>
|
||||
</Theme>
|
||||
</ThemeToggleProvider>
|
||||
);
|
||||
|
||||
// Click button
|
||||
|
||||
@ -9,6 +9,8 @@ import GuidedTour from '../GuidedTour';
|
||||
import AutoReloadOverlayBlockerProvider from '../AutoReloadOverlayBlockerProvider';
|
||||
import Notifications from '../Notifications';
|
||||
import OverlayBlocker from '../OverlayBlocker';
|
||||
import ThemeToggleProvider from '../ThemeToggleProvider';
|
||||
import Theme from '../Theme';
|
||||
|
||||
const queryClient = new QueryClient({
|
||||
defaultOptions: {
|
||||
@ -36,41 +38,45 @@ const Providers = ({
|
||||
settings,
|
||||
showReleaseNotification,
|
||||
showTutorials,
|
||||
|
||||
store,
|
||||
themes,
|
||||
}) => {
|
||||
return (
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<Provider store={store}>
|
||||
<AdminContext.Provider value={{ getAdminInjectedComponents }}>
|
||||
<ConfigurationsContext.Provider
|
||||
value={{ authLogo, menuLogo, showReleaseNotification, showTutorials }}
|
||||
>
|
||||
<StrapiAppProvider
|
||||
getPlugin={getPlugin}
|
||||
menu={menu}
|
||||
plugins={plugins}
|
||||
runHookParallel={runHookParallel}
|
||||
runHookWaterfall={runHookWaterfall}
|
||||
runHookSeries={runHookSeries}
|
||||
settings={settings}
|
||||
>
|
||||
<LibraryProvider components={components} fields={fields}>
|
||||
<LanguageProvider messages={messages} localeNames={localeNames}>
|
||||
<AutoReloadOverlayBlockerProvider>
|
||||
<OverlayBlocker>
|
||||
<GuidedTour>
|
||||
<Notifications>{children}</Notifications>
|
||||
</GuidedTour>
|
||||
</OverlayBlocker>
|
||||
</AutoReloadOverlayBlockerProvider>
|
||||
</LanguageProvider>
|
||||
</LibraryProvider>
|
||||
</StrapiAppProvider>
|
||||
</ConfigurationsContext.Provider>
|
||||
</AdminContext.Provider>
|
||||
</Provider>
|
||||
</QueryClientProvider>
|
||||
<ThemeToggleProvider themes={themes}>
|
||||
<Theme>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<Provider store={store}>
|
||||
<AdminContext.Provider value={{ getAdminInjectedComponents }}>
|
||||
<ConfigurationsContext.Provider
|
||||
value={{ authLogo, menuLogo, showReleaseNotification, showTutorials }}
|
||||
>
|
||||
<StrapiAppProvider
|
||||
getPlugin={getPlugin}
|
||||
menu={menu}
|
||||
plugins={plugins}
|
||||
runHookParallel={runHookParallel}
|
||||
runHookWaterfall={runHookWaterfall}
|
||||
runHookSeries={runHookSeries}
|
||||
settings={settings}
|
||||
>
|
||||
<LibraryProvider components={components} fields={fields}>
|
||||
<LanguageProvider messages={messages} localeNames={localeNames}>
|
||||
<AutoReloadOverlayBlockerProvider>
|
||||
<OverlayBlocker>
|
||||
<GuidedTour>
|
||||
<Notifications>{children}</Notifications>
|
||||
</GuidedTour>
|
||||
</OverlayBlocker>
|
||||
</AutoReloadOverlayBlockerProvider>
|
||||
</LanguageProvider>
|
||||
</LibraryProvider>
|
||||
</StrapiAppProvider>
|
||||
</ConfigurationsContext.Provider>
|
||||
</AdminContext.Provider>
|
||||
</Provider>
|
||||
</QueryClientProvider>
|
||||
</Theme>
|
||||
</ThemeToggleProvider>
|
||||
);
|
||||
};
|
||||
|
||||
@ -104,6 +110,33 @@ Providers.propTypes = {
|
||||
showReleaseNotification: PropTypes.bool.isRequired,
|
||||
showTutorials: PropTypes.bool.isRequired,
|
||||
store: PropTypes.object.isRequired,
|
||||
themes: PropTypes.shape({
|
||||
light: PropTypes.shape({
|
||||
colors: PropTypes.object.isRequired,
|
||||
shadows: PropTypes.object.isRequired,
|
||||
sizes: PropTypes.object.isRequired,
|
||||
zIndices: PropTypes.array.isRequired,
|
||||
spaces: PropTypes.array.isRequired,
|
||||
borderRadius: PropTypes.string.isRequired,
|
||||
mediaQueries: PropTypes.object.isRequired,
|
||||
fontSizes: PropTypes.array.isRequired,
|
||||
lineHeights: PropTypes.array.isRequired,
|
||||
fontWeights: PropTypes.object.isRequired,
|
||||
}).isRequired,
|
||||
dark: PropTypes.shape({
|
||||
colors: PropTypes.object.isRequired,
|
||||
shadows: PropTypes.object.isRequired,
|
||||
sizes: PropTypes.object.isRequired,
|
||||
zIndices: PropTypes.array.isRequired,
|
||||
spaces: PropTypes.array.isRequired,
|
||||
borderRadius: PropTypes.string.isRequired,
|
||||
mediaQueries: PropTypes.object.isRequired,
|
||||
fontSizes: PropTypes.array.isRequired,
|
||||
lineHeights: PropTypes.array.isRequired,
|
||||
fontWeights: PropTypes.object.isRequired,
|
||||
}).isRequired,
|
||||
custom: PropTypes.object,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
export default Providers;
|
||||
|
||||
@ -1,23 +1,22 @@
|
||||
import React from 'react';
|
||||
import { ThemeProvider } from '@strapi/design-system/ThemeProvider';
|
||||
import PropTypes from 'prop-types';
|
||||
import { lightTheme } from '@strapi/design-system/themes';
|
||||
import { useThemeToggle } from '../../hooks';
|
||||
import GlobalStyle from '../GlobalStyle';
|
||||
|
||||
const Theme = ({ children, theme }) => (
|
||||
<ThemeProvider theme={theme}>
|
||||
{children}
|
||||
<GlobalStyle />
|
||||
</ThemeProvider>
|
||||
);
|
||||
const Theme = ({ children }) => {
|
||||
const { currentTheme, themes } = useThemeToggle();
|
||||
|
||||
return (
|
||||
<ThemeProvider theme={themes[currentTheme] || themes.light}>
|
||||
{children}
|
||||
<GlobalStyle />
|
||||
</ThemeProvider>
|
||||
);
|
||||
};
|
||||
|
||||
Theme.propTypes = {
|
||||
children: PropTypes.element.isRequired,
|
||||
theme: PropTypes.object,
|
||||
};
|
||||
|
||||
Theme.defaultProps = {
|
||||
theme: lightTheme,
|
||||
};
|
||||
|
||||
export default Theme;
|
||||
|
||||
@ -0,0 +1,66 @@
|
||||
/**
|
||||
*
|
||||
* ThemeToggleProvider
|
||||
*
|
||||
*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { ThemeToggleContext } from '../../contexts';
|
||||
|
||||
const THEME_KEY = 'STRAPI_THEME';
|
||||
|
||||
const getDefaultTheme = () => {
|
||||
const browserTheme = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
||||
const persistedTheme = localStorage.getItem(THEME_KEY);
|
||||
|
||||
return persistedTheme || browserTheme;
|
||||
};
|
||||
|
||||
const ThemeToggleProvider = ({ children, themes }) => {
|
||||
const [currentTheme, setCurrentTheme] = useState(getDefaultTheme());
|
||||
|
||||
const handleChangeTheme = nextTheme => {
|
||||
setCurrentTheme(nextTheme);
|
||||
localStorage.setItem(THEME_KEY, nextTheme);
|
||||
};
|
||||
|
||||
return (
|
||||
<ThemeToggleContext.Provider value={{ currentTheme, onChangeTheme: handleChangeTheme, themes }}>
|
||||
{children}
|
||||
</ThemeToggleContext.Provider>
|
||||
);
|
||||
};
|
||||
|
||||
ThemeToggleProvider.propTypes = {
|
||||
children: PropTypes.node.isRequired,
|
||||
themes: PropTypes.shape({
|
||||
light: PropTypes.shape({
|
||||
colors: PropTypes.object.isRequired,
|
||||
shadows: PropTypes.object.isRequired,
|
||||
sizes: PropTypes.object.isRequired,
|
||||
zIndices: PropTypes.array.isRequired,
|
||||
spaces: PropTypes.array.isRequired,
|
||||
borderRadius: PropTypes.string.isRequired,
|
||||
mediaQueries: PropTypes.object.isRequired,
|
||||
fontSizes: PropTypes.array.isRequired,
|
||||
lineHeights: PropTypes.array.isRequired,
|
||||
fontWeights: PropTypes.object.isRequired,
|
||||
}).isRequired,
|
||||
dark: PropTypes.shape({
|
||||
colors: PropTypes.object.isRequired,
|
||||
shadows: PropTypes.object.isRequired,
|
||||
sizes: PropTypes.object.isRequired,
|
||||
zIndices: PropTypes.array.isRequired,
|
||||
spaces: PropTypes.array.isRequired,
|
||||
borderRadius: PropTypes.string.isRequired,
|
||||
mediaQueries: PropTypes.object.isRequired,
|
||||
fontSizes: PropTypes.array.isRequired,
|
||||
lineHeights: PropTypes.array.isRequired,
|
||||
fontWeights: PropTypes.object.isRequired,
|
||||
}).isRequired,
|
||||
custom: PropTypes.object,
|
||||
}).isRequired,
|
||||
};
|
||||
|
||||
export default ThemeToggleProvider;
|
||||
@ -8,7 +8,9 @@ import { DndProvider } from 'react-dnd';
|
||||
import { HTML5Backend } from 'react-dnd-html5-backend';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
import { lightTheme } from '@strapi/design-system';
|
||||
import Theme from '../../../../components/Theme';
|
||||
import ThemeToggleProvider from '../../../../components/ThemeToggleProvider';
|
||||
import { App as ContentManagerApp } from '..';
|
||||
import cmReducers from '../../../../reducers';
|
||||
import useModels from '../useModels';
|
||||
@ -96,15 +98,17 @@ describe('Content manager | App | main', () => {
|
||||
|
||||
const { container } = render(
|
||||
<IntlProvider messages={{}} defaultLocale="en" locale="en">
|
||||
<Theme>
|
||||
<DndProvider backend={HTML5Backend}>
|
||||
<Provider store={store}>
|
||||
<Router history={history}>
|
||||
<ContentManagerApp />
|
||||
</Router>
|
||||
</Provider>
|
||||
</DndProvider>
|
||||
</Theme>
|
||||
<ThemeToggleProvider themes={{ light: lightTheme }}>
|
||||
<Theme>
|
||||
<DndProvider backend={HTML5Backend}>
|
||||
<Provider store={store}>
|
||||
<Router history={history}>
|
||||
<ContentManagerApp />
|
||||
</Router>
|
||||
</Provider>
|
||||
</DndProvider>
|
||||
</Theme>
|
||||
</ThemeToggleProvider>
|
||||
</IntlProvider>
|
||||
);
|
||||
|
||||
@ -795,15 +799,17 @@ describe('Content manager | App | main', () => {
|
||||
|
||||
render(
|
||||
<IntlProvider messages={{}} defaultLocale="en" locale="en">
|
||||
<Theme>
|
||||
<DndProvider backend={HTML5Backend}>
|
||||
<Provider store={store}>
|
||||
<Router history={history}>
|
||||
<ContentManagerApp />
|
||||
</Router>
|
||||
</Provider>
|
||||
</DndProvider>
|
||||
</Theme>
|
||||
<ThemeToggleProvider themes={{ light: lightTheme }}>
|
||||
<Theme>
|
||||
<DndProvider backend={HTML5Backend}>
|
||||
<Provider store={store}>
|
||||
<Router history={history}>
|
||||
<ContentManagerApp />
|
||||
</Router>
|
||||
</Provider>
|
||||
</DndProvider>
|
||||
</Theme>
|
||||
</ThemeToggleProvider>
|
||||
</IntlProvider>
|
||||
);
|
||||
|
||||
@ -839,15 +845,17 @@ describe('Content manager | App | main', () => {
|
||||
|
||||
render(
|
||||
<IntlProvider messages={{}} defaultLocale="en" locale="en">
|
||||
<Theme>
|
||||
<DndProvider backend={HTML5Backend}>
|
||||
<Provider store={store}>
|
||||
<Router history={history}>
|
||||
<ContentManagerApp />
|
||||
</Router>
|
||||
</Provider>
|
||||
</DndProvider>
|
||||
</Theme>
|
||||
<ThemeToggleProvider themes={{ light: lightTheme }}>
|
||||
<Theme>
|
||||
<DndProvider backend={HTML5Backend}>
|
||||
<Provider store={store}>
|
||||
<Router history={history}>
|
||||
<ContentManagerApp />
|
||||
</Router>
|
||||
</Provider>
|
||||
</DndProvider>
|
||||
</Theme>
|
||||
</ThemeToggleProvider>
|
||||
</IntlProvider>
|
||||
);
|
||||
|
||||
@ -882,15 +890,17 @@ describe('Content manager | App | main', () => {
|
||||
|
||||
render(
|
||||
<IntlProvider messages={{}} defaultLocale="en" locale="en">
|
||||
<Theme>
|
||||
<DndProvider backend={HTML5Backend}>
|
||||
<Provider store={store}>
|
||||
<Router history={history}>
|
||||
<ContentManagerApp />
|
||||
</Router>
|
||||
</Provider>
|
||||
</DndProvider>
|
||||
</Theme>
|
||||
<ThemeToggleProvider themes={{ light: lightTheme }}>
|
||||
<Theme>
|
||||
<DndProvider backend={HTML5Backend}>
|
||||
<Provider store={store}>
|
||||
<Router history={history}>
|
||||
<ContentManagerApp />
|
||||
</Router>
|
||||
</Provider>
|
||||
</DndProvider>
|
||||
</Theme>
|
||||
</ThemeToggleProvider>
|
||||
</IntlProvider>
|
||||
);
|
||||
|
||||
|
||||
@ -8,7 +8,9 @@ import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
import { MemoryRouter } from 'react-router-dom';
|
||||
import { lightTheme } from '@strapi/design-system';
|
||||
import Theme from '../../../../../components/Theme';
|
||||
import ThemeToggleProvider from '../../../../../components/ThemeToggleProvider';
|
||||
import { Header } from '../index';
|
||||
import components from '../utils/tests/data/compos-schema.json';
|
||||
import ct from '../utils/tests/data/ct-schema.json';
|
||||
@ -31,9 +33,11 @@ const makeApp = (props = defaultProps) => {
|
||||
return (
|
||||
<MemoryRouter>
|
||||
<IntlProvider locale="en" defaultLocale="en" messages={{}}>
|
||||
<Theme>
|
||||
<Header {...props} />
|
||||
</Theme>
|
||||
<ThemeToggleProvider themes={{ light: lightTheme }}>
|
||||
<Theme>
|
||||
<Header {...props} />
|
||||
</Theme>
|
||||
</ThemeToggleProvider>
|
||||
</IntlProvider>
|
||||
</MemoryRouter>
|
||||
);
|
||||
@ -46,63 +50,6 @@ describe('CONTENT MANAGER | EditView | Header', () => {
|
||||
} = render(makeApp());
|
||||
|
||||
expect(firstChild).toMatchInlineSnapshot(`
|
||||
.c0 {
|
||||
background: #f6f6f9;
|
||||
padding-top: 24px;
|
||||
padding-right: 56px;
|
||||
padding-bottom: 40px;
|
||||
padding-left: 56px;
|
||||
}
|
||||
|
||||
.c1 {
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.c6 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-flex-direction: row;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
-webkit-box-pack: justify;
|
||||
-webkit-justify-content: space-between;
|
||||
-ms-flex-pack: justify;
|
||||
justify-content: space-between;
|
||||
-webkit-align-items: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.c7 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-flex-direction: row;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
-webkit-align-items: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.c8 {
|
||||
color: #32324d;
|
||||
font-weight: 600;
|
||||
font-size: 2rem;
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
.c15 {
|
||||
color: #666687;
|
||||
font-size: 1rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.c14 {
|
||||
font-weight: 600;
|
||||
color: #32324d;
|
||||
@ -180,7 +127,7 @@ describe('CONTENT MANAGER | EditView | Header', () => {
|
||||
background: #4945ff;
|
||||
}
|
||||
|
||||
.c12 .sc-egiyK {
|
||||
.c12 .sc-fTQvRK {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
@ -233,6 +180,86 @@ describe('CONTENT MANAGER | EditView | Header', () => {
|
||||
background: #4945ff;
|
||||
}
|
||||
|
||||
.c9 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-flex-direction: row;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
-webkit-align-items: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.c10 > * {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.c10 > * + * {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
.c0 {
|
||||
background: #f6f6f9;
|
||||
padding-top: 24px;
|
||||
padding-right: 56px;
|
||||
padding-bottom: 40px;
|
||||
padding-left: 56px;
|
||||
}
|
||||
|
||||
.c1 {
|
||||
padding-bottom: 8px;
|
||||
}
|
||||
|
||||
.c6 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-flex-direction: row;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
-webkit-box-pack: justify;
|
||||
-webkit-justify-content: space-between;
|
||||
-ms-flex-pack: justify;
|
||||
justify-content: space-between;
|
||||
-webkit-align-items: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.c7 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-flex-direction: row;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
-webkit-align-items: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.c8 {
|
||||
color: #32324d;
|
||||
font-weight: 600;
|
||||
font-size: 2rem;
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
.c15 {
|
||||
color: #666687;
|
||||
font-size: 1rem;
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.c5 {
|
||||
color: #4945ff;
|
||||
font-size: 0.75rem;
|
||||
@ -303,29 +330,6 @@ describe('CONTENT MANAGER | EditView | Header', () => {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.c9 {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
display: flex;
|
||||
-webkit-flex-direction: row;
|
||||
-ms-flex-direction: row;
|
||||
flex-direction: row;
|
||||
-webkit-align-items: center;
|
||||
-webkit-box-align: center;
|
||||
-ms-flex-align: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.c10 > * {
|
||||
margin-left: 0;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.c10 > * + * {
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
<div
|
||||
style="height: 0px;"
|
||||
>
|
||||
|
||||
@ -8,7 +8,9 @@ import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
import { useCMEditViewDataManager } from '@strapi/helper-plugin';
|
||||
import { lightTheme } from '@strapi/design-system';
|
||||
import Theme from '../../../../../components/Theme';
|
||||
import ThemeToggleProvider from '../../../../../components/ThemeToggleProvider';
|
||||
import Informations from '../index';
|
||||
|
||||
jest.mock('@strapi/helper-plugin', () => ({
|
||||
@ -22,9 +24,11 @@ const makeApp = () => {
|
||||
defaultLocale="en"
|
||||
messages={{ 'containers.Edit.information': 'Information' }}
|
||||
>
|
||||
<Theme>
|
||||
<Informations />
|
||||
</Theme>
|
||||
<ThemeToggleProvider themes={{ light: lightTheme }}>
|
||||
<Theme>
|
||||
<Informations />
|
||||
</Theme>
|
||||
</ThemeToggleProvider>
|
||||
</IntlProvider>
|
||||
);
|
||||
};
|
||||
|
||||
@ -3,7 +3,9 @@ import { render } from '@testing-library/react';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
import { Router } from 'react-router-dom';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import { lightTheme } from '@strapi/design-system';
|
||||
import Theme from '../../../../components/Theme';
|
||||
import ThemeToggleProvider from '../../../../components/ThemeToggleProvider';
|
||||
import NoContentType from '../index';
|
||||
|
||||
jest.mock('@strapi/helper-plugin', () => ({
|
||||
@ -17,9 +19,11 @@ describe('CONTENT MANAGER | pages | NoContentType', () => {
|
||||
} = render(
|
||||
<Router history={createMemoryHistory()}>
|
||||
<IntlProvider messages={{}} defaultLocale="en" textComponent="span" locale="en">
|
||||
<Theme>
|
||||
<NoContentType />
|
||||
</Theme>
|
||||
<ThemeToggleProvider themes={{ light: lightTheme }}>
|
||||
<Theme>
|
||||
<NoContentType />
|
||||
</Theme>
|
||||
</ThemeToggleProvider>
|
||||
</IntlProvider>
|
||||
</Router>
|
||||
);
|
||||
|
||||
@ -7,7 +7,9 @@
|
||||
import React from 'react';
|
||||
import { render } from '@testing-library/react';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
import { lightTheme } from '@strapi/design-system';
|
||||
import Theme from '../../../../components/Theme';
|
||||
import ThemeToggleProvider from '../../../../components/ThemeToggleProvider';
|
||||
import NoPermissions from '../index';
|
||||
|
||||
jest.mock('@strapi/helper-plugin', () => ({
|
||||
@ -21,9 +23,11 @@ describe('<NoPermissions />', () => {
|
||||
container: { firstChild },
|
||||
} = render(
|
||||
<IntlProvider locale="en" messages={{}} defaultLocale="en" textComponent="span">
|
||||
<Theme>
|
||||
<NoPermissions />
|
||||
</Theme>
|
||||
<ThemeToggleProvider themes={{ light: lightTheme }}>
|
||||
<Theme>
|
||||
<NoPermissions />
|
||||
</Theme>
|
||||
</ThemeToggleProvider>
|
||||
</IntlProvider>
|
||||
);
|
||||
|
||||
|
||||
@ -0,0 +1,5 @@
|
||||
import { createContext } from 'react';
|
||||
|
||||
const ThemeToggleContext = createContext({});
|
||||
|
||||
export default ThemeToggleContext;
|
||||
@ -1,3 +1,4 @@
|
||||
export { default as AdminContext } from './Admin';
|
||||
export { default as ConfigurationsContext } from './Configurations';
|
||||
export { default as PermissionsDataManagerContext } from './PermisssionsDataManagerContext';
|
||||
export { default as ThemeToggleContext } from './ThemeToggle';
|
||||
|
||||
@ -9,3 +9,4 @@ export { default as useSettingsMenu } from './useSettingsMenu';
|
||||
export { default as useSettingsForm } from './useSettingsForm';
|
||||
export { default as usePermissionsDataManager } from './usePermissionsDataManager';
|
||||
export { default as useReleaseNotification } from './useReleaseNotification';
|
||||
export { default as useThemeToggle } from './useThemeToggle';
|
||||
|
||||
10
packages/core/admin/admin/src/hooks/useThemeToggle/index.js
Normal file
10
packages/core/admin/admin/src/hooks/useThemeToggle/index.js
Normal file
@ -0,0 +1,10 @@
|
||||
import { useContext } from 'react';
|
||||
import { ThemeToggleContext } from '../../contexts';
|
||||
|
||||
const useThemeToggle = () => {
|
||||
const context = useContext(ThemeToggleContext);
|
||||
|
||||
return context;
|
||||
};
|
||||
|
||||
export default useThemeToggle;
|
||||
@ -12,9 +12,9 @@ import {
|
||||
} from '@strapi/helper-plugin';
|
||||
import { useIntl } from 'react-intl';
|
||||
import { Formik } from 'formik';
|
||||
import upperFirst from 'lodash/upperFirst';
|
||||
import { useQuery, useMutation, useQueryClient } from 'react-query';
|
||||
import pick from 'lodash/pick';
|
||||
import omit from 'lodash/omit';
|
||||
import { Helmet } from 'react-helmet';
|
||||
import { Main } from '@strapi/design-system/Main';
|
||||
import { Typography } from '@strapi/design-system/Typography';
|
||||
@ -31,6 +31,7 @@ import Eye from '@strapi/icons/Eye';
|
||||
import EyeStriked from '@strapi/icons/EyeStriked';
|
||||
import Check from '@strapi/icons/Check';
|
||||
import useLocalesProvider from '../../components/LocalesProvider/useLocalesProvider';
|
||||
import { useThemeToggle } from '../../hooks';
|
||||
import { fetchUser, putUser } from './utils/api';
|
||||
import schema from './utils/schema';
|
||||
import { getFullName } from '../../utils';
|
||||
@ -62,6 +63,7 @@ const ProfilePage = () => {
|
||||
const toggleNotification = useNotification();
|
||||
const { lockApp, unlockApp } = useOverlayBlocker();
|
||||
const { notifyStatus } = useNotifyAT();
|
||||
const { currentTheme, themes: allApplicationThemes, onChangeTheme } = useThemeToggle();
|
||||
useFocusWhenNavigate();
|
||||
|
||||
const { status, data } = useQuery('user', () => fetchUser(), {
|
||||
@ -83,14 +85,17 @@ const ProfilePage = () => {
|
||||
|
||||
const isLoading = status !== 'success';
|
||||
|
||||
const submitMutation = useMutation(body => putUser(omit(body, 'confirmPassword')), {
|
||||
const submitMutation = useMutation(body => putUser(body), {
|
||||
onSuccess: async data => {
|
||||
await queryClient.invalidateQueries('user');
|
||||
|
||||
auth.setUserInfo(data);
|
||||
auth.setUserInfo(
|
||||
pick(data, ['email', 'firstname', 'lastname', 'username', 'preferedLanguage'])
|
||||
);
|
||||
const userDisplayName = data.username || getFullName(data.firstname, data.lastname);
|
||||
setUserDisplayName(userDisplayName);
|
||||
changeLocale(data.preferedLanguage);
|
||||
onChangeTheme(data.currentTheme);
|
||||
|
||||
toggleNotification({
|
||||
type: 'success',
|
||||
@ -128,9 +133,16 @@ const ProfilePage = () => {
|
||||
);
|
||||
};
|
||||
|
||||
const fieldsToPick = ['email', 'firstname', 'lastname', 'username', 'preferedLanguage'];
|
||||
const fieldsToPick = [
|
||||
'currentTheme',
|
||||
'email',
|
||||
'firstname',
|
||||
'lastname',
|
||||
'username',
|
||||
'preferedLanguage',
|
||||
];
|
||||
|
||||
const initialData = pick(data, fieldsToPick);
|
||||
const initialData = pick({ ...data, currentTheme }, fieldsToPick);
|
||||
|
||||
if (isLoading) {
|
||||
return (
|
||||
@ -154,6 +166,10 @@ const ProfilePage = () => {
|
||||
);
|
||||
}
|
||||
|
||||
const themesToDisplay = Object.keys(allApplicationThemes).filter(
|
||||
themeName => allApplicationThemes[themeName]
|
||||
);
|
||||
|
||||
return (
|
||||
<Main aria-busy={isSubmittingForm}>
|
||||
<Helmet
|
||||
@ -487,6 +503,47 @@ const ProfilePage = () => {
|
||||
})}
|
||||
</Select>
|
||||
</GridItem>
|
||||
<GridItem s={12} col={6}>
|
||||
<Select
|
||||
label={formatMessage({
|
||||
id: 'Settings.profile.form.section.experience.mode.label',
|
||||
defaultMessage: 'Interface mode',
|
||||
})}
|
||||
placeholder={formatMessage({
|
||||
id: 'components.Select.placeholder',
|
||||
defaultMessage: 'Select',
|
||||
})}
|
||||
hint={formatMessage({
|
||||
id: 'Settings.profile.form.section.experience.mode.hint',
|
||||
defaultMessage: 'Displays your interface in the chosen mode.',
|
||||
})}
|
||||
value={values.currentTheme}
|
||||
onChange={e => {
|
||||
handleChange({
|
||||
target: { name: 'currentTheme', value: e },
|
||||
});
|
||||
}}
|
||||
>
|
||||
{themesToDisplay.map(theme => {
|
||||
const label = formatMessage(
|
||||
{
|
||||
id:
|
||||
'Settings.profile.form.section.experience.mode.option-label',
|
||||
defaultMessage: '{name} mode',
|
||||
},
|
||||
{
|
||||
name: upperFirst(theme),
|
||||
}
|
||||
);
|
||||
|
||||
return (
|
||||
<Option value={theme} key={theme}>
|
||||
{label}
|
||||
</Option>
|
||||
);
|
||||
})}
|
||||
</Select>
|
||||
</GridItem>
|
||||
</Grid>
|
||||
</Stack>
|
||||
</Box>
|
||||
|
||||
@ -2,9 +2,11 @@ import React from 'react';
|
||||
import { render, waitFor, screen } from '@testing-library/react';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
import { QueryClient, QueryClientProvider } from 'react-query';
|
||||
import { ThemeProvider, lightTheme } from '@strapi/design-system';
|
||||
import { lightTheme } from '@strapi/design-system';
|
||||
import ProfilePage from '../index';
|
||||
import server from './utils/server';
|
||||
import ThemeToggleProvider from '../../../components/ThemeToggleProvider';
|
||||
import Theme from '../../../components/Theme';
|
||||
|
||||
jest.mock('../../../components/LocalesProvider/useLocalesProvider', () => () => ({
|
||||
changeLocale: () => {},
|
||||
@ -31,9 +33,11 @@ const client = new QueryClient({
|
||||
const App = (
|
||||
<QueryClientProvider client={client}>
|
||||
<IntlProvider messages={{}} textComponent="span" locale="en">
|
||||
<ThemeProvider theme={lightTheme}>
|
||||
<ProfilePage />
|
||||
</ThemeProvider>
|
||||
<ThemeToggleProvider themes={{ light: lightTheme }}>
|
||||
<Theme>
|
||||
<ProfilePage />
|
||||
</Theme>
|
||||
</ThemeToggleProvider>
|
||||
</IntlProvider>
|
||||
</QueryClientProvider>
|
||||
);
|
||||
@ -1327,6 +1331,90 @@ describe('ADMIN | Pages | Profile page', () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="c20"
|
||||
>
|
||||
<div
|
||||
class=""
|
||||
>
|
||||
<div>
|
||||
<div
|
||||
class="c36"
|
||||
>
|
||||
<span
|
||||
class="c37"
|
||||
for="select-2"
|
||||
id="select-2-label"
|
||||
>
|
||||
Interface mode
|
||||
</span>
|
||||
<div
|
||||
class="c38 c39"
|
||||
>
|
||||
<button
|
||||
aria-describedby="select-2-hint"
|
||||
aria-disabled="false"
|
||||
aria-expanded="false"
|
||||
aria-haspopup="listbox"
|
||||
aria-labelledby="select-2-label select-2-content"
|
||||
class="c40"
|
||||
id="select-2"
|
||||
type="button"
|
||||
/>
|
||||
<div
|
||||
class="c41 c42"
|
||||
>
|
||||
<div
|
||||
class="c38"
|
||||
>
|
||||
<div
|
||||
class="c43"
|
||||
>
|
||||
<span
|
||||
class="c44"
|
||||
id="select-2-content"
|
||||
>
|
||||
Light mode
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="c38"
|
||||
>
|
||||
<button
|
||||
aria-hidden="true"
|
||||
class="c46 c45 c47"
|
||||
tabindex="-1"
|
||||
type="button"
|
||||
>
|
||||
<svg
|
||||
fill="none"
|
||||
height="1em"
|
||||
viewBox="0 0 14 8"
|
||||
width="1em"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
clip-rule="evenodd"
|
||||
d="M14 .889a.86.86 0 01-.26.625L7.615 7.736A.834.834 0 017 8a.834.834 0 01-.615-.264L.26 1.514A.861.861 0 010 .889c0-.24.087-.45.26-.625A.834.834 0 01.875 0h12.25c.237 0 .442.088.615.264a.86.86 0 01.26.625z"
|
||||
fill="#32324D"
|
||||
fill-rule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<p
|
||||
class="c48"
|
||||
id="select-2-hint"
|
||||
>
|
||||
Displays your interface in the chosen mode.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import omit from 'lodash/omit';
|
||||
import { axiosInstance } from '../../../core/utils';
|
||||
|
||||
const fetchUser = async () => {
|
||||
@ -7,9 +8,10 @@ const fetchUser = async () => {
|
||||
};
|
||||
|
||||
const putUser = async body => {
|
||||
const { data } = await axiosInstance.put('/admin/users/me', body);
|
||||
const dataToSend = omit(body, ['confirmPassword', 'currentTheme']);
|
||||
const { data } = await axiosInstance.put('/admin/users/me', dataToSend);
|
||||
|
||||
return data.data;
|
||||
return { ...data.data, currentTheme: body.currentTheme };
|
||||
};
|
||||
|
||||
export { fetchUser, putUser };
|
||||
|
||||
@ -5,8 +5,10 @@ import { Router, Route } from 'react-router-dom';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import { useRBAC } from '@strapi/helper-plugin';
|
||||
import { QueryClient, QueryClientProvider } from 'react-query';
|
||||
import { lightTheme } from '@strapi/design-system';
|
||||
import { axiosInstance } from '../../../../../../core/utils';
|
||||
import Theme from '../../../../../../components/Theme';
|
||||
import ThemeToggleProvider from '../../../../../../components/ThemeToggleProvider';
|
||||
import ListView from '../index';
|
||||
|
||||
jest.mock('@strapi/helper-plugin', () => ({
|
||||
@ -49,13 +51,15 @@ const makeApp = history => {
|
||||
return (
|
||||
<QueryClientProvider client={client}>
|
||||
<IntlProvider messages={{}} defaultLocale="en" textComponent="span" locale="en">
|
||||
<Theme>
|
||||
<Router history={history}>
|
||||
<Route path="/settings/api-tokens">
|
||||
<ListView />
|
||||
</Route>
|
||||
</Router>
|
||||
</Theme>
|
||||
<ThemeToggleProvider themes={{ light: lightTheme }}>
|
||||
<Theme>
|
||||
<Router history={history}>
|
||||
<Route path="/settings/api-tokens">
|
||||
<ListView />
|
||||
</Route>
|
||||
</Router>
|
||||
</Theme>
|
||||
</ThemeToggleProvider>
|
||||
</IntlProvider>
|
||||
</QueryClientProvider>
|
||||
);
|
||||
|
||||
@ -104,7 +104,7 @@ exports[`<EditPage /> renders and matches the snapshot 1`] = `
|
||||
background: #4945ff;
|
||||
}
|
||||
|
||||
.c13 .sc-eCImPb {
|
||||
.c13 .sc-fTQvRK {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
@ -169,7 +169,7 @@ exports[`<EditPage /> renders and matches the snapshot 1`] = `
|
||||
background: #f0f0ff;
|
||||
}
|
||||
|
||||
.c24 .sc-eCImPb {
|
||||
.c24 .sc-fTQvRK {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
|
||||
@ -10,7 +10,9 @@ import { IntlProvider } from 'react-intl';
|
||||
import { Router, Switch, Route } from 'react-router-dom';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import moment from 'moment';
|
||||
import { lightTheme } from '@strapi/design-system';
|
||||
import Theme from '../../../../../../components/Theme';
|
||||
import ThemeToggleProvider from '../../../../../../components/ThemeToggleProvider';
|
||||
|
||||
import EditPage from '../index';
|
||||
|
||||
@ -37,15 +39,17 @@ const makeApp = history => (
|
||||
locale="en"
|
||||
defaultLocale="en"
|
||||
>
|
||||
<Theme>
|
||||
<Router history={history}>
|
||||
<Switch>
|
||||
<Route path="/settings/roles/:id">
|
||||
<EditPage />
|
||||
</Route>
|
||||
</Switch>
|
||||
</Router>
|
||||
</Theme>
|
||||
<ThemeToggleProvider themes={{ light: lightTheme }}>
|
||||
<Theme>
|
||||
<Router history={history}>
|
||||
<Switch>
|
||||
<Route path="/settings/roles/:id">
|
||||
<EditPage />
|
||||
</Route>
|
||||
</Switch>
|
||||
</Router>
|
||||
</Theme>
|
||||
</ThemeToggleProvider>
|
||||
</IntlProvider>
|
||||
);
|
||||
|
||||
|
||||
@ -10,9 +10,11 @@ import { createMemoryHistory } from 'history';
|
||||
import { Router } from 'react-router-dom';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
import { useRBAC } from '@strapi/helper-plugin';
|
||||
import { lightTheme } from '@strapi/design-system';
|
||||
import { useRolesList } from '../../../../../../hooks';
|
||||
|
||||
import Theme from '../../../../../../components/Theme';
|
||||
import ThemeToggleProvider from '../../../../../../components/ThemeToggleProvider';
|
||||
import ListPage from '../index';
|
||||
|
||||
jest.mock('@strapi/helper-plugin', () => ({
|
||||
@ -31,11 +33,13 @@ jest.mock('../../../../../../hooks', () => ({
|
||||
|
||||
const makeApp = history => (
|
||||
<IntlProvider messages={{}} defaultLocale="en" textComponent="span" locale="en">
|
||||
<Theme>
|
||||
<Router history={history}>
|
||||
<ListPage />
|
||||
</Router>
|
||||
</Theme>
|
||||
<ThemeToggleProvider themes={{ light: lightTheme }}>
|
||||
<Theme>
|
||||
<Router history={history}>
|
||||
<ListPage />
|
||||
</Router>
|
||||
</Theme>
|
||||
</ThemeToggleProvider>
|
||||
</IntlProvider>
|
||||
);
|
||||
|
||||
|
||||
@ -466,7 +466,7 @@ exports[`DynamicTable renders and matches the snapshot 1`] = `
|
||||
</div>
|
||||
<nav
|
||||
aria-label="pagination"
|
||||
class="sc-fHeRUh"
|
||||
class="sc-jwQYvw"
|
||||
>
|
||||
<ul
|
||||
class="c16 c17"
|
||||
|
||||
@ -3,19 +3,23 @@ import { render } from '@testing-library/react';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import { Router, Route } from 'react-router-dom';
|
||||
import { lightTheme } from '@strapi/design-system';
|
||||
import Theme from '../../../../../../../components/Theme';
|
||||
import ThemeToggleProvider from '../../../../../../../components/ThemeToggleProvider';
|
||||
import PaginationFooter from '../index';
|
||||
|
||||
const makeApp = (history, pagination) => {
|
||||
return (
|
||||
<IntlProvider messages={{}} textComponent="span" locale="en" defaultLocale="en">
|
||||
<Theme>
|
||||
<Router history={history}>
|
||||
<Route path="/settings/user">
|
||||
<PaginationFooter pagination={pagination} />
|
||||
</Route>
|
||||
</Router>
|
||||
</Theme>
|
||||
<ThemeToggleProvider themes={{ light: lightTheme }}>
|
||||
<Theme>
|
||||
<Router history={history}>
|
||||
<Route path="/settings/user">
|
||||
<PaginationFooter pagination={pagination} />
|
||||
</Route>
|
||||
</Router>
|
||||
</Theme>
|
||||
</ThemeToggleProvider>
|
||||
</IntlProvider>
|
||||
);
|
||||
};
|
||||
|
||||
@ -5,7 +5,9 @@ import { Router, Route } from 'react-router-dom';
|
||||
import { QueryClient, QueryClientProvider } from 'react-query';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import { useRBAC } from '@strapi/helper-plugin';
|
||||
import { lightTheme } from '@strapi/design-system';
|
||||
import Theme from '../../../../../../components/Theme';
|
||||
import ThemeToggleProvider from '../../../../../../components/ThemeToggleProvider';
|
||||
import ListPage from '../index';
|
||||
import server from './utils/server';
|
||||
|
||||
@ -30,13 +32,15 @@ const makeApp = history => {
|
||||
return (
|
||||
<QueryClientProvider client={client}>
|
||||
<IntlProvider messages={{}} defaultLocale="en" textComponent="span" locale="en">
|
||||
<Theme>
|
||||
<Router history={history}>
|
||||
<Route path="/settings/user">
|
||||
<ListPage />
|
||||
</Route>
|
||||
</Router>
|
||||
</Theme>
|
||||
<ThemeToggleProvider themes={{ light: lightTheme }}>
|
||||
<Theme>
|
||||
<Router history={history}>
|
||||
<Route path="/settings/user">
|
||||
<ListPage />
|
||||
</Route>
|
||||
</Router>
|
||||
</Theme>
|
||||
</ThemeToggleProvider>
|
||||
</IntlProvider>
|
||||
</QueryClientProvider>
|
||||
);
|
||||
|
||||
@ -3,8 +3,10 @@ import userEvent from '@testing-library/user-event';
|
||||
import React from 'react';
|
||||
import { Router } from 'react-router-dom';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import { lightTheme } from '@strapi/design-system';
|
||||
import en from '../../../../../../../../translations/en.json';
|
||||
import Theme from '../../../../../../../../components/Theme';
|
||||
import ThemeToggleProvider from '../../../../../../../../components/ThemeToggleProvider';
|
||||
import LanguageProvider from '../../../../../../../../components/LanguageProvider';
|
||||
import WebhookForm from '../index';
|
||||
|
||||
@ -15,9 +17,11 @@ const makeApp = component => {
|
||||
|
||||
return (
|
||||
<LanguageProvider messages={messages} localeNames={localeNames}>
|
||||
<Theme>
|
||||
<Router history={history}>{component}</Router>
|
||||
</Theme>
|
||||
<ThemeToggleProvider themes={{ light: lightTheme }}>
|
||||
<Theme>
|
||||
<Router history={history}>{component}</Router>
|
||||
</Theme>
|
||||
</ThemeToggleProvider>
|
||||
</LanguageProvider>
|
||||
);
|
||||
};
|
||||
|
||||
@ -4,13 +4,16 @@ import { StrapiAppProvider, AppInfosContext } from '@strapi/helper-plugin';
|
||||
import { render, screen, waitFor } from '@testing-library/react';
|
||||
import userEvent from '@testing-library/user-event';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import { lightTheme } from '@strapi/design-system';
|
||||
import Theme from '../../../components/Theme';
|
||||
import ThemeToggleProvider from '../../../components/ThemeToggleProvider';
|
||||
import { SettingsPage } from '..';
|
||||
import { useSettingsMenu } from '../../../hooks';
|
||||
|
||||
jest.mock('../../../hooks', () => ({
|
||||
useSettingsMenu: jest.fn(() => ({ isLoading: false, menu: [] })),
|
||||
useAppInfos: jest.fn(() => ({ shouldUpdateStrapi: false })),
|
||||
useThemeToggle: jest.fn(() => ({ currentTheme: 'light', themes: { light: lightTheme } })),
|
||||
}));
|
||||
|
||||
jest.mock('@fortawesome/react-fontawesome', () => ({
|
||||
@ -24,24 +27,26 @@ jest.mock('react-intl', () => ({
|
||||
jest.mock('../pages/ApplicationInfosPage', () => () => <h1>App infos</h1>);
|
||||
|
||||
const makeApp = (history, settings) => (
|
||||
<Theme>
|
||||
<AppInfosContext.Provider value={{ shouldUpdateStrapi: false }}>
|
||||
<StrapiAppProvider
|
||||
settings={settings}
|
||||
plugins={{}}
|
||||
getPlugin={jest.fn()}
|
||||
runHookParallel={jest.fn()}
|
||||
runHookWaterfall={jest.fn()}
|
||||
runHookSeries={jest.fn()}
|
||||
menu={[]}
|
||||
>
|
||||
<Router history={history}>
|
||||
<Route path="/settings/:settingId" component={SettingsPage} />
|
||||
<Route path="/settings" component={SettingsPage} />
|
||||
</Router>
|
||||
</StrapiAppProvider>
|
||||
</AppInfosContext.Provider>
|
||||
</Theme>
|
||||
<ThemeToggleProvider themes={{ light: lightTheme }}>
|
||||
<Theme>
|
||||
<AppInfosContext.Provider value={{ shouldUpdateStrapi: false }}>
|
||||
<StrapiAppProvider
|
||||
settings={settings}
|
||||
plugins={{}}
|
||||
getPlugin={jest.fn()}
|
||||
runHookParallel={jest.fn()}
|
||||
runHookWaterfall={jest.fn()}
|
||||
runHookSeries={jest.fn()}
|
||||
menu={[]}
|
||||
>
|
||||
<Router history={history}>
|
||||
<Route path="/settings/:settingId" component={SettingsPage} />
|
||||
<Route path="/settings" component={SettingsPage} />
|
||||
</Router>
|
||||
</StrapiAppProvider>
|
||||
</AppInfosContext.Provider>
|
||||
</Theme>
|
||||
</ThemeToggleProvider>
|
||||
);
|
||||
|
||||
describe('ADMIN | pages | SettingsPage', () => {
|
||||
|
||||
102
packages/core/admin/admin/src/temp-dark-theme.js
Normal file
102
packages/core/admin/admin/src/temp-dark-theme.js
Normal file
@ -0,0 +1,102 @@
|
||||
// TODO delete this file when we release the DS.
|
||||
|
||||
const darkTheme = {
|
||||
colors: {
|
||||
alternative100: '#212134',
|
||||
alternative200: '#4a4a6a',
|
||||
alternative500: '#ac73e6',
|
||||
alternative600: '#f6ecfc',
|
||||
alternative700: '#e0c1f4',
|
||||
danger100: '#212134',
|
||||
danger200: '#4a4a6a',
|
||||
danger500: '#ee5e52',
|
||||
danger600: '#fcecea',
|
||||
danger700: '#f5c0b8',
|
||||
neutral0: '#212134',
|
||||
neutral100: '#181826',
|
||||
neutral1000: '#ffffff',
|
||||
neutral150: '#4a4a6a',
|
||||
neutral200: '#666687',
|
||||
neutral300: '#666687',
|
||||
neutral400: '#a5a5ba',
|
||||
neutral500: '#c0c0cf',
|
||||
neutral600: '#a5a5ba',
|
||||
neutral700: '#eaeaef',
|
||||
neutral800: '#ffffff',
|
||||
neutral900: '#ffffff',
|
||||
primary100: '#212134',
|
||||
primary200: '#4a4a6a',
|
||||
primary500: '#d9d8ff',
|
||||
primary600: '#7b79ff',
|
||||
primary700: '#7b79ff',
|
||||
secondary100: '#212134',
|
||||
secondary200: '#4a4a6a',
|
||||
secondary500: '#66b7f1',
|
||||
secondary600: '#eaf5ff',
|
||||
secondary700: '#b8e1ff',
|
||||
success100: '#212134',
|
||||
success200: '#4a4a6a',
|
||||
success500: '#5cb176',
|
||||
success600: '#c6f0c2',
|
||||
success700: '#c6f0c2',
|
||||
warning100: '#212134',
|
||||
warning200: '#4a4a6a',
|
||||
warning500: '#f29d41',
|
||||
warning600: '#fdf4dc',
|
||||
warning700: '#fae7b9',
|
||||
},
|
||||
shadows: {
|
||||
filterShadow: '0px 1px 4px rgba(33, 33, 52, 0.1)',
|
||||
focus:
|
||||
'inset 2px 0px 0px rgb(39, 31, 224), inset 0px 2px 0px rgb(39, 31, 224), inset -2px 0px 0px rgb(39, 31, 224), inset 0px -2px 0px rgb(39, 31, 224)',
|
||||
focusShadow: '0px 0px 6px rgba(76, 191, 255, 0.75)',
|
||||
popupShadow: '0px 2px 15px rgba(33, 33, 52, 0.1)',
|
||||
tableShadow: '0px 1px 4px rgba(33, 33, 52, 0.1)',
|
||||
},
|
||||
sizes: {
|
||||
input: {
|
||||
S: `${32 / 16}rem`,
|
||||
M: `${40 / 16}rem`,
|
||||
},
|
||||
accordions: {
|
||||
S: `${48 / 16}rem`,
|
||||
M: `${88 / 16}rem`,
|
||||
},
|
||||
},
|
||||
zIndices: [5, 10, 15, 20], // TBD
|
||||
spaces: [
|
||||
'0px',
|
||||
'4px',
|
||||
'8px',
|
||||
'12px',
|
||||
'16px',
|
||||
'20px',
|
||||
'24px',
|
||||
'32px',
|
||||
'40px',
|
||||
'48px',
|
||||
'56px',
|
||||
'64px',
|
||||
],
|
||||
borderRadius: '4px',
|
||||
mediaQueries: {
|
||||
tablet: `@media (max-width: ${1100 / 16}rem)`,
|
||||
mobile: `@media (max-width: ${550 / 16}rem)`,
|
||||
},
|
||||
fontSizes: [
|
||||
`${11 / 16}rem`,
|
||||
`${12 / 16}rem`,
|
||||
`${14 / 16}rem`,
|
||||
'1rem',
|
||||
`${18 / 16}rem`,
|
||||
`${32 / 16}rem`,
|
||||
],
|
||||
lineHeights: [1.14, 1.22, 1.25, 1.33, 1.43, 1.45, 1.5],
|
||||
fontWeights: {
|
||||
regular: 400,
|
||||
semiBold: 500,
|
||||
bold: 600,
|
||||
},
|
||||
};
|
||||
|
||||
export default darkTheme;
|
||||
@ -299,7 +299,7 @@ describe('ADMIN | StrapiApp', () => {
|
||||
|
||||
app.createCustomConfigurations();
|
||||
|
||||
expect(app.configurations.theme.main.colors.red).toBe('black');
|
||||
expect(app.configurations.themes.custom.main.colors.red).toBe('black');
|
||||
});
|
||||
|
||||
it('should override the tutorials', () => {
|
||||
|
||||
@ -1,51 +0,0 @@
|
||||
const colors = {
|
||||
black: '#333740',
|
||||
white: '#ffffff',
|
||||
red: '#ff203c',
|
||||
orange: '#ff5d00',
|
||||
lightOrange: '#f64d0a',
|
||||
yellow: '#ffd500',
|
||||
green: '#6dbb1a',
|
||||
blue: '#0097f7',
|
||||
teal: '#5bc0de',
|
||||
pink: '#ff5b77',
|
||||
purple: '#613d7c',
|
||||
gray: '#464a4c',
|
||||
border: '#e3e9f3',
|
||||
'gray-dark': '#292b2c',
|
||||
grayLight: '#636c72',
|
||||
'gray-lighter': '#eceeef',
|
||||
'gray-lightest': '#f7f7f9',
|
||||
brightGrey: '#f0f3f8',
|
||||
darkGrey: '#e3e9f3',
|
||||
lightGrey: '#fafafa',
|
||||
lightestGrey: '#fbfbfb',
|
||||
mediumGrey: '#f2f3f4',
|
||||
grey: '#9ea7b8',
|
||||
greyDark: '#292b2c',
|
||||
greyAlpha: 'rgba(227, 233, 243, 0.5)',
|
||||
lightestBlue: '#e4f0fc',
|
||||
lightBlue: '#e6f0fb',
|
||||
mediumBlue: '#007eff',
|
||||
darkBlue: '#aed4fb',
|
||||
pale: '#f7f8f8',
|
||||
content: {
|
||||
background: '#fafafb',
|
||||
'background-alpha': 'rgba(14, 22, 34, 0.02)',
|
||||
},
|
||||
leftMenu: {
|
||||
'link-hover': '#1c2431',
|
||||
'link-color': '#919bae',
|
||||
'title-color': '#5b626f',
|
||||
'background-header-link': '#007eff',
|
||||
},
|
||||
strapi: {
|
||||
'gray-light': '#eff3f6',
|
||||
gray: '#535f76',
|
||||
'blue-darker': '#18202e',
|
||||
'blue-dark': '#151c2e',
|
||||
blue: '#0097f7',
|
||||
},
|
||||
};
|
||||
|
||||
export default colors;
|
||||
@ -1,8 +0,0 @@
|
||||
const fontWeights = {
|
||||
regular: 400,
|
||||
semiBold: 500,
|
||||
bold: 600,
|
||||
black: 900,
|
||||
};
|
||||
|
||||
export default fontWeights;
|
||||
@ -1,13 +0,0 @@
|
||||
import colors from './colors';
|
||||
import fontWeights from './fontWeights';
|
||||
import sizes from './sizes';
|
||||
|
||||
const theme = {
|
||||
main: {
|
||||
colors,
|
||||
fontWeights,
|
||||
sizes,
|
||||
},
|
||||
};
|
||||
|
||||
export default theme;
|
||||
@ -1,31 +0,0 @@
|
||||
const sizes = {
|
||||
borderRadius: '2px',
|
||||
header: {
|
||||
height: '6rem',
|
||||
},
|
||||
leftMenu: {
|
||||
height: '6rem',
|
||||
width: '24rem',
|
||||
},
|
||||
margins: {
|
||||
// TODO:
|
||||
sm: '10px',
|
||||
},
|
||||
paddings: {
|
||||
// TODO
|
||||
xs: '5px',
|
||||
sm: '10px',
|
||||
smd: '20px',
|
||||
md: '30px',
|
||||
lg: '40px',
|
||||
},
|
||||
fonts: {
|
||||
xs: '11px',
|
||||
sm: '12px',
|
||||
md: '13px',
|
||||
lg: '18px',
|
||||
xl: '24px',
|
||||
},
|
||||
};
|
||||
|
||||
export default sizes;
|
||||
@ -137,6 +137,9 @@
|
||||
"Settings.profile.form.section.experience.interfaceLanguage": "Interface language",
|
||||
"Settings.profile.form.section.experience.interfaceLanguage.hint": "This will only display your own interface in the chosen language.",
|
||||
"Settings.profile.form.section.experience.interfaceLanguageHelp": "Selection will change the interface language only for you. Please refer to this {documentation} to make other languages available for your team.",
|
||||
"Settings.profile.form.section.experience.mode.label": "Interface mode",
|
||||
"Settings.profile.form.section.experience.mode.hint": "Displays your interface in the chosen mode.",
|
||||
"Settings.profile.form.section.experience.mode.option-label": "{name} mode",
|
||||
"Settings.profile.form.section.experience.title": "Experience",
|
||||
"Settings.profile.form.section.helmet.title": "User profile",
|
||||
"Settings.profile.form.section.password.title": "Change password",
|
||||
|
||||
@ -97,7 +97,7 @@ exports[`<CreatePage /> renders and matches the snapshot 1`] = `
|
||||
background: #f0f0ff;
|
||||
}
|
||||
|
||||
.c13 .sc-eCImPb {
|
||||
.c13 .sc-fTQvRK {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
@ -179,7 +179,7 @@ exports[`<CreatePage /> renders and matches the snapshot 1`] = `
|
||||
background: #4945ff;
|
||||
}
|
||||
|
||||
.c16 .sc-eCImPb {
|
||||
.c16 .sc-fTQvRK {
|
||||
display: -webkit-box;
|
||||
display: -webkit-flex;
|
||||
display: -ms-flexbox;
|
||||
|
||||
@ -10,7 +10,9 @@ import { IntlProvider } from 'react-intl';
|
||||
import { Router, Switch, Route } from 'react-router-dom';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import moment from 'moment';
|
||||
import { lightTheme } from '@strapi/design-system';
|
||||
import Theme from '../../../../../../../../admin/src/components/Theme';
|
||||
import ThemeToggleProvider from '../../../../../../../../admin/src/components/ThemeToggleProvider';
|
||||
|
||||
import { CreatePage } from '../index';
|
||||
|
||||
@ -37,18 +39,20 @@ const makeApp = history => (
|
||||
locale="en"
|
||||
defaultLocale="en"
|
||||
>
|
||||
<Theme>
|
||||
<Router history={history}>
|
||||
<Switch>
|
||||
<Route path="/settings/roles/duplicate/:id">
|
||||
<CreatePage />
|
||||
</Route>
|
||||
<Route path="/settings/roles/new">
|
||||
<CreatePage />
|
||||
</Route>
|
||||
</Switch>
|
||||
</Router>
|
||||
</Theme>
|
||||
<ThemeToggleProvider themes={{ light: lightTheme }}>
|
||||
<Theme>
|
||||
<Router history={history}>
|
||||
<Switch>
|
||||
<Route path="/settings/roles/duplicate/:id">
|
||||
<CreatePage />
|
||||
</Route>
|
||||
<Route path="/settings/roles/new">
|
||||
<CreatePage />
|
||||
</Route>
|
||||
</Switch>
|
||||
</Router>
|
||||
</Theme>
|
||||
</ThemeToggleProvider>
|
||||
</IntlProvider>
|
||||
);
|
||||
|
||||
|
||||
@ -10,9 +10,11 @@ import { createMemoryHistory } from 'history';
|
||||
import { Router } from 'react-router-dom';
|
||||
import { IntlProvider } from 'react-intl';
|
||||
import { useRBAC } from '@strapi/helper-plugin';
|
||||
import { lightTheme } from '@strapi/design-system';
|
||||
import { useRolesList } from '../../../../../../../../admin/src/hooks';
|
||||
|
||||
import Theme from '../../../../../../../../admin/src/components/Theme';
|
||||
import ThemeToggleProvider from '../../../../../../../../admin/src/components/ThemeToggleProvider';
|
||||
import ListPage from '../index';
|
||||
|
||||
jest.mock('@strapi/helper-plugin', () => ({
|
||||
@ -31,11 +33,13 @@ jest.mock('../../../../../../../../admin/src/hooks', () => ({
|
||||
|
||||
const makeApp = history => (
|
||||
<IntlProvider messages={{}} textComponent="span" locale="en">
|
||||
<Theme>
|
||||
<Router history={history}>
|
||||
<ListPage />
|
||||
</Router>
|
||||
</Theme>
|
||||
<ThemeToggleProvider themes={{ light: lightTheme }}>
|
||||
<Theme>
|
||||
<Router history={history}>
|
||||
<ListPage />
|
||||
</Router>
|
||||
</Theme>
|
||||
</ThemeToggleProvider>
|
||||
</IntlProvider>
|
||||
);
|
||||
|
||||
|
||||
@ -4,13 +4,14 @@
|
||||
*
|
||||
*/
|
||||
|
||||
import { Layout } from '@strapi/design-system';
|
||||
import { Layout, lightTheme } from '@strapi/design-system';
|
||||
import { render } from '@testing-library/react';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import React from 'react';
|
||||
import { Router } from 'react-router-dom';
|
||||
import LanguageProvider from '../../../../../../admin/admin/src/components/LanguageProvider';
|
||||
import Theme from '../../../../../../admin/admin/src/components/Theme';
|
||||
import ThemeToggleProvider from '../../../../../../admin/admin/src/components/ThemeToggleProvider';
|
||||
import en from '../../../../../../admin/admin/src/translations/en.json';
|
||||
import ContentTypeBuilderNav from '../index';
|
||||
import mockData from './mockData';
|
||||
@ -30,13 +31,15 @@ const makeApp = () => {
|
||||
|
||||
return (
|
||||
<LanguageProvider messages={messages} localeNames={localeNames}>
|
||||
<Theme>
|
||||
<Router history={history}>
|
||||
<Layout sideNav={<ContentTypeBuilderNav />}>
|
||||
<div />
|
||||
</Layout>
|
||||
</Router>
|
||||
</Theme>
|
||||
<ThemeToggleProvider themes={{ light: lightTheme }}>
|
||||
<Theme>
|
||||
<Router history={history}>
|
||||
<Layout sideNav={<ContentTypeBuilderNav />}>
|
||||
<div />
|
||||
</Layout>
|
||||
</Router>
|
||||
</Theme>
|
||||
</ThemeToggleProvider>
|
||||
</LanguageProvider>
|
||||
);
|
||||
};
|
||||
|
||||
@ -8,8 +8,10 @@ import { render } from '@testing-library/react';
|
||||
import { createMemoryHistory } from 'history';
|
||||
import React from 'react';
|
||||
import { Router } from 'react-router-dom';
|
||||
import { lightTheme } from '@strapi/design-system';
|
||||
import LanguageProvider from '../../../../../../admin/admin/src/components/LanguageProvider';
|
||||
import Theme from '../../../../../../admin/admin/src/components/Theme';
|
||||
import ThemeToggleProvider from '../../../../../../admin/admin/src/components/ThemeToggleProvider';
|
||||
import en from '../../../../../../admin/admin/src/translations/en.json';
|
||||
import FormModalNavigationProvider from '../../../components/FormModalNavigationProvider';
|
||||
import pluginEn from '../../../translations/en.json';
|
||||
@ -52,13 +54,15 @@ const makeApp = () => {
|
||||
|
||||
return (
|
||||
<LanguageProvider messages={messages} localeNames={localeNames}>
|
||||
<Theme>
|
||||
<Router history={history}>
|
||||
<FormModalNavigationProvider>
|
||||
<ListView />
|
||||
</FormModalNavigationProvider>
|
||||
</Router>
|
||||
</Theme>
|
||||
<ThemeToggleProvider themes={{ light: lightTheme }}>
|
||||
<Theme>
|
||||
<Router history={history}>
|
||||
<FormModalNavigationProvider>
|
||||
<ListView />
|
||||
</FormModalNavigationProvider>
|
||||
</Router>
|
||||
</Theme>
|
||||
</ThemeToggleProvider>
|
||||
</LanguageProvider>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
import { isEmpty } from 'lodash';
|
||||
// TODO @soupette we need to refactor this file
|
||||
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
|
||||
const TOKEN_KEY = 'jwtToken';
|
||||
const USER_INFO = 'userInfo';
|
||||
const CURRENT_STEP = 'GUIDED_TOUR_CURRENT_STEP';
|
||||
const COMPLETED_STEPS = 'GUIDED_TOUR_COMPLETED_STEPS';
|
||||
const THEME_KEY = 'STRAPI_THEME'; // Also used in packages/core/admin/admin/src/components/ThemeToggleProvider/index.js
|
||||
|
||||
const parse = JSON.parse;
|
||||
const stringify = JSON.stringify;
|
||||
@ -29,6 +32,7 @@ const auth = {
|
||||
const localeLang = localStorage.getItem('strapi-admin-language');
|
||||
const guidedTourCurrentStep = auth.get(CURRENT_STEP);
|
||||
const guidedTourState = auth.get(COMPLETED_STEPS);
|
||||
const applicationTheme = localStorage.getItem(THEME_KEY);
|
||||
|
||||
localStorage.clear();
|
||||
|
||||
@ -38,6 +42,7 @@ const auth = {
|
||||
localStorage.setItem('strapi-admin-language', localeLang);
|
||||
localStorage.setItem(CURRENT_STEP, stringify(guidedTourCurrentStep));
|
||||
localStorage.setItem(COMPLETED_STEPS, stringify(guidedTourState));
|
||||
localStorage.setItem(THEME_KEY, applicationTheme);
|
||||
}
|
||||
|
||||
if (sessionStorage) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user