Workspace Layout Update - Enhanced Query Tool and PSQL Behaviour:

With these changes, the Query Tool and PSQL tabs will now open in the same active workspace where the action is initiated.
pull/8427/head
Akshay Joshi 2025-02-11 15:36:03 +05:30
parent 2c37ff2893
commit eb7c3ef361
7 changed files with 61 additions and 7 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 KiB

After

Width:  |  Height:  |  Size: 280 KiB

View File

@ -286,6 +286,11 @@ Expand the *Miscellaneous* node to specify miscellaneous display preferences.
areas for the Query Tool, PSQL, and Schema Diff tools. 'Workspace' layout is
the default layout, but user can change it to 'Classic'.
* When the *Open the Query Tool/PSQL in their respective workspaces* switch is set to *True*
then all Query Tool/PSQL tabs will open in their respective workspaces. By default,
this setting is False, meaning that Query Tool/PSQL tabs will open in the currently
active workspace (either the default or the workspace selected at the time of opening).
* 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.

View File

@ -105,6 +105,20 @@ class MiscModule(PgAdminModule):
'Diff tools.'
)
)
self.preference.register(
'user_interface', 'open_in_res_workspace',
gettext("Open the Query Tool/PSQL in their respective workspaces"),
'boolean', False,
category_label=PREF_LABEL_USER_INTERFACE,
help_str=gettext(
'This setting applies only when the layout is set to '
'Workspace Layout. When set to True, all Query Tool/PSQL '
'tabs will open in their respective workspaces. By default, '
'this setting is False, meaning that Query Tool/PSQL tabs '
'will open in the currently active workspace (either the '
'default or the workspace selected at the time of opening)'
)
)
def get_exposed_url_endpoints(self):
"""

View File

@ -9,7 +9,7 @@
import React, { useContext, useMemo, useRef, useState } from 'react';
import PropTypes from 'prop-types';
import { WORKSPACES } from '../../../../browser/static/js/constants';
import { BROWSER_PANELS, WORKSPACES } from '../../../../browser/static/js/constants';
import { usePgAdmin } from '../../../../static/js/PgAdminProvider';
import usePreferences from '../../../../preferences/static/js/store';
import { config } from './config';
@ -23,8 +23,11 @@ export function WorkspaceProvider({children}) {
const [currentWorkspace, setCurrentWorkspace] = useState(WORKSPACES.DEFAULT);
const lastSelectedTreeItem = useRef();
const isClassic = (usePreferences()?.getPreferencesForModule('misc')?.layout ?? 'classic') == 'classic';
const openInResWorkspace = usePreferences()?.getPreferencesForModule('misc')?.open_in_res_workspace && !isClassic;
pgAdmin.Browser.docker.currentWorkspace = WORKSPACES.DEFAULT;
if (_.isUndefined(pgAdmin.Browser.docker.currentWorkspace)) {
pgAdmin.Browser.docker.currentWorkspace = WORKSPACES.DEFAULT;
}
/* In case of classic UI all workspace objects should point to the
* the instance of the default layout.
*/
@ -50,6 +53,14 @@ export function WorkspaceProvider({children}) {
workspace = WORKSPACES.DEFAULT;
}
// If the layout is Workspace layout and 'Open the Query Tool/PSQL in their respective workspaces'
// is False then check the current workspace and set the workspace and docker accordingly.
if (!openInResWorkspace && pgAdmin.Browser.docker.currentWorkspace == WORKSPACES.DEFAULT &&
(panelId.indexOf(BROWSER_PANELS.QUERY_TOOL) >= 0 || panelId.indexOf(BROWSER_PANELS.PSQL_TOOL) >= 0)) {
docker = pgAdmin.Browser.docker.default_workspace;
workspace = WORKSPACES.DEFAULT;
}
// Call onWorkspaceChange to enable or disable the menu based on the selected workspace.
changeWorkspace(workspace);
return {docker: docker, focus: ()=>changeWorkspace(workspace)};

View File

@ -299,6 +299,8 @@ export default function PreferencesComponent({ ...props }) {
preferencesValues[element.id] = { 'warning': _val[0], 'alert': _val[1] };
} else if (subNode.label == gettext('Results grid') && node.label == gettext('Query Tool')) {
setResultsOptions(element, subNode, preferencesValues, type);
} else if (subNode.label == gettext('User Interface') && node.label == gettext('Miscellaneous')) {
setWorkspaceOptions(element, subNode, preferencesValues, type);
} else {
element.type = type;
preferencesValues[element.id] = element.value;
@ -329,6 +331,23 @@ export default function PreferencesComponent({ ...props }) {
preferencesValues[element.id] = element.value;
}
function setWorkspaceOptions(element, subNode, preferencesValues, type) {
if (element.name== 'open_in_res_workspace') {
let layout_control_id = null;
subNode.preferences.forEach((_el) => {
if(_el.name == 'layout') {
layout_control_id = _el.id;
}
});
element.disabled = (state) => {
return state[layout_control_id] != 'workspace';
};
}
element.type = type;
preferencesValues[element.id] = element.value;
}
function setThemesOptions(element) {
if (element.name == 'theme') {
element.type = 'theme';

View File

@ -80,16 +80,16 @@ let defaultLayout = {
mode: 'horizontal',
children: [
{
size: 20,
size: 10,
tabs: [
LayoutDocker.getPanel({
id: BROWSER_PANELS.OBJECT_EXPLORER, title: gettext('Object Explorer'),
id: BROWSER_PANELS.OBJECT_EXPLORER, title: gettext(''),
content: <ObjectExplorer />, group: 'object-explorer'
}),
],
},
{
size: 80,
size: 90,
id: BROWSER_PANELS.MAIN,
group: 'playground',
tabs: defaultTabsData.map((t)=>LayoutDocker.getPanel(t)),

View File

@ -23,7 +23,7 @@ import ReactDOM from 'react-dom/client';
import QueryToolComponent from './components/QueryToolComponent';
import ModalProvider from '../../../../static/js/helpers/ModalProvider';
import Theme from '../../../../static/js/Theme';
import { BROWSER_PANELS } from '../../../../browser/static/js/constants';
import { BROWSER_PANELS, WORKSPACES } from '../../../../browser/static/js/constants';
import { NotifierProvider } from '../../../../static/js/helpers/Notifier';
import usePreferences, { listenPreferenceBroadcast } from '../../../../preferences/static/js/store';
import { PgAdminProvider } from '../../../../static/js/PgAdminProvider';
@ -229,6 +229,11 @@ export default class SQLEditor {
}
async loadComponent(container, params) {
let panelDocker = pgWindow.pgAdmin.Browser.docker.query_tool_workspace;
if (pgWindow.pgAdmin.Browser.docker.currentWorkspace == WORKSPACES.DEFAULT) {
panelDocker = pgWindow.pgAdmin.Browser.docker.default_workspace;
}
const selectedNodeInfo = params.selectedNodeInfo ? JSON.parse(_.unescape(params.selectedNodeInfo)) : params.selectedNodeInfo;
pgAdmin.Browser.keyboardNavigation.init();
await listenPreferenceBroadcast();
@ -238,7 +243,7 @@ export default class SQLEditor {
<PgAdminProvider value={pgAdmin}>
<ModalProvider>
<NotifierProvider pgAdmin={pgAdmin} pgWindow={pgWindow} />
<QueryToolComponent params={params} pgWindow={pgWindow} pgAdmin={pgAdmin} qtPanelDocker={pgWindow.pgAdmin.Browser.docker.query_tool_workspace}
<QueryToolComponent params={params} pgWindow={pgWindow} pgAdmin={pgAdmin} qtPanelDocker={panelDocker}
qtPanelId={`${BROWSER_PANELS.QUERY_TOOL}_${params.trans_id}`} selectedNodeInfo={selectedNodeInfo}/>
</ModalProvider>
</PgAdminProvider>