Added feature to restore preferences to their default values. #1900

This commit is contained in:
Pravesh Sharma 2024-08-30 12:24:24 +05:30 committed by GitHub
parent 445e89576b
commit f88ca891fa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
35 changed files with 118 additions and 9 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 116 KiB

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 KiB

After

Width:  |  Height:  |  Size: 191 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 185 KiB

After

Width:  |  Height:  |  Size: 190 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 91 KiB

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 98 KiB

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 217 KiB

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 160 KiB

After

Width:  |  Height:  |  Size: 166 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 171 KiB

After

Width:  |  Height:  |  Size: 178 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 178 KiB

After

Width:  |  Height:  |  Size: 188 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 132 KiB

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 148 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 104 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 236 KiB

After

Width:  |  Height:  |  Size: 245 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 102 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

After

Width:  |  Height:  |  Size: 162 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 126 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 123 KiB

After

Width:  |  Height:  |  Size: 131 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 186 KiB

After

Width:  |  Height:  |  Size: 193 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 93 KiB

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 181 KiB

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 169 KiB

After

Width:  |  Height:  |  Size: 182 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 190 KiB

After

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

After

Width:  |  Height:  |  Size: 94 KiB

View File

@ -11,9 +11,7 @@ The left pane of the *Preferences* dialog displays a tree control; each node of
the tree control provides access to options that are related to the node under
which they are displayed.
* Use the plus sign (+) to the left of a node name to expand a segment of the
tree control.
* Use the minus sign (-) to the left of a node name to close that node.
* Click the *Reset all preferences* button to restore all preferences to their default values.
The Browser Node
****************

View File

@ -320,3 +320,17 @@ def update():
data={'data': 'Success'},
status=200
)
@blueprint.route("/", methods=['DELETE'], endpoint="reset_prefs")
@pga_login_required
def reset():
"""
Reset preferences to default
"""
res, msg = Preferences.reset()
if not res:
return internal_server_error(errormsg=msg)
return success_return()

View File

@ -20,6 +20,7 @@ import getApiInstance from '../../../../static/js/api_instance';
import CloseSharpIcon from '@mui/icons-material/CloseSharp';
import HelpIcon from '@mui/icons-material/HelpRounded';
import SaveSharpIcon from '@mui/icons-material/SaveSharp';
import SettingsBackupRestoreIcon from'@mui/icons-material/SettingsBackupRestore';
import pgAdmin from 'sources/pgadmin';
import { DefaultButton, PgIconButton, PrimaryButton } from '../../../../static/js/components/Buttons';
import BaseUISchema from 'sources/SchemaView/base_schema.ui';
@ -589,6 +590,64 @@ export default function PreferencesComponent({ ...props }) {
window.open(url_for('help.static', { 'filename': 'preferences.html' }), 'pgadmin_help');
};
const reset = () => {
pgAdmin.Browser.notifier.confirm(
gettext('Reset all preferences'),
`${gettext('All preferences will be reset to their default values.')}<br><br>${gettext('Do you want to proceed?')}<br><br>
${gettext('Note:')}<br> <ul style="padding-left:20px"><li style="list-style-type:disc">${gettext('The object explorer tree will be refreshed automatically to reflect the changes.')}</li>
<li style="list-style-type:disc">${gettext('If the application language changes, a reload of the application will be required. You can choose to reload later at your convenience.')}</li></ul>`,
function () {},
function () {},
'',
'Cancel',
function (closeModal) {
return [
{
type: 'default',
icon: <SaveSharpIcon />,
label: gettext('Save & Reload'),
onclick: () => {
resetPrefsToDefault(true);
closeModal();
}
}, {
type: 'primary',
icon: <SaveSharpIcon />,
label: gettext('Save & Reload Later'),
onclick: () => {
resetPrefsToDefault(false);
closeModal();
}
}
];
}
);
};
const resetPrefsToDefault = (refresh = false) => {
api({
url: url_for('preferences.index'),
method: 'DELETE'
}).then(()=>{
if (refresh){
location.reload();
return true;
}
preferencesStore.cache();
pgAdmin.Browser.tree.destroy().then(
() => {
pgAdmin.Browser.Events.trigger(
'pgadmin-browser:tree:destroyed', undefined, undefined
);
return true;
}
);
props.closeModal();
}).catch((err) => {
pgAdmin.Browser.notifier.alert(err.response.data);
});
};
return (
<StyledBox height={'100%'}>
<Box className='PreferencesComponent-root'>
@ -615,6 +674,9 @@ export default function PreferencesComponent({ ...props }) {
<PgIconButton data-test="dialog-help" onClick={onDialogHelp} icon={<HelpIcon />} title={gettext('Help for this dialog.')} />
</Box>
<Box className='PreferencesComponent-actionBtn' marginLeft="auto">
<DefaultButton className='PreferencesComponent-buttonMargin' onClick={reset} startIcon={<SettingsBackupRestoreIcon />}>
{gettext('Reset all preferences')}
</DefaultButton>
<DefaultButton className='PreferencesComponent-buttonMargin' onClick={() => { props.closeModal();}} startIcon={<CloseSharpIcon onClick={() => { props.closeModal();}} />}>
{gettext('Cancel')}
</DefaultButton>

View File

@ -41,7 +41,18 @@ export function useModal() {
return React.useContext(ModalContext);
}
function AlertContent({ text, confirm, okLabel = gettext('OK'), cancelLabel = gettext('Cancel'), onOkClick, onCancelClick }) {
function renderExtraButtons(button) {
switch(button.type) {
case 'primary':
return <PrimaryButton className='Alert-margin' startIcon={button.icon} onClick={button.onclick}>{button.label}</PrimaryButton>;
case 'default':
return <DefaultButton className='Alert-margin' startIcon={button.icon} onClick={button.onclick}>{button.label}</DefaultButton>;
default:
return <DefaultButton className='Alert-margin' startIcon={button.icon} onClick={button.onclick}>{button.label}</DefaultButton>;
};
}
function AlertContent({ text, confirm, okLabel = gettext('OK'), cancelLabel = gettext('Cancel'), onOkClick, onCancelClick, extraButtons }) {
return (
<StyledBox display="flex" flexDirection="column" height="100%">
<Box flexGrow="1" p={2}>{typeof (text) == 'string' ? HTMLReactParser(text) : text}</Box>
@ -49,7 +60,12 @@ function AlertContent({ text, confirm, okLabel = gettext('OK'), cancelLabel = ge
{confirm &&
<DefaultButton startIcon={<CloseIcon />} onClick={onCancelClick} >{cancelLabel}</DefaultButton>
}
<PrimaryButton className='Alert-margin' startIcon={<CheckRoundedIcon />} onClick={onOkClick} autoFocus={true} >{okLabel}</PrimaryButton>
{
extraButtons?.length ?
extraButtons.map(button=>renderExtraButtons(button))
:
<PrimaryButton className='Alert-margin' startIcon={<CheckRoundedIcon />} onClick={onOkClick} autoFocus={true} >{okLabel}</PrimaryButton>
}
</Box>
</StyledBox>
);
@ -61,6 +77,7 @@ AlertContent.propTypes = {
onCancelClick: PropTypes.func,
okLabel: PropTypes.string,
cancelLabel: PropTypes.string,
extraButtons: PropTypes.array
};
function alert(title, text, onOkClick, okLabel = gettext('OK')) {
@ -76,7 +93,7 @@ function alert(title, text, onOkClick, okLabel = gettext('OK')) {
});
}
function confirm(title, text, onOkClick, onCancelClick, okLabel = gettext('Yes'), cancelLabel = gettext('No')) {
function confirm(title, text, onOkClick, onCancelClick, okLabel = gettext('Yes'), cancelLabel = gettext('No'), extras = null) {
// bind the modal provider before calling
this.showModal(title, (closeModal) => {
const onCancelClickClose = () => {
@ -87,8 +104,9 @@ function confirm(title, text, onOkClick, onCancelClick, okLabel = gettext('Yes')
onOkClick?.();
closeModal();
};
const extraButtons = extras?.(closeModal);
return (
<AlertContent text={text} confirm onOkClick={onOkClickClose} onCancelClick={onCancelClickClose} okLabel={okLabel} cancelLabel={cancelLabel} />
<AlertContent text={text} confirm onOkClick={onOkClickClose} onCancelClick={onCancelClickClose} okLabel={okLabel} cancelLabel={cancelLabel} extraButtons={extraButtons} />
);
});
}

View File

@ -175,10 +175,10 @@ class Notifier {
this.modal.alert(title, text, onOkClick, okLabel);
}
confirm(title, text, onOkClick, onCancelClick, okLabel=gettext('Yes'), cancelLabel=gettext('No')) {
confirm(title, text, onOkClick, onCancelClick, okLabel=gettext('Yes'), cancelLabel=gettext('No'), extras=null) {
/* Use this if you want to use pgAdmin global notifier.
Or else, if you want to use modal inside iframe only then use ModalProvider eg- query tool */
this.modal.confirm(title, text, onOkClick, onCancelClick, okLabel, cancelLabel);
this.modal.confirm(title, text, onOkClick, onCancelClick, okLabel, cancelLabel, extras);
}
showModal(title, content, modalOptions) {

View File

@ -694,3 +694,20 @@ class Preferences():
pref.value = converter_func(pref.value)
db.session.commit()
@classmethod
def reset(cls):
"""
reset
Reset the preferences for the current user in the configuration table.
"""
try:
db.session.query(UserPrefTable).filter(
UserPrefTable.uid == current_user.id).delete()
db.session.commit()
except Exception as e:
db.session.rollback()
current_app.logger.exception(e)
return False, str(e)
return True, None