Ensure that restored query tool tabs display the correct title. #3319
parent
5df2c7686c
commit
f07eabedbe
|
|
@ -16,7 +16,6 @@ import getApiInstance, {parseApiError} from '../../../static/js/api_instance';
|
|||
import usePreferences, { setupPreferenceBroadcast } from '../../../preferences/static/js/store';
|
||||
import checkNodeVisibility from '../../../static/js/check_node_visibility';
|
||||
import * as showQueryTool from '../../../tools/sqleditor/static/js/show_query_tool';
|
||||
import {getRandomInt} from 'sources/utils';
|
||||
|
||||
define('pgadmin.browser', [
|
||||
'sources/gettext', 'sources/url_for', 'sources/pgadmin',
|
||||
|
|
@ -304,30 +303,35 @@ define('pgadmin.browser', [
|
|||
url_for('settings.get_application_state')
|
||||
).then((res)=> {
|
||||
if(res.data.success && res.data.data.result.length > 0){
|
||||
let deleteToolDataIds = [];
|
||||
_.each(res.data.data.result, function(toolState){
|
||||
let toolNme = toolState.tool_name;
|
||||
let toolDataId = `${toolNme}-${getRandomInt(1, 9999999)}`;
|
||||
let toolDataId = `${toolNme}-${toolState.id}`;
|
||||
let connectionInfo = toolState.connection_info;
|
||||
localStorage.setItem(toolDataId, toolState.tool_data);
|
||||
|
||||
|
||||
if (toolNme == 'sqleditor'){
|
||||
showQueryTool.relaunchSqlTool(connectionInfo, toolDataId);
|
||||
}else if(toolNme == 'psql'){
|
||||
pgAdmin.Tools.Psql.openPsqlTool(null, null, connectionInfo);
|
||||
}else if(toolNme == 'ERD'){
|
||||
pgAdmin.Tools.ERD.showErdTool(null, null, false, connectionInfo, toolDataId);
|
||||
}else if(toolNme == 'schema_diff'){
|
||||
pgAdmin.Tools.SchemaDiff.launchSchemaDiff(toolDataId);
|
||||
}else{
|
||||
localStorage.setItem(toolDataId, toolState.tool_data);
|
||||
deleteToolDataIds.push(toolState.id);
|
||||
if(toolNme == 'psql'){
|
||||
pgAdmin.Tools.Psql.openPsqlTool(null, null, connectionInfo);
|
||||
}else if(toolNme == 'ERD'){
|
||||
pgAdmin.Tools.ERD.showErdTool(null, null, false, connectionInfo, toolDataId);
|
||||
}else if(toolNme == 'schema_diff'){
|
||||
pgAdmin.Tools.SchemaDiff.launchSchemaDiff(toolDataId);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// call clear application state data.
|
||||
try {
|
||||
getApiInstance().delete(url_for('settings.delete_application_state'), {});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
pgAdmin.Browser.notifier.error(gettext('Failed to remove query data.') + parseApiError(error));
|
||||
}
|
||||
if(deleteToolDataIds.length > 0){
|
||||
try {
|
||||
getApiInstance().delete(url_for('settings.delete_application_state'), {data:{'trans_ids': deleteToolDataIds}});
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
pgAdmin.Browser.notifier.error(gettext('Failed to remove query data.') + parseApiError(error));
|
||||
}}
|
||||
}
|
||||
}).catch(function(error) {
|
||||
pgAdmin.Browser.notifier.pgRespErrorNotify(error);
|
||||
|
|
|
|||
|
|
@ -57,7 +57,8 @@ class SettingsModule(PgAdminModule):
|
|||
'settings.get_file_format_setting',
|
||||
'settings.save_application_state',
|
||||
'settings.get_application_state',
|
||||
'settings.delete_application_state'
|
||||
'settings.delete_application_state',
|
||||
'settings.get_tool_data'
|
||||
]
|
||||
|
||||
|
||||
|
|
@ -326,8 +327,7 @@ def get_last_saved_file_hash(file_path, trans_id):
|
|||
|
||||
@blueprint.route(
|
||||
'/get_application_state',
|
||||
methods=["GET"], endpoint='get_application_state'
|
||||
)
|
||||
methods=["GET"], endpoint='get_application_state')
|
||||
@pga_login_required
|
||||
def get_application_state():
|
||||
"""
|
||||
|
|
@ -370,16 +370,44 @@ def get_application_state():
|
|||
)
|
||||
|
||||
|
||||
@blueprint.route(
|
||||
'/get_tool_data/<int:trans_id>',
|
||||
methods=["GET"], endpoint='get_tool_data')
|
||||
@pga_login_required
|
||||
def get_tool_data(trans_id):
|
||||
fernet = Fernet(current_app.config['SECRET_KEY'].encode())
|
||||
result = db.session \
|
||||
.query(ApplicationState) \
|
||||
.filter(ApplicationState.uid == current_user.id,
|
||||
ApplicationState.id == trans_id) \
|
||||
.first()
|
||||
|
||||
return make_json_response(
|
||||
data={
|
||||
'status': True,
|
||||
'msg': '',
|
||||
'result': {
|
||||
'tool_data': fernet.decrypt(result.tool_data).decode(),
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@blueprint.route(
|
||||
'/delete_application_state/',
|
||||
methods=["DELETE"], endpoint='delete_application_state')
|
||||
@pga_login_required
|
||||
def delete_application_state():
|
||||
trans_id = None
|
||||
status = False
|
||||
msg = gettext('Unable to delete application state data.')
|
||||
if request.data:
|
||||
data = json.loads(request.data)
|
||||
trans_id = int(data['panelId'].split('_')[-1])
|
||||
status, msg = delete_tool_data(trans_id)
|
||||
if 'trans_ids' in data:
|
||||
for trans_id in data['trans_ids']:
|
||||
status, msg = delete_tool_data(trans_id)
|
||||
else:
|
||||
trans_id = int(data['panelId'].split('_')[-1])
|
||||
status, msg = delete_tool_data(trans_id)
|
||||
return make_json_response(
|
||||
data={
|
||||
'status': status,
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ export function deleteToolData(panelId, closePanelId){
|
|||
}
|
||||
};
|
||||
|
||||
export function ApplicationStateProvider({children}){
|
||||
export function ApplicationStateProvider({children, toolDataId}){
|
||||
const preferencesStore = usePreferences();
|
||||
const saveAppState = preferencesStore?.getPreferencesForModule('misc')?.save_app_state;
|
||||
const openNewTab = preferencesStore?.getPreferencesForModule('browser')?.new_browser_tab_open;
|
||||
|
|
@ -63,9 +63,36 @@ export function ApplicationStateProvider({children}){
|
|||
return saveAppState;
|
||||
};
|
||||
|
||||
async function getQueryToolContent() {
|
||||
try {
|
||||
let transId = toolDataId.split('-')[1];
|
||||
const res = await getApiInstance({'Content-Encoding': 'gzip'}).get(
|
||||
url_for('settings.get_tool_data', {
|
||||
'trans_id': transId,
|
||||
})
|
||||
);
|
||||
return res.data.success? JSON.parse(res.data.data.result.tool_data): null;
|
||||
} catch (error) {
|
||||
pgAdmin.Browser.notifier.pgRespErrorNotify(error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const deleteToolData = ()=>{
|
||||
let transId = toolDataId.split('-')[1];
|
||||
getApiInstance().delete(
|
||||
url_for('settings.delete_application_state'), {data:{'panelId': transId}}
|
||||
).then(()=> { /* Sonar Qube */}).catch(function(error) {
|
||||
pgAdmin.Browser.notifier.pgRespErrorNotify(error);
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
const value = useMemo(()=>({
|
||||
saveToolData,
|
||||
isSaveToolDataEnabled,
|
||||
getQueryToolContent,
|
||||
deleteToolData
|
||||
}), []);
|
||||
|
||||
return <ApplicationStateContext.Provider value={value}>
|
||||
|
|
@ -75,5 +102,6 @@ export function ApplicationStateProvider({children}){
|
|||
}
|
||||
|
||||
ApplicationStateProvider.propTypes = {
|
||||
children: PropTypes.object
|
||||
children: PropTypes.object,
|
||||
toolDataId: PropTypes.string
|
||||
};
|
||||
|
|
@ -45,7 +45,7 @@ function TabTitle({id, closable, defaultInternal}) {
|
|||
}, []);
|
||||
|
||||
useEffect(()=>{
|
||||
const deregister = layoutDocker.eventBus.registerListener(LAYOUT_EVENTS.REFRESH_TITLE, _.debounce((panelId)=>{
|
||||
const deregister = layoutDocker.eventBus.registerListener(LAYOUT_EVENTS.REFRESH_TITLE, (panelId)=>{
|
||||
if(panelId == id) {
|
||||
const internal = layoutDocker?.find(id)?.internal??{};
|
||||
setAttrs({
|
||||
|
|
@ -54,7 +54,7 @@ function TabTitle({id, closable, defaultInternal}) {
|
|||
tooltip: internal.tooltip ?? internal.title,
|
||||
});
|
||||
}
|
||||
}, 100));
|
||||
});
|
||||
|
||||
return ()=>deregister?.();
|
||||
}, []);
|
||||
|
|
|
|||
|
|
@ -360,6 +360,8 @@ export default class ERDTool extends React.Component {
|
|||
this.diagram.deserialize(sqlValue);
|
||||
this.diagram.clearSelection();
|
||||
this.registerModelEvents();
|
||||
this.setState({dirty: true});
|
||||
this.eventBus.fireEvent(ERD_EVENTS.DIRTY, true, this.serializeFile());
|
||||
}
|
||||
}
|
||||
else if(this.props.params.gen) {
|
||||
|
|
|
|||
|
|
@ -220,9 +220,7 @@ export default class SQLEditor {
|
|||
let browser_preferences = usePreferences.getState().getPreferencesForModule('browser');
|
||||
let open_new_tab = browser_preferences.new_browser_tab_open;
|
||||
const [icon, tooltip] = panelTitleFunc.getQueryToolIcon(panel_title, is_query_tool);
|
||||
let selectedNodeInfo = pgAdmin.Browser.tree?.getTreeNodeHierarchy(
|
||||
pgAdmin.Browser.tree.selected()
|
||||
);
|
||||
let selectedNodeInfo = pgAdmin.Browser.tree?.selected() ? pgAdmin.Browser.tree?.getTreeNodeHierarchy(pgAdmin.Browser.tree.selected()) : null;
|
||||
|
||||
pgAdmin.Browser.Events.trigger(
|
||||
'pgadmin:tool:show',
|
||||
|
|
@ -248,7 +246,7 @@ export default class SQLEditor {
|
|||
root.render(
|
||||
<Theme>
|
||||
<PgAdminProvider value={pgAdmin}>
|
||||
<ApplicationStateProvider>
|
||||
<ApplicationStateProvider toolDataId={params.toolDataId}>
|
||||
<ModalProvider>
|
||||
<NotifierProvider pgAdmin={pgAdmin} pgWindow={pgWindow} />
|
||||
{ params.error ?
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
|
|||
const docker = useRef(null);
|
||||
const api = useMemo(()=>getApiInstance(), []);
|
||||
const modal = useModal();
|
||||
const {isSaveToolDataEnabled} = useApplicationState();
|
||||
const {isSaveToolDataEnabled, deleteToolData} = useApplicationState();
|
||||
|
||||
/* Connection status poller */
|
||||
let pollTime = qtState.preferences.sqleditor.connection_status_fetch_time > 0
|
||||
|
|
@ -283,7 +283,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
|
|||
eventBus.current.fireEvent(QUERY_TOOL_EVENTS.HANDLE_API_ERROR, err);
|
||||
setQtStatePartial({ editor_disabled: true });
|
||||
});
|
||||
} else if (qtState.params.sql_id) {
|
||||
} else if (qtState.params.toolDataId) {
|
||||
populateEditorData();
|
||||
} else {
|
||||
setQtStatePartial({ editor_disabled: false });
|
||||
|
|
@ -291,23 +291,24 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
|
|||
};
|
||||
|
||||
const populateEditorData = () =>{
|
||||
let sqlId = qtState.params.sql_id,
|
||||
loadSqlFromLocalStorage = true;
|
||||
|
||||
let populateQueryContent = true;
|
||||
|
||||
if(qtState.params.open_file_name){
|
||||
if(qtState.params.file_deleted == 'false' && qtState.params.is_editor_dirty == 'false'){
|
||||
// call load file from disk as no fil changes
|
||||
// call load file from disk as no file changes
|
||||
eventBus.current.fireEvent(QUERY_TOOL_EVENTS.LOAD_FILE, qtState.params.open_file_name, qtState.params?.storage);
|
||||
populateQueryContent = false;
|
||||
deleteToolData();
|
||||
}else if(qtState.params.file_deleted != 'true'){
|
||||
if(qtState.params.external_file_changes == 'true'){
|
||||
loadSqlFromLocalStorage = false;
|
||||
eventBus.current.fireEvent(QUERY_TOOL_EVENTS.WARN_RELOAD_FILE, qtState.params.open_file_name, sqlId);
|
||||
populateQueryContent = false;
|
||||
eventBus.current.fireEvent(QUERY_TOOL_EVENTS.WARN_RELOAD_FILE, qtState.params.open_file_name);
|
||||
}else{
|
||||
eventBus.current.fireEvent(QUERY_TOOL_EVENTS.LOAD_FILE_DONE, qtState.params.open_file_name, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
if(loadSqlFromLocalStorage) eventBus.current.fireEvent(QUERY_TOOL_EVENTS.LOAD_SQL_FROM_LOCAL_STORAGE, sqlId);
|
||||
if(populateQueryContent) eventBus.current.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_GET_QUERY_CONTENT);
|
||||
setQtStatePartial({ editor_disabled: false });
|
||||
};
|
||||
|
||||
|
|
@ -545,7 +546,7 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
|
|||
});
|
||||
isDirtyRef.current = false;
|
||||
setPanelTitle(qtPanelDocker, qtPanelId, fileName, {...qtState, current_file: fileName}, isDirtyRef.current);
|
||||
|
||||
|
||||
if(isSaveToolDataEnabled('sqleditor'))eventBus.current.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_SAVE_QUERY_TOOL_DATA);
|
||||
}
|
||||
eventBus.current.fireEvent(QUERY_TOOL_EVENTS.EDITOR_LAST_FOCUS);
|
||||
|
|
@ -584,6 +585,8 @@ export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedN
|
|||
[QUERY_TOOL_EVENTS.LOAD_FILE_DONE, fileDone],
|
||||
[QUERY_TOOL_EVENTS.SAVE_FILE_DONE, fileDone],
|
||||
[QUERY_TOOL_EVENTS.QUERY_CHANGED, (isDirty)=>{
|
||||
if(isDirtyRef.current === isDirty) return;
|
||||
|
||||
isDirtyRef.current = isDirty;
|
||||
if(qtState.params.is_query_tool) {
|
||||
setPanelTitle(qtPanelDocker, qtPanelId, null, qtState, isDirty);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ export const QUERY_TOOL_EVENTS = {
|
|||
TRIGGER_GRAPH_VISUALISER: 'TRIGGER_GRAPH_VISUALISER',
|
||||
TRIGGER_SELECT_ALL: 'TRIGGER_SELECT_ALL',
|
||||
TRIGGER_SAVE_QUERY_TOOL_DATA: 'TRIGGER_SAVE_QUERY_TOOL_DATA',
|
||||
TRIGGER_GET_QUERY_CONTENT: 'TRIGGER_GET_QUERY_CONTENT',
|
||||
|
||||
COPY_DATA: 'COPY_DATA',
|
||||
SET_LIMIT_VALUE: 'SET_LIMIT_VALUE',
|
||||
|
|
|
|||
|
|
@ -23,10 +23,9 @@ import ConfirmExecuteQueryContent from '../dialogs/ConfirmExecuteQueryContent';
|
|||
import usePreferences from '../../../../../../preferences/static/js/store';
|
||||
import { getTitle } from '../../sqleditor_title';
|
||||
import PropTypes from 'prop-types';
|
||||
import { useApplicationState, getToolData } from '../../../../../../settings/static/ApplicationStateProvider';
|
||||
import { useApplicationState } from '../../../../../../settings/static/ApplicationStateProvider';
|
||||
import { useDelayDebounce } from '../../../../../../static/js/custom_hooks';
|
||||
|
||||
|
||||
async function registerAutocomplete(editor, api, transId) {
|
||||
editor.registerAutocomplete((context, onAvailable)=>{
|
||||
return new Promise((resolve, reject)=>{
|
||||
|
|
@ -64,7 +63,7 @@ export default function Query({onTextSelect, setQtStatePartial}) {
|
|||
const layoutDocker = useContext(LayoutDockerContext);
|
||||
const lastCursorPos = React.useRef();
|
||||
const pgAdmin = usePgAdmin();
|
||||
const {saveToolData, isSaveToolDataEnabled} = useApplicationState();
|
||||
const {saveToolData, isSaveToolDataEnabled, getQueryToolContent, deleteToolData} = useApplicationState();
|
||||
const preferencesStore = usePreferences();
|
||||
const modalId = MODAL_DIALOGS.QT_CONFIRMATIONS;
|
||||
|
||||
|
|
@ -160,15 +159,16 @@ export default function Query({onTextSelect, setQtStatePartial}) {
|
|||
}
|
||||
};
|
||||
|
||||
const warnReloadFile = (fileName, sqlId, storage=null)=>{
|
||||
const warnReloadFile = (fileName, storage=null)=>{
|
||||
queryToolCtx.modal.confirm(
|
||||
gettext('Reload file?'),
|
||||
gettext('The file has been modified by another program. Do you want to reload it and loose changes made in pgadmin?'),
|
||||
function() {
|
||||
eventBus.fireEvent(QUERY_TOOL_EVENTS.LOAD_FILE, fileName);
|
||||
deleteToolData();
|
||||
},
|
||||
function() {
|
||||
eventBus.fireEvent(QUERY_TOOL_EVENTS.LOAD_SQL_FROM_LOCAL_STORAGE, sqlId);
|
||||
eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_GET_QUERY_CONTENT);
|
||||
eventBus.fireEvent(QUERY_TOOL_EVENTS.LOAD_FILE_DONE, fileName, true, storage);
|
||||
}
|
||||
);
|
||||
|
|
@ -244,6 +244,7 @@ export default function Query({onTextSelect, setQtStatePartial}) {
|
|||
focus && editor.current?.focus();
|
||||
editor.current?.setValue(value, !queryToolCtx.params.is_query_tool);
|
||||
});
|
||||
|
||||
eventBus.registerListener(QUERY_TOOL_EVENTS.TRIGGER_QUERY_CHANGE, ()=>{
|
||||
change();
|
||||
});
|
||||
|
|
@ -283,10 +284,12 @@ export default function Query({onTextSelect, setQtStatePartial}) {
|
|||
setSaveQtData(true);
|
||||
});
|
||||
|
||||
eventBus.registerListener(QUERY_TOOL_EVENTS.LOAD_SQL_FROM_LOCAL_STORAGE, (sqlId)=>{
|
||||
let sqlValue = getToolData(sqlId);
|
||||
if (sqlValue) {
|
||||
eventBus.registerListener(QUERY_TOOL_EVENTS.TRIGGER_GET_QUERY_CONTENT, async ()=>{
|
||||
let sqlValue = await getQueryToolContent();
|
||||
if(sqlValue){
|
||||
eventBus.fireEvent(QUERY_TOOL_EVENTS.EDITOR_SET_SQL, sqlValue);
|
||||
// call delete appplication state api
|
||||
deleteToolData();
|
||||
}
|
||||
});
|
||||
}, []);
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ export function showERDSqlTool(parentData, erdSqlId, queryToolTitle, queryToolMo
|
|||
launchQueryTool(queryToolMod, transId, gridUrl, queryToolTitle, {});
|
||||
}
|
||||
|
||||
export function relaunchSqlTool(connectionInfo, sqlId){
|
||||
export function relaunchSqlTool(connectionInfo, toolDataId){
|
||||
let browserPref = usePreferences.getState().getPreferencesForModule('browser');
|
||||
let parentData = {
|
||||
server_group: {
|
||||
|
|
@ -135,7 +135,7 @@ export function relaunchSqlTool(connectionInfo, sqlId){
|
|||
const qtUrl = generateUrl(transId, parentData, null);
|
||||
const title = getTitle(pgAdmin, browserPref, parentData, false, connectionInfo.server_name, connectionInfo.database_name, connectionInfo.role || connectionInfo.user);
|
||||
launchQueryTool(pgWindow.pgAdmin.Tools.SQLEditor, transId, qtUrl, title, {
|
||||
sql_id: sqlId,
|
||||
toolDataId: toolDataId,
|
||||
...connectionInfo,
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue