Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions web/pgadmin/settings/static/ApplicationStateProvider.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,16 +71,16 @@ export function ApplicationStateProvider({children}){
if(connectionInfo.is_editor_dirty){
if(connectionInfo.external_file_changes){
// file has external chages
return {loadFile: loadFile, fileName: fileName, data: toolContent, modifiedExternally: true};
return {loadFile: loadFile, fileName: fileName, data: toolContent, modifiedExternally: true, connectionInfo: connectionInfo};
}
}else if(connectionInfo.file_deleted){
return {loadFile: loadFile, fileName: null, data: toolContent};
return {loadFile: loadFile, fileName: null, data: toolContent, connectionInfo: connectionInfo};
}else{
loadFile = true;
return {loadFile: loadFile, fileName: fileName, data: null};
return {loadFile: loadFile, fileName: fileName, data: null, connectionInfo: connectionInfo};
}
}
return {loadFile: loadFile, fileName: fileName, data: toolContent};
return {loadFile: loadFile, fileName: fileName, data: toolContent, connectionInfo: connectionInfo};

} catch (error) {
let errorMsg = gettext(error?.response?.data?.errormsg || error);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,30 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
const restoreToolContent = async () =>{
let toolContent = await getToolContent(qtState.params.trans_id);
if(toolContent){
const connList = toolContent.connectionInfo?.connection_list;
if (Array.isArray(connList) && connList.length > 0) {
// ensure exactly one is_selected
if (!connList.some(c => c.is_selected)) {
connList[0].is_selected = true;
}
// pick selected connection to update params (so UI shows correct selected conn)
const sel = connList.find(c => c.is_selected) || connList[0];

setQtStatePartial(prev => ({
...prev,
connection_list: connList,
params: {
...prev.params,
sid: sel.sid,
did: sel.did,
user: sel.user,
role: sel.role,
server_name: sel.server_name,
database_name: sel.database_name,
title: sel.title,
},
}));
Comment on lines +317 to +330
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Search for sgid, fgcolor, bgcolor usage in params context
echo "=== Searching for sgid, fgcolor, bgcolor in params ==="
rg -n --type=js -i 'params\.(sgid|fgcolor|bgcolor)' web/pgadmin/tools/sqleditor/

echo -e "\n=== Searching for these fields in connection objects ==="
rg -n --type=js '(sgid|fgcolor|bgcolor)' web/pgadmin/tools/sqleditor/ | grep -v node_modules | head -20

Repository: pgadmin-org/pgadmin4

Length of output: 3094


🏁 Script executed:

#!/bin/bash
# Get the actual code context around lines 317-330
echo "=== Code at lines 317-330 in QueryToolComponent.jsx ==="
sed -n '310,340p' web/pgadmin/tools/sqleditor/static/js/components/QueryToolComponent.jsx

echo -e "\n=== Initial state context (lines 140-165) ==="
sed -n '140,165p' web/pgadmin/tools/sqleditor/static/js/components/QueryToolComponent.jsx

Repository: pgadmin-org/pgadmin4

Length of output: 2507


Restore missing connection parameters during user/role updates.

When updating params after a user/role change, the restoration at lines 322-328 omits sgid, fgcolor, and bgcolor that are present in the connection state. The sgid field is used for connection matching (line 922), and fgcolor/bgcolor are used for UI styling (ConnectionBar.jsx). Include these fields in the params update to maintain connection identification and visual consistency.

🤖 Prompt for AI Agents
In web/pgadmin/tools/sqleditor/static/js/components/QueryToolComponent.jsx
around lines 317 to 330, the params update after selecting a connection restores
several fields but omits sgid, fgcolor, and bgcolor which are needed for
connection matching and UI styling; update the params object to also copy
sel.sgid, sel.fgcolor, and sel.bgcolor (e.g., add sgid: sel.sgid, fgcolor:
sel.fgcolor, bgcolor: sel.bgcolor) so the connection identification and visual
appearance are preserved when user/role changes occur.

}
if (toolContent?.modifiedExternally) {
toolContent = await fmUtilsObj.warnFileReload(toolContent?.fileName, toolContent.data, '');
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ export default function Query({onTextSelect, setQtStatePartial}) {
const preferencesStore = usePreferences();
const modalId = MODAL_DIALOGS.QT_CONFIRMATIONS;
const fmUtilsObj = useMemo(()=>new FileManagerUtils(queryToolCtx.api, {}), []);
const initialTransIdRef = React.useRef(queryToolCtx.params.trans_id);

const highlightError = (cmObj, {errormsg: result, data}, executeCursor)=>{
let errorLineNo = 0,
Expand Down Expand Up @@ -363,8 +364,9 @@ export default function Query({onTextSelect, setQtStatePartial}) {

const change = useCallback(()=>{
eventBus.fireEvent(QUERY_TOOL_EVENTS.QUERY_CHANGED, editor.current.isDirty());

if(isSaveToolDataEnabled('sqleditor') && editor.current.isDirty()){
const value = editor.current.getValue() || '';
const isDirty = editor.current.isDirty();
if(isSaveToolDataEnabled('sqleditor') && (isDirty || value.length === 0)){
eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_SAVE_QUERY_TOOL_DATA);
}

Expand All @@ -379,10 +381,18 @@ export default function Query({onTextSelect, setQtStatePartial}) {


const [saveQtData, setSaveQtData] = useState(false);
useDelayDebounce(()=>{
let connectionInfo = { ..._.find(queryToolCtx.connection_list, c => c.is_selected),
'open_file_name':queryToolCtx.current_file, 'is_editor_dirty': editor.current.isDirty() };
saveToolData('sqleditor', connectionInfo, queryToolCtx.params.trans_id, editor.current.getValue());

useDelayDebounce(() => {
const currentTransId = initialTransIdRef.current || queryToolCtx.params.trans_id;
const currentConnList = queryToolCtx.connection_list;
const currentFile = queryToolCtx.current_file;

let connectionInfo = {
connection_list: currentConnList,
open_file_name: currentFile,
is_editor_dirty: editor.current.isDirty()
};
saveToolData('sqleditor', connectionInfo, currentTransId, editor.current.getValue());
setSaveQtData(false);
}, saveQtData, 500);
Comment on lines +384 to 397
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Add null guard for editor reference in debounced save.

The debounced callback accesses editor.current without null checks. If the component unmounts or the editor hasn't initialized when the debounce fires, this could throw.

  useDelayDebounce(() => {
+   if (!editor.current) {
+     setSaveQtData(false);
+     return;
+   }
    const currentTransId = initialTransIdRef.current || queryToolCtx.params.trans_id;
    const currentConnList = queryToolCtx.connection_list;
    const currentFile = queryToolCtx.current_file;

    let connectionInfo = {
      connection_list: currentConnList,
      open_file_name: currentFile,
      is_editor_dirty: editor.current.isDirty()
    };
    saveToolData('sqleditor', connectionInfo, currentTransId, editor.current.getValue());
    setSaveQtData(false);
  }, saveQtData, 500);
🤖 Prompt for AI Agents
In web/pgadmin/tools/sqleditor/static/js/components/sections/Query.jsx around
lines 384 to 397, the debounced callback dereferences editor.current without
null checks which can throw if the component unmounts or the editor isn't
initialized; add a null guard at the start of the callback (e.g. if (!editor ||
!editor.current) return or skip editor-dependent fields) and only call
editor.current.isDirty() and editor.current.getValue() when editor.current is
present, ensuring saveToolData still receives safe values (or bail out early)
and setSaveQtData(false) is handled appropriately.


Expand Down
Loading