Use 'Drop' instead of 'Delete' for object commands to make destructive actions more deliberate. #8958

pull/8965/head
Akshay Joshi 2025-07-16 18:02:24 +05:30 committed by GitHub
parent 770a0f27af
commit d26b63fdf5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 38 additions and 35 deletions

View File

@ -63,11 +63,11 @@ following options (in alphabetical order):
| *Create* | Click *Create* to access a context menu that provides context-sensitive selections. |
| | Your selection opens a *Create* dialog for creating a new object. |
+-----------------------------+--------------------------------------------------------------------------------------------------------------------------+
| *Delete* | Click to delete the currently selected object from the server. |
| *Drop* | Click to drop the currently selected object from the server. |
+-----------------------------+--------------------------------------------------------------------------------------------------------------------------+
| *Delete (Cascade)* | Click to delete the currently selected object and all dependent objects from the server. |
| *Drop (Cascade)* | Click to drop the currently selected object and all dependent objects from the server. |
+-----------------------------+--------------------------------------------------------------------------------------------------------------------------+
| *Delete (Force)* | Click to delete the currently selected database with force option. |
| *Drop (Force)* | Click to drop the currently selected database with force option. |
+-----------------------------+--------------------------------------------------------------------------------------------------------------------------+
| *Disconnect from server* | Click to disconnect from the currently selected server. |
+-----------------------------+--------------------------------------------------------------------------------------------------------------------------+

View File

@ -20,6 +20,7 @@ Bundled PostgreSQL Utilities
New features
************
| `Issue #1923 <https://github.com/pgadmin-org/pgadmin4/issues/1923>`_ - Ensure that keyboard shortcuts are displayed in tooltips, context menus, and the main menu.
| `Issue #5797 <https://github.com/pgadmin-org/pgadmin4/issues/5797>`_ - Implemented a server-side cursor to enhance performance when retrieving large datasets.
| `Issue #7979 <https://github.com/pgadmin-org/pgadmin4/issues/7979>`_ - Added support for setting a custom SESSION_DIGEST_METHOD in pgAdmin 4 to facilitate FIPS compliance.
| `Issue #8941 <https://github.com/pgadmin-org/pgadmin4/issues/8941>`_ - Enable the PKCE workflow for OAuth 2 authentication.
@ -28,6 +29,7 @@ Housekeeping
************
| `Issue #8828 <https://github.com/pgadmin-org/pgadmin4/issues/8828>`_ - Ensure that pgAdmin 4 is compatible with PG/EPAS v18.
| `Issue #8958 <https://github.com/pgadmin-org/pgadmin4/issues/8958>`_ - Use 'Drop' instead of 'Delete' for object commands to make destructive actions more deliberate.
Bug fixes
*********
@ -35,4 +37,5 @@ Bug fixes
| `Issue #8420 <https://github.com/pgadmin-org/pgadmin4/issues/8420>`_ - Fixed an issue where windows installer is not signing tmp files generated by InnoSetup.
| `Issue #8675 <https://github.com/pgadmin-org/pgadmin4/issues/8675>`_ - Fixed an issue in the Search Objects tool where selecting a node occasionally selected an incorrect node.
| `Issue #8901 <https://github.com/pgadmin-org/pgadmin4/issues/8901>`_ - Improved the application state restoration by leveraging rc-dock layout and ensure the order and layout of tabs is maintained on restore.
| `Issue #8907 <https://github.com/pgadmin-org/pgadmin4/issues/8907>`_ - Fixed an issue where json editor in result grid was crashing if null value is set in the json editor.
| `Issue #8914 <https://github.com/pgadmin-org/pgadmin4/issues/8914>`_ - Update zstd library link to 1.5.7 in Dockerfile.

View File

@ -49,11 +49,11 @@ following selections (options appear in alphabetical order):
+---------------------------+---------------------------------------------------------------------------------------------------------------------------+
| *Debugging* | Click through to open the :ref:`Debug <debugger>` tool or to select *Set breakpoint* to stop or pause a script execution. |
+---------------------------+---------------------------------------------------------------------------------------------------------------------------+
| *Delete* | Click to delete the currently selected object from the server. |
| *Drop* | Click to drop the currently selected object from the server. |
+---------------------------+---------------------------------------------------------------------------------------------------------------------------+
| *Delete (Cascade)* | Click to delete the currently selected object and all dependent objects from the server. |
| *Drop (Cascade)* | Click to drop the currently selected object and all dependent objects from the server. |
+---------------------------+---------------------------------------------------------------------------------------------------------------------------+
| *Delete (Force)* | Click to delete the currently selected database with force option. |
| *Drop (Force)* | Click to drop the currently selected database with force option. |
+---------------------------+---------------------------------------------------------------------------------------------------------------------------+
| *Disconnect Database...* | Click to terminate a database connection. |
+---------------------------+---------------------------------------------------------------------------------------------------------------------------+

View File

@ -325,7 +325,7 @@ def register_browser_preferences(self):
self.preference.register(
'keyboard_shortcuts',
'sub_menu_delete',
gettext('Delete object'),
gettext('Drop object'),
'keyboardshortcut',
{
'alt': True,

View File

@ -103,7 +103,7 @@ define('pgadmin.node.database', [
},{
name: 'delete_database_force', node: 'database', module: this,
applies: ['object', 'context'], callback: 'delete_database_force',
category: 'delete', priority: 2, label: gettext('Delete (Force)'),
category: 'delete', priority: 2, label: gettext('Drop (Force)'),
enable : canDeleteWithForce,
}, {
name: 'disconnect_database', node: 'database', module: this,

View File

@ -155,7 +155,7 @@ define('pgadmin.browser.node', [
applies: ['object', 'context'],
callback: 'delete_obj',
priority: self.dropPriority,
label: (self.dropAsRemove) ? gettext('Remove %s', self.label) : gettext('Delete'),
label: (self.dropAsRemove) ? gettext('Remove %s', self.label) : gettext('Drop'),
data: {
'url': 'drop',
data_disabled: gettext('The selected tree node does not support this option.'),
@ -176,7 +176,7 @@ define('pgadmin.browser.node', [
applies: ['object', 'context'],
callback: 'delete_obj',
priority: 2,
label: gettext('Delete (Cascade)'),
label: gettext('Drop (Cascade)'),
data: {
'url': 'delete',
},
@ -532,13 +532,13 @@ define('pgadmin.browser.node', [
let msg, title;
if (input.url == 'delete' && d._type === 'database') {
msg = gettext('Delete database with the force option will attempt to terminate all existing connections to the <b>"%s"</b> database. Are you sure you want to proceed?', d.label);
title = gettext('Delete FORCE %s?', obj.label);
msg = gettext('Drop database with the force option will attempt to terminate all existing connections to the <b>"%s"</b> database. Are you sure you want to proceed?', d.label);
title = gettext('Drop FORCE %s?', obj.label);
} else if (input.url == 'delete') {
msg = gettext('Are you sure you want to delete the %s <b>"%s"</b> and all the objects that depend on it?',
msg = gettext('Are you sure you want to drop the %s <b>"%s"</b> and all the objects that depend on it?',
obj.label.toLowerCase(), d.label);
title = gettext('Delete CASCADE %s?', obj.label);
title = gettext('Drop CASCADE %s?', obj.label);
if (!(_.isFunction(obj.canDropCascade) ?
obj.canDropCascade(d, i) : obj.canDropCascade)) {
@ -553,8 +553,8 @@ define('pgadmin.browser.node', [
msg = gettext('Are you sure you want to remove the %s <b>"%s"</b>?', obj.label.toLowerCase(), d.label);
title = gettext('Remove %s?', obj.label);
} else {
msg = gettext('Are you sure you want to delete the %s <b>"%s"</b>?', obj.label.toLowerCase(), d.label);
title = gettext('Delete %s?', obj.label);
msg = gettext('Are you sure you want to drop the %s <b>"%s"</b>?', obj.label.toLowerCase(), d.label);
title = gettext('Drop %s?', obj.label);
}
if (!(_.isFunction(obj.canDrop) ?
@ -605,7 +605,7 @@ define('pgadmin.browser.node', [
});
},
() => {},
gettext('Delete'),
obj.dropAsRemove ? gettext('Remove') : gettext('Drop'),
gettext('Cancel'),
);
},
@ -735,7 +735,7 @@ define('pgadmin.browser.node', [
}, 0);
}
pgBrowser.Node.callbacks.change_server_background(item, data);
// Suppress added tree event being called during object search operations
// Suppress added tree event being called during object search operations
// where tree.select clashes due to previous tree state restore
const suppressPath = pgBrowser.tree.suppressEventsForPath;
if (suppressPath) {
@ -745,7 +745,7 @@ define('pgadmin.browser.node', [
return;
}
}
pgBrowser.Events.trigger('pgadmin:browser:tree:expand-from-previous-tree-state', item);
},
// Callback called - when a node is selected in browser tree.
@ -792,7 +792,7 @@ define('pgadmin.browser.node', [
opened: function(item) {
let tree = pgBrowser.tree,
auto_expand = usePreferences.getState().getPreferences('browser', 'auto_expand_sole_children');
// Suppress opened tree event being called during object search operations
// Suppress opened tree event being called during object search operations
// where tree.select clashes due to only child of parent opens automatically.
const suppressPath = pgBrowser.tree.suppressEventsForPath;
if (suppressPath) {

View File

@ -47,7 +47,7 @@ function CustomHeader({node, nodeData, nodeItem, treeNodeInfo, selectedObject, o
<PgIconButton
icon={<DeleteIcon style={{height: '1.35rem'}}/>}
aria-label="Delete"
title={gettext('Delete')}
title={gettext('Drop')}
onClick={() => {
onDrop('drop');
}}
@ -59,8 +59,8 @@ function CustomHeader({node, nodeData, nodeItem, treeNodeInfo, selectedObject, o
></PgIconButton>
{node.type !== 'coll-database' ? <PgIconButton
icon={<DeleteSweepIcon style={{height: '1.5rem'}} />}
aria-label="Delete Cascade"
title={gettext('Delete (Cascade)')}
aria-label="Drop Cascade"
title={gettext('Drop (Cascade)')}
onClick={() => {
onDrop('dropCascade');
}}
@ -72,8 +72,8 @@ function CustomHeader({node, nodeData, nodeItem, treeNodeInfo, selectedObject, o
></PgIconButton> :
<PgIconButton
icon={<DeleteForeverIcon style={{height: '1.4rem'}} />}
aria-label="Delete Force"
title={gettext('Delete (Force)')}
aria-label="Drop Force"
title={gettext('Drop (Force)')}
onClick={() => {
onDrop('dropForce');
}}
@ -144,8 +144,8 @@ export default function CollectionNodeProperties({
if (selRows.length === 0) {
pgAdmin.Browser.notifier.alert(
gettext('Delete Multiple'),
gettext('Please select at least one object to delete.')
gettext('Drop Multiple'),
gettext('Please select at least one object to drop.')
);
return;
}
@ -155,19 +155,19 @@ export default function CollectionNodeProperties({
if (type === 'dropCascade') {
url = selNode.generate_url(selItem, 'delete');
msg = gettext(
'Are you sure you want to delete all the selected objects and all the objects that depend on them?'
'Are you sure you want to drop all the selected objects and all the objects that depend on them?'
);
title = gettext('Delete CASCADE multiple objects?');
title = gettext('Drop CASCADE multiple objects?');
} else if (type === 'dropForce') {
url = selNode.generate_url(selItem, 'delete');
msg = gettext(
'Delete databases with the force option will attempt to terminate all the existing connections to the selected databases. Are you sure you want to proceed?'
'Drop databases with the force option will attempt to terminate all the existing connections to the selected databases. Are you sure you want to proceed?'
);
title = gettext('Delete FORCE multiple objects?');
title = gettext('Drop FORCE multiple objects?');
} else {
url = selNode.generate_url(selItem, 'drop');
msg = gettext('Are you sure you want to delete all the selected objects?');
title = gettext('Delete multiple objects?');
msg = gettext('Are you sure you want to drop all the selected objects?');
title = gettext('Drop multiple objects?');
}
const api = getApiInstance();
@ -198,7 +198,7 @@ export default function CollectionNodeProperties({
};
if (confirm) {
pgAdmin.Browser.notifier.confirmDelete(title, msg, dropNodeProperties, () => {}, gettext('Delete'), gettext('Cancel'));
pgAdmin.Browser.notifier.confirmDelete(title, msg, dropNodeProperties, () => {}, gettext('Drop'), gettext('Cancel'));
} else {
dropNodeProperties();
}

View File

@ -366,7 +366,7 @@ class PgadminPage:
self.click_element(self.find_by_css_selector(
"li[data-label='Remove Server']"))
self.driver.switch_to.default_content()
self.click_modal('Delete')
self.click_modal('Remove')
time.sleep(1)
else:
print(server_config['name'] + " server is not removed",