mirror of
https://github.com/pgadmin-org/pgadmin4.git
synced 2025-01-12 09:01:57 -06:00
Provide an option to set the theme based on the OS theme. #5932
This commit is contained in:
parent
bdadc77235
commit
6357672387
docs/en_US
web/pgadmin
misc
static
Binary file not shown.
Before (image error) Size: 76 KiB After (image error) Size: 142 KiB |
@ -282,7 +282,8 @@ Expand the *Miscellaneous* node to specify miscellaneous display preferences.
|
||||
* Use the *Themes* drop-down listbox to select the theme for pgAdmin. You'll also get a preview just below the
|
||||
drop down. You can also submit your own themes,
|
||||
check `here <https://github.com/pgadmin-org/pgadmin4/blob/master/README.md>`_ how.
|
||||
Currently we support Standard, Dark and High Contrast theme.
|
||||
Currently we support Standard, Dark and High Contrast and System theme. Selecting System option will follow
|
||||
your computer's settings.
|
||||
|
||||
The Paths Node
|
||||
**************
|
||||
|
@ -20,7 +20,6 @@ from pgadmin.utils import PgAdminModule, replace_binary_path, \
|
||||
from pgadmin.utils.csrf import pgCSRFProtect
|
||||
from pgadmin.utils.session import cleanup_session_files
|
||||
from pgadmin.misc.themes import get_all_themes
|
||||
from pgadmin.utils.constants import MIMETYPE_APP_JS, UTILITIES_ARRAY
|
||||
from pgadmin.utils.ajax import precondition_required, make_json_response, \
|
||||
internal_server_error
|
||||
from pgadmin.utils.heartbeat import log_server_heartbeat, \
|
||||
@ -74,20 +73,21 @@ class MiscModule(PgAdminModule):
|
||||
'preview_src': url_for(
|
||||
'static', filename='js/generated/img/' +
|
||||
theme_data['preview_img']
|
||||
)
|
||||
) if 'preview_img' in theme_data else None
|
||||
})
|
||||
|
||||
self.preference.register(
|
||||
'themes', 'theme',
|
||||
gettext("Theme"), 'options', 'standard',
|
||||
gettext("Theme"), 'options', 'light',
|
||||
category_label=gettext('Themes'),
|
||||
options=theme_options,
|
||||
control_props={
|
||||
'allowClear': False,
|
||||
'creatable': False,
|
||||
},
|
||||
help_str=gettext(
|
||||
'A refresh is required to apply the theme. Above is the '
|
||||
'preview of the theme'
|
||||
'Click the save button to apply the theme. Below is the '
|
||||
'preview of the theme.'
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -5,9 +5,9 @@ from pgadmin.utils.preferences import Preferences
|
||||
|
||||
def get_all_themes():
|
||||
all_themes = {
|
||||
"standard": {
|
||||
"disp_name": "Standard",
|
||||
"preview_img": "standard_preview.png"
|
||||
"light": {
|
||||
"disp_name": "Light",
|
||||
"preview_img": "light_preview.png"
|
||||
},
|
||||
"dark": {
|
||||
"disp_name": "dark",
|
||||
@ -17,5 +17,8 @@ def get_all_themes():
|
||||
"disp_name": "high_contrast",
|
||||
"preview_img": "high_contrast_preview.png"
|
||||
},
|
||||
"system": {
|
||||
"disp_name": "system"
|
||||
},
|
||||
}
|
||||
return all_themes
|
||||
|
Binary file not shown.
Before (image error) Size: 37 KiB After (image error) Size: 54 KiB |
Binary file not shown.
Before (image error) Size: 27 KiB After (image error) Size: 74 KiB |
BIN
web/pgadmin/static/img/light_preview.png
Normal file
BIN
web/pgadmin/static/img/light_preview.png
Normal file
Binary file not shown.
After (image error) Size: 56 KiB |
Binary file not shown.
Before (image error) Size: 20 KiB |
@ -773,10 +773,11 @@ function getFinalTheme(baseTheme) {
|
||||
/* In future, this will be moved to App container */
|
||||
export default function Theme({children}) {
|
||||
const prefStore = usePreferences();
|
||||
const [themeName, setThemeName] = useState(prefStore.getPreferencesForModule('misc')?.theme);
|
||||
const [currentTheme, setCurrentTheme] = useState(prefStore.getPreferencesForModule('misc')?.theme);
|
||||
|
||||
const themeObj = useMemo(()=>{
|
||||
let baseTheme = getStandardTheme(basicSettings);
|
||||
switch(themeName) {
|
||||
switch(currentTheme) {
|
||||
case 'dark':
|
||||
baseTheme = getDarkTheme(baseTheme);
|
||||
break;
|
||||
@ -785,11 +786,20 @@ export default function Theme({children}) {
|
||||
break;
|
||||
}
|
||||
return getFinalTheme(baseTheme);
|
||||
}, [themeName]);
|
||||
}, [currentTheme]);
|
||||
|
||||
useEffect(() => usePreferences.subscribe(
|
||||
state => {
|
||||
setThemeName(state.getPreferencesForModule('misc').theme);
|
||||
let selectdTheme = state.getPreferencesForModule('misc').theme;
|
||||
if(selectdTheme === 'system'){
|
||||
const themeQuery = window.matchMedia('(prefers-color-scheme: light)');
|
||||
setCurrentTheme(themeQuery.matches ? 'light' : 'dark');
|
||||
themeQuery.addEventListener('change', ({ matches }) => {
|
||||
setCurrentTheme(matches ? 'light' : 'dark');
|
||||
});
|
||||
}else{
|
||||
setCurrentTheme(selectdTheme);
|
||||
}
|
||||
}
|
||||
), []);
|
||||
|
||||
|
@ -1211,8 +1211,8 @@ export function FormInputSelectThemes({ hasError, label, className, helpMessage,
|
||||
const cid = _.uniqueId('c');
|
||||
const helpid = `h${cid}`;
|
||||
return (
|
||||
<FormInput label={label} error={hasError} className={className} helpMessage={helpMessage} testcid={testcid} labelTooltip={labelTooltip}>
|
||||
<SelectThemes cid={cid} helpid={helpid} onChange={onChange} {...props} />
|
||||
<FormInput label={label} error={hasError} className={className} testcid={testcid} labelTooltip={labelTooltip}>
|
||||
<SelectThemes cid={cid} helpid={helpid} helpMessage={helpMessage} onChange={onChange} {...props} />
|
||||
</FormInput>
|
||||
);
|
||||
}
|
||||
|
@ -8,24 +8,29 @@
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
import gettext from 'sources/gettext';
|
||||
import { Grid } from '@mui/material';
|
||||
import { Grid, FormHelperText } from '@mui/material';
|
||||
import React, { useMemo } from 'react';
|
||||
import {InputSelect } from './FormComponents';
|
||||
import PropTypes from 'prop-types';
|
||||
import CustomPropTypes from '../custom_prop_types';
|
||||
import HTMLReactParse from 'html-react-parser';
|
||||
|
||||
|
||||
export default function SelectThemes({onChange, ...props}) {
|
||||
export default function SelectThemes({onChange, helpMessage, ...props}) {
|
||||
|
||||
const previewSrc = useMemo(()=>(props.options?.find((o)=>o.value==props.value)?.preview_src), [props.value]);
|
||||
|
||||
const cid = _.uniqueId('c');
|
||||
const helpid = `h${cid}`;
|
||||
return (
|
||||
<Grid container direction="column">
|
||||
<Grid container direction="column" spacing={0.5}>
|
||||
<Grid item lg={12} md={12} sm={12} xs={12}>
|
||||
<InputSelect ref={props.inputRef} onChange={onChange} {...props} />
|
||||
</Grid>
|
||||
<Grid item lg={12} md={12} sm={12} xs={12} sx={{paddingTop: 10}}>
|
||||
<img className='img-fluid mx-auto d-block border' src={previewSrc} alt={gettext('Preview not available...')} />
|
||||
{ previewSrc && <>
|
||||
<FormHelperText id={helpid} variant="outlined">{HTMLReactParse(helpMessage || '')}</FormHelperText>
|
||||
<img className='img-fluid mx-auto d-block border' src={previewSrc} alt={gettext('Preview not available...')} />
|
||||
</> }
|
||||
</Grid>
|
||||
</Grid>
|
||||
);
|
||||
@ -37,5 +42,6 @@ SelectThemes.propTypes = {
|
||||
controlProps: PropTypes.object,
|
||||
fields: PropTypes.array,
|
||||
options: PropTypes.array,
|
||||
inputRef: CustomPropTypes.ref
|
||||
inputRef: CustomPropTypes.ref,
|
||||
helpMessage: PropTypes.string
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user