Skip to content

Commit

Permalink
add theme editor
Browse files Browse the repository at this point in the history
  • Loading branch information
4rthem committed Dec 13, 2023
1 parent 5f4b00a commit 69f0279
Show file tree
Hide file tree
Showing 20 changed files with 307 additions and 85 deletions.
11 changes: 6 additions & 5 deletions databox/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,18 @@
"@alchemy/core": "workspace:*",
"@alchemy/react-auth": "workspace:*",
"@alchemy/react-ps": "workspace:*",
"@alchemy/theme-editor": "workspace:*",
"@alchemy/visual-workflow": "workspace:*",
"@alchemy/react-hooks": "workspace:*",
"@alchemy/navigation": "workspace:*",
"@dnd-kit/core": "^6.0.5",
"@dnd-kit/sortable": "^7.0.1",
"@dnd-kit/utilities": "^3.2.0",
"@emotion/react": "^11.9.0",
"@emotion/styled": "^11.8.1",
"@mui/icons-material": "^5.6.2",
"@mui/lab": "^5.0.0-alpha.80",
"@mui/material": "^5.10.13",
"@emotion/react": "^11.11.1",
"@emotion/styled": "^11.11.0",
"@mui/icons-material": "^5.15.0",
"@mui/lab": "^5.0.0-alpha.156",
"@mui/material": "^5.15.0",
"@toast-ui/react-image-editor": "^3.15.2",
"ace-builds": "^1.14.0",
"axios": "^1.6.2",
Expand Down
14 changes: 9 additions & 5 deletions databox/client/src/components/Layout/ChangeTheme.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,23 +11,27 @@ import {useTranslation} from 'react-i18next';
import themes from '../../themes';
import {ThemeName} from '../../lib/theme';
import {UserPreferencesContext} from '../User/Preferences/UserPreferencesContext';
import {StackedModalProps, useModals} from '@alchemy/navigation';

type Props = {
onClose: () => void;
};
type Props = {} & StackedModalProps;

export default function ChangeTheme({onClose}: Props) {
export default function ChangeTheme({
open,
}: Props) {
const {t} = useTranslation();
const prefContext = useContext(UserPreferencesContext);
const {preferences, updatePreference} = prefContext;
const {closeModal} = useModals();

const handleClick = (name: ThemeName) => {
updatePreference('theme', name);
};

const onClose = () => closeModal();

return (
<>
<Dialog onClose={onClose} open={true}>
<Dialog onClose={onClose} open={open}>
<DialogTitle>
{t('change_theme.title', 'Choose a theme')}
</DialogTitle>
Expand Down
38 changes: 31 additions & 7 deletions databox/client/src/components/Layout/MainAppBar.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as React from 'react';
import {useContext, useState} from 'react';
import {useContext} from 'react';
import AppBar from '@mui/material/AppBar';
import Box from '@mui/material/Box';
import Toolbar from '@mui/material/Toolbar';
Expand All @@ -17,13 +17,16 @@ import LogoutIcon from '@mui/icons-material/Logout';
import {SearchContext} from '../Media/Search/SearchContext';
import ColorLensIcon from '@mui/icons-material/ColorLens';
import AccountBoxIcon from '@mui/icons-material/AccountBox';
import ChangeTheme from './ChangeTheme';
import {zIndex} from '../../themes/zIndex';
import {useKeycloakUrls} from '@alchemy/react-auth';
import {ThemeEditorContext} from '@alchemy/theme-editor';
import config from '../../config.ts';
import {keycloakClient} from '../../api/api-client.ts';
import {useUser} from '../../lib/auth.ts';
import {DashboardMenu} from '@alchemy/react-ps';
import {useModals} from '@alchemy/navigation';
import ChangeTheme from "./ChangeTheme.tsx";
import ThemeEditor from "./ThemeEditor.tsx";

export const menuHeight = 42;

Expand All @@ -34,7 +37,8 @@ type Props = {

export default function MainAppBar({onToggleLeftPanel}: Props) {
const {t} = useTranslation();
const [changeTheme, setChangeTheme] = useState(false);
const {openModal} = useModals();
const themeEditorContext = useContext(ThemeEditorContext);
const userContext = useUser();
const [anchorElUser, setAnchorElUser] = React.useState<null | HTMLElement>(
null
Expand Down Expand Up @@ -70,9 +74,6 @@ export default function MainAppBar({onToggleLeftPanel}: Props) {
}}
position="static"
>
{changeTheme && (
<ChangeTheme onClose={() => setChangeTheme(false)} />
)}
<Container maxWidth={false}>
<Toolbar
disableGutters
Expand Down Expand Up @@ -201,7 +202,7 @@ export default function MainAppBar({onToggleLeftPanel}: Props) {
</MenuItem>
<MenuItem
onClick={() => {
setChangeTheme(true);
openModal(ChangeTheme);
handleCloseUserMenu();
}}
>
Expand All @@ -215,6 +216,29 @@ export default function MainAppBar({onToggleLeftPanel}: Props) {
)}
/>
</MenuItem>
<MenuItem
onClick={() => {
openModal(ThemeEditor, {}, {
forwardedContexts: [
{
context: ThemeEditorContext,
value: themeEditorContext,
}
]
});
handleCloseUserMenu();
}}
>
<ListItemIcon>
<ColorLensIcon />
</ListItemIcon>
<ListItemText
primary={t(
'menu.theme_editor',
'Theme Editor'
)}
/>
</MenuItem>
<Divider light />
<MenuItem
key={'logout'}
Expand Down
24 changes: 24 additions & 0 deletions databox/client/src/components/Layout/ThemeEditor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import AppDialog from "./AppDialog.tsx";
import {StackedModalProps, useModals} from '@alchemy/navigation';
import {MuiThemeEditor} from '@alchemy/theme-editor';

type Props = {} & StackedModalProps;

export default function ThemeEditor({
open,
modalIndex,
}: Props) {
const {closeModal} = useModals();

const onClose= () => closeModal();

return <AppDialog
modalIndex={modalIndex}
open={open}
onClose={onClose}
>
<MuiThemeEditor
onClose={onClose}
/>
</AppDialog>
}
11 changes: 5 additions & 6 deletions databox/client/src/components/Root.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import React from 'react';
import {ModalStack} from '@alchemy/navigation';
import {ModalStack, RouterProvider} from '@alchemy/navigation';
import UserPreferencesProvider from './User/Preferences/UserPreferencesProvider';
import {keycloakClient, oauthClient} from '../api/api-client';
import {AuthenticationProvider, MatomoUser} from '@alchemy/react-auth';
import {RouterProvider} from '@alchemy/navigation';
import {routes} from '../routes.ts';
import RouteProxy from './Routing/RouteProxy.tsx';

Expand All @@ -17,16 +16,16 @@ export default function Root({}: Props) {
return (
<AuthenticationProvider oauthClient={oauthClient} onLogout={onLogout}>
<MatomoUser/>
<ModalStack>
<UserPreferencesProvider>
<UserPreferencesProvider>
<ModalStack>
<RouterProvider
routes={routes}
options={{
RouteProxyComponent: RouteProxy,
}}
/>
</UserPreferencesProvider>
</ModalStack>
</ModalStack>
</UserPreferencesProvider>
</AuthenticationProvider>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ import {
UserPreferencesContext,
} from './UserPreferencesContext';
import {getUserPreferences, putUserPreferences} from '../../../api/user';
import {createCachedTheme} from '../../../lib/theme';
import {CssBaseline, GlobalStyles, ThemeProvider} from '@mui/material';
import {createCachedThemeOptions} from '../../../lib/theme';
import {CssBaseline, GlobalStyles} from '@mui/material';
import {useAuth} from '@alchemy/react-auth';
import {ThemeEditorProvider} from '@alchemy/theme-editor';

const sessionStorageKey = 'userPrefs';

Expand Down Expand Up @@ -77,8 +78,8 @@ export default function UserPreferencesProvider({children}: Props) {

return (
<UserPreferencesContext.Provider value={value}>
<ThemeProvider
theme={createCachedTheme(preferences.theme ?? 'default')}
<ThemeEditorProvider
defaultTheme={createCachedThemeOptions(preferences.theme ?? 'default')}
>
<CssBaseline />
<GlobalStyles
Expand All @@ -101,7 +102,7 @@ export default function UserPreferencesProvider({children}: Props) {
})}
/>
{children}
</ThemeProvider>
</ThemeEditorProvider>
</UserPreferencesContext.Provider>
);
}
11 changes: 4 additions & 7 deletions databox/client/src/lib/theme.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,16 @@
import {Theme, ThemeOptions} from '@mui/material';
import {createTheme} from '@mui/material/styles';
import {ThemeOptions} from '@mui/material';
import {mergeDeep} from './merge';
import baseTheme from '../themes/base';
import themes from '../themes';

const themeCache: Record<string, Theme> = {};
const themeCache: Record<string, ThemeOptions> = {};

export type ThemeName = keyof typeof themes;

export function createCachedTheme(name: ThemeName): Theme {
export function createCachedThemeOptions(name: ThemeName): ThemeOptions {
if (themeCache[name]) {
return themeCache[name];
}

return (themeCache[name] = createTheme(
mergeDeep({}, baseTheme, themes[name]) as ThemeOptions
));
return (themeCache[name] = mergeDeep({}, baseTheme, themes[name]) as ThemeOptions);
}
2 changes: 2 additions & 0 deletions lib/js/core/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import {initSentry, logError} from "./src/sentry";
import {ErrorBoundary} from "@sentry/react";

export {
initSentry,
logError,
ErrorBoundary,
};

export * from './src/types';
1 change: 1 addition & 0 deletions lib/js/navigation/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"dependencies": {
"@remix-run/router": "1.11.0",
"react-router-dom": "6.18.0",
"@alchemy/core": "workspace:*",
"@alchemy/phrasea-ui": "workspace:*"
},
"peerDependencies": {
Expand Down
37 changes: 0 additions & 37 deletions lib/js/navigation/src/DefaultErrorBoundary.tsx

This file was deleted.

24 changes: 14 additions & 10 deletions lib/js/navigation/src/Router.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import {RouteDefinition, RouteParameters, Routes, RouteProxyProps, RouteProxyComponent, ErrorComponent} from "./types";
import {
RouteDefinition,
RouteParameters,
Routes,
RouteProxyProps,
RouteProxyComponent,
TErrorBoundaryComponent, TErrorFallbackComponent,
} from "./types";
import {getFullPath, getLocationPrefix} from "./utils";
import {Outlet, RouteObject} from "react-router-dom";
import React, {PropsWithChildren} from "react";
import DefaultErrorBoundary, {
ErrorFallbackProps, TErrorBoundaryComponent
} from "./DefaultErrorBoundary";
import DefaultRouteProxy from "./proxy/DefaultRouteProxy";
import {DefaultErrorComponent} from "./DefaultErrorComponent";
import {NotFoundPage} from "@alchemy/phrasea-ui";
import {NotFoundPage, ErrorPage} from "@alchemy/phrasea-ui";
import {ErrorBoundary} from "@alchemy/core";


export function compileRoutes(routes: Routes, rootUrl?: string): Routes {
Expand Down Expand Up @@ -113,7 +117,7 @@ export function createRouteComponent(route: RouteDefinition, RouteProxyComponent

export type RouterProviderOptions = {
RouteProxyComponent?: RouteProxyComponent,
ErrorComponent?: ErrorComponent,
ErrorComponent?: TErrorFallbackComponent,
ErrorBoundaryComponent?: TErrorBoundaryComponent,
WrapperComponent?: React.FC<PropsWithChildren<{}>>;
}
Expand All @@ -126,8 +130,8 @@ export function createRouterProviderRoutes(

const {
RouteProxyComponent: RouteProxyComponent = DefaultRouteProxy,
ErrorComponent = DefaultErrorComponent,
ErrorBoundaryComponent = DefaultErrorBoundary,
ErrorComponent = ErrorPage,
ErrorBoundaryComponent = ErrorBoundary,
WrapperComponent
} = options;

Expand Down Expand Up @@ -157,7 +161,7 @@ export function createRouterProviderRoutes(

return [
{
Component: () => <ErrorBoundaryComponent fallback={(props: ErrorFallbackProps) => <ErrorComponent {...props}/>}>
Component: () => <ErrorBoundaryComponent fallback={ErrorComponent}>
{WrapperComponent ? React.createElement(WrapperComponent, {
children: <Outlet />
}) : <Outlet />}
Expand Down
7 changes: 7 additions & 0 deletions lib/js/navigation/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,10 @@ export type RouteParameters = Record<string, string | undefined | null>;

export type RouteProxyComponent = FunctionComponent<RouteProxyProps>;
export type ErrorComponent = ElementType;

export type ErrorFallbackProps = { error: any };
export type TErrorFallbackComponent = (props: ErrorFallbackProps) => React.JSX.Element;

export type TErrorBoundaryComponent = React.JSXElementConstructor<PropsWithChildren<{
fallback: TErrorFallbackComponent;
}>>;
11 changes: 11 additions & 0 deletions lib/js/theme-editor/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import ThemeEditorProvider from "./src/ThemeEditorProvider";
import MuiThemeEditor from "./src/MuiThemeEditor";
import ThemeEditorContext from "./src/ThemeEditorContext";
export {
ThemeEditorProvider,
MuiThemeEditor,
ThemeEditorContext,
};

export * from './src/types';

Loading

0 comments on commit 69f0279

Please sign in to comment.