{keys.map((key, i)=>{
return
{key}
;
@@ -59,5 +97,5 @@ export default function ShortcutTitle({title, shortcut, accessKey}) {
ShortcutTitle.propTypes = {
title: PropTypes.string,
shortcut: CustomPropTypes.shortcut,
- accessKey: PropTypes.string,
+ accesskey: PropTypes.string,
};
diff --git a/web/pgadmin/static/js/custom_hooks.js b/web/pgadmin/static/js/custom_hooks.js
index b6370bbbe..a38088851 100644
--- a/web/pgadmin/static/js/custom_hooks.js
+++ b/web/pgadmin/static/js/custom_hooks.js
@@ -1,5 +1,6 @@
import {useRef, useEffect, useState, useCallback} from 'react';
-export { useStopwatch } from 'react-timer-hook';
+import moment from 'moment';
+// export { useStopwatch } from 'react-timer-hook';
/* React hook for setInterval */
export function useInterval(callback, delay) {
@@ -78,6 +79,50 @@ export function useIsMounted() {
return useCallback(() => ref.current, []);
}
+export function useStopwatch() {
+ const prevTime = useRef(new Date());
+ const [totalMsec, setTotalMsec] = useState(0);
+ const [isRunning, setIsRunning] = useState(false);
+
+ useInterval(() => {
+ setTotalMsec(moment(new Date()).diff(prevTime.current));
+ }, isRunning ? 100 : -1);
+
+ function start(startTime) {
+ prevTime.current = startTime || new Date();
+ setIsRunning(true);
+ }
+
+ const pause = (endTime)=>{
+ setIsRunning(false);
+ setTotalMsec(moment(endTime || new Date()).diff(prevTime.current));
+ };
+
+ function reset() {
+ setTotalMsec(0);
+ }
+
+ let msec = totalMsec;
+ /* Extract seconds from millisecs */
+ let seconds = parseInt(msec/1000);
+ msec = msec%1000;
+
+ /* Extract mins from seconds */
+ let minutes = parseInt(seconds/60);
+ seconds = seconds%60;
+
+ /* Extract hrs from mins */
+ let hours = parseInt(minutes/60);
+ minutes = minutes%60;
+
+ return {
+ hours: hours,
+ minutes: minutes,
+ seconds: seconds,
+ msec: msec,
+ start, pause, reset, isRunning,
+ };
+}
/*
shortcuts = [
@@ -105,27 +150,30 @@ export function useKeyboardShortcuts(shortcuts, eleRef) {
const matchFound = (shortcut, e)=>{
if(!shortcut) return false;
let keyCode = e.which || e.keyCode;
- return shortcut.alt == e.altKey &&
- shortcut.shift == e.shiftKey &&
- shortcut.control == e.ctrlKey &&
+ return Boolean(shortcut.alt) == e.altKey &&
+ Boolean(shortcut.shift) == e.shiftKey &&
+ Boolean(shortcut.control) == e.ctrlKey &&
shortcut.key.key_code == keyCode;
};
useEffect(()=>{
let ele = eleRef.current ?? document;
- const keyupCallback = (e)=>{
- for(let i=0; i<(shortcutsRef.current??[]).length; i++){
- let {shortcut, options} = shortcutsRef.current[i];
- if(matchFound(shortcut, e)) {
- if(options.callback && (options.enabled ?? true)) {
- options.callback(e);
- }
- break;
+ const keydownCallback = (e)=>{
+ Promise.resolve(0).then(()=>{
+ let allListeners = _.filter(shortcutsRef.current, (s)=>matchFound(s.shortcut, e));
+ for(const {options} of allListeners) {
+ Promise.resolve(0).then(()=>{
+ if(options.callback && (options.enabled ?? true)) {
+ e.preventDefault();
+ e.stopPropagation();
+ options.callback(e);
+ }
+ });
}
- }
+ });
};
- ele.addEventListener('keyup', keyupCallback);
+ ele.addEventListener('keydown', keydownCallback);
return ()=>{
- ele.removeEventListener('keyup', keyupCallback);
+ ele.removeEventListener('keydown', keydownCallback);
};
}, [eleRef.current]);
diff --git a/web/pgadmin/static/js/custom_prop_types.js b/web/pgadmin/static/js/custom_prop_types.js
index 6ba21a6d3..1a2d4c935 100644
--- a/web/pgadmin/static/js/custom_prop_types.js
+++ b/web/pgadmin/static/js/custom_prop_types.js
@@ -31,9 +31,9 @@ const CustomPropTypes = {
]),
shortcut: PropTypes.shape({
- alt: PropTypes.bool,
- control: PropTypes.bool,
- shift: PropTypes.bool,
+ alt: PropTypes.oneOfType([PropTypes.bool, PropTypes.number]),
+ control: PropTypes.oneOfType([PropTypes.bool, PropTypes.number]),
+ shift: PropTypes.oneOfType([PropTypes.bool, PropTypes.number]),
key: PropTypes.shape({
char: PropTypes.string,
}),
diff --git a/web/pgadmin/static/js/helpers/EventBus.js b/web/pgadmin/static/js/helpers/EventBus.js
index a9d077820..9a6906429 100644
--- a/web/pgadmin/static/js/helpers/EventBus.js
+++ b/web/pgadmin/static/js/helpers/EventBus.js
@@ -1,4 +1,3 @@
-import React from 'react';
import _ from 'lodash';
export default class EventBus {
@@ -6,11 +5,12 @@ export default class EventBus {
this._eventListeners = [];
}
- registerListener(event, callback) {
+ registerListener(event, callback, once=false) {
this._eventListeners = this._eventListeners || [];
this._eventListeners.push({
event: event,
callback: callback,
+ fired: once ? 'pending' : 'ignore',
});
}
@@ -28,17 +28,19 @@ export default class EventBus {
}
fireEvent(event, ...args) {
+ let self = this;
Promise.resolve(0).then(()=>{
let allListeners = _.filter(this._eventListeners, (e)=>e.event==event);
if(allListeners) {
for(const listener of allListeners) {
Promise.resolve(0).then(()=>{
listener.callback(...args);
+ if(listener.fired == 'pending') {
+ self.deregisterListener(event, listener.callback);
+ }
});
}
}
});
}
}
-
-export const EventBusContext = React.createContext(new EventBus());
diff --git a/web/pgadmin/static/js/helpers/Layout.jsx b/web/pgadmin/static/js/helpers/Layout.jsx
index 5e3cbe9b0..5074024cc 100644
--- a/web/pgadmin/static/js/helpers/Layout.jsx
+++ b/web/pgadmin/static/js/helpers/Layout.jsx
@@ -1,8 +1,14 @@
-import React from 'react';
+import React, { useRef, useMemo } from 'react';
import DockLayout from 'rc-dock';
import { makeStyles } from '@material-ui/styles';
import PropTypes from 'prop-types';
-import CustomPropTypes from '../custom_prop_types';
+import EventBus from './EventBus';
+import getApiInstance from '../api_instance';
+import url_for from 'sources/url_for';
+import { PgIconButton } from '../components/Buttons';
+import CloseIcon from '@material-ui/icons/CloseRounded';
+import gettext from 'sources/gettext';
+import {ExpandDialogIcon, MinimizeDialogIcon } from '../components/ExternalIcon';
const useStyles = makeStyles((theme)=>({
@@ -26,10 +32,21 @@ const useStyles = makeStyles((theme)=>({
paddingLeft: 0,
backgroundColor: theme.palette.background.default,
...theme.mixins.panelBorder.bottom,
+ '& .dock-nav-wrap': {
+ cursor: 'move',
+ }
},
'& .dock-panel': {
border: 'none',
+ '&.dragging': {
+ opacity: 0.6,
+ pointerEvents: 'visible',
+ },
+ '& .dock': {
+ borderRadius: 'inherit',
+ },
'&.dock-style-dialogs': {
+ borderRadius: theme.shape.borderRadius,
'&.dock-panel.dragging': {
opacity: 1,
},
@@ -46,6 +63,10 @@ const useStyles = makeStyles((theme)=>({
color: theme.palette.text.primary,
}
},
+ },
+ '& .dock-tabpane': {
+ backgroundColor: theme.palette.background.default,
+ color: theme.palette.text.primary,
}
},
'& .dock-tab': {
@@ -54,10 +75,33 @@ const useStyles = makeStyles((theme)=>({
marginRight: 0,
background: 'unset',
fontWeight: 'unset',
+ color: theme.palette.text.primary,
'&::hover': {
color: 'unset',
+ },
+ '& > div': {
+ padding: '4px 10px',
+ },
+ '& .drag-initiator': {
+ display: 'flex',
+ '& .dock-tab-close-btn': {
+ color: theme.palette.text.primary,
+ position: 'unset',
+ marginLeft: '8px',
+ fontSize: '18px',
+ transition: 'none',
+ '&::before': {
+ content: '"\\00d7"',
+ position: 'relative',
+ top: '-5px',
+ }
+ }
}
},
+ '& .dock-extra-content': {
+ alignItems: 'center',
+ paddingRight: '10px',
+ },
'& .dock-vbox, & .dock-hbox .dock-vbox': {
'& .dock-divider': {
flexBasis: '1px',
@@ -91,25 +135,33 @@ const useStyles = makeStyles((theme)=>({
},
'& .dock-fbox': {
zIndex: 1060,
+ },
+ '& .dock-mbox': {
+ zIndex: 1080,
+ },
+ '& .drag-accept-reject::after': {
+ content: '',
}
}
}));
+export const LayoutEventsContext = React.createContext();
export class LayoutHelper {
static getPanel(attrs) {
return {
cached: true,
+ group: 'default',
...attrs,
};
}
static close(docker, panelId) {
- docker.dockMove(docker.find(panelId), 'remove');
+ docker?.dockMove(docker.find(panelId), 'remove');
}
static focus(docker, panelId) {
- docker.updateTab(panelId, null, true);
+ docker?.updateTab(panelId, null, true);
}
static openDialog(docker, panelData, width=500, height=300) {
@@ -128,12 +180,16 @@ export class LayoutHelper {
tabs: [LayoutHelper.getPanel({
...panelData,
group: 'dialogs',
- closable: true,
+ closable: false,
})],
}, null, 'float');
}
}
+ static isTabOpen(docker, panelId) {
+ return Boolean(docker.find(panelId));
+ }
+
static openTab(docker, panelData, refTabId, direction, forceRerender=false) {
let panel = docker.find(panelData.id);
if(panel) {
@@ -149,31 +205,110 @@ export class LayoutHelper {
}
}
-export default function Layout({groups, layoutInstance, ...props}) {
+function saveLayout(layoutObj, layoutId) {
+ let api = getApiInstance();
+ if(!layoutId || !layoutObj) {
+ return;
+ }
+ const formData = new FormData();
+ formData.append('setting', layoutId);
+ formData.append('value', JSON.stringify(layoutObj.saveLayout()));
+ api.post(url_for('settings.store_bulk'), formData)
+ .catch(()=>{/* No need to throw error */});
+}
+
+function getDialogsGroup() {
+ return {
+ disableDock: true,
+ tabLocked: true,
+ floatable: 'singleTab',
+ panelExtra: (panelData, context) => (
+
+
} size="xs" noBorder onClick={()=>{
+ context.dockMove(panelData, null, 'remove');
+ }} />
+
+ )
+ };
+}
+
+function getDefaultGroup() {
+ return {
+ maximizable: false,
+ panelExtra: (panelData, context) => {
+ let icon =
;
+ let title = gettext('Maximise');
+ if(panelData?.parent?.mode == 'maximize') {
+ icon =
;
+ title = gettext('Restore');
+ }
+ return
+
{
+ context.dockMove(panelData, null, 'maximize');
+ }} />
+ ;
+ }
+ };
+}
+
+export default function Layout({groups, getLayoutInstance, layoutId, savedLayout, ...props}) {
const classes = useStyles();
+ const layoutObj = useRef();
const defaultGroups = React.useMemo(()=>({
- 'dialogs': {
- disableDock: true,
- tabLocked: true,
- floatable: 'singleTab',
- },
+ 'dialogs': getDialogsGroup(),
+ 'default': getDefaultGroup(),
...groups,
}), [groups]);
- return (
+
+ const layoutEventBus = React.useRef(new EventBus());
+ return useMemo(()=>(
-
+
+ {
+ layoutObj.current = obj;
+ if(layoutObj.current) {
+ layoutObj.current.resetLayout = ()=>{
+ layoutObj.current.loadLayout(props.defaultLayout);
+ saveLayout(layoutObj.current, layoutId);
+ };
+ }
+ getLayoutInstance?.(layoutObj.current);
+ try {
+ layoutObj.current?.loadLayout(JSON.parse(savedLayout));
+ } catch {
+ /* Fallback to default */
+ layoutObj.current?.loadLayout(props.defaultLayout);
+ }
+ }}
+ groups={defaultGroups}
+ onLayoutChange={(_l, currentTabId, direction)=>{
+ saveLayout(layoutObj.current, layoutId);
+ if(Object.values(LAYOUT_EVENTS).indexOf(direction) > -1) {
+ layoutEventBus.current.fireEvent(LAYOUT_EVENTS[direction.toUpperCase()], currentTabId);
+ }
+ }}
+ {...props}
+ />
+
- );
+ ), []);
}
Layout.propTypes = {
groups: PropTypes.object,
- layoutInstance: CustomPropTypes.ref,
+ getLayoutInstance: PropTypes.func,
+};
+
+
+export const LAYOUT_EVENTS = {
+ ACTIVE: 'active',
+ REMOVE: 'remove',
+ FLOAT: 'float',
+ FRONT: 'front',
+ MAXIMIZE: 'maximize',
+ MOVE: 'move',
};
diff --git a/web/pgadmin/static/js/helpers/ModalProvider.jsx b/web/pgadmin/static/js/helpers/ModalProvider.jsx
index 1f6d07433..f51f69568 100644
--- a/web/pgadmin/static/js/helpers/ModalProvider.jsx
+++ b/web/pgadmin/static/js/helpers/ModalProvider.jsx
@@ -209,7 +209,7 @@ PaperComponent.propTypes = {
height: PropTypes.number,
};
-const useModalStyles = makeStyles(() => ({
+export const useModalStyles = makeStyles((theme) => ({
titleBar: {
display: 'flex',
flexGrow: 1
@@ -227,9 +227,18 @@ const useModalStyles = makeStyles(() => ({
flexShrink: 0,
userSelect: 'none',
},
+ footer: {
+ display: 'flex',
+ justifyContent: 'flex-end',
+ padding: '0.5rem',
+ ...theme.mixins.panelBorder?.top,
+ },
+ margin: {
+ marginLeft: '0.25rem',
+ },
iconButtonStyle: {
marginLeft: 'auto',
- marginRight: '0.3em'
+ marginRight: '4px'
}
}));
diff --git a/web/pgadmin/static/js/sqleditor/calculate_query_run_time.js b/web/pgadmin/static/js/sqleditor/calculate_query_run_time.js
deleted file mode 100644
index 8182ab42a..000000000
--- a/web/pgadmin/static/js/sqleditor/calculate_query_run_time.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import moment from 'moment';
-import gettext from 'sources/gettext';
-
-export function calculateQueryRunTime(startTime, endTime) {
- let total_ms = moment(endTime).diff(startTime);
- let result = '';
- let secs, mins, hrs;
-
- /* Extract seconds from millisecs */
- secs = parseInt(total_ms/1000);
- total_ms = total_ms%1000;
-
- /* Extract mins from seconds */
- mins = parseInt(secs/60);
- secs = secs%60;
-
- /* Extract hrs from mins */
- hrs = parseInt(mins/60);
- mins = mins%60;
-
- result = (hrs>0 ? hrs + ' ' + gettext('hr') + ' ': '')
- + (mins>0 ? mins + ' ' + gettext('min') + ' ': '')
- + (hrs<=0 && secs>0 ? secs + ' ' + gettext('secs') + ' ': '')
- + (hrs<=0 && mins<=0 ? total_ms + ' ' + gettext('msec') + ' ':'');
- return result.trim();
-}
diff --git a/web/pgadmin/static/js/sqleditor/call_render_after_poll.js b/web/pgadmin/static/js/sqleditor/call_render_after_poll.js
deleted file mode 100644
index 16fe689e0..000000000
--- a/web/pgadmin/static/js/sqleditor/call_render_after_poll.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import {calculateQueryRunTime} from './calculate_query_run_time';
-import gettext from '../gettext';
-
-function hasResultsToDisplay(res) {
- return res.colinfo != null;
-}
-
-function isQueryTool(sqlEditor) {
- return sqlEditor.is_query_tool;
-}
-
-function isNotificationEnabled(sqlEditor) {
- return sqlEditor.info_notifier_timeout >= 0;
-}
-
-export function callRenderAfterPoll(sqlEditor, Notify, res) {
- sqlEditor.query_end_time = new Date();
- sqlEditor.rows_affected = res.rows_affected;
- sqlEditor.has_more_rows = res.has_more_rows;
-
- if (hasResultsToDisplay(res)) {
- sqlEditor._render(res);
- } else {
- sqlEditor.total_time = calculateQueryRunTime(
- sqlEditor.query_start_time,
- sqlEditor.query_end_time);
- const msg = gettext('Query returned successfully in %s.', sqlEditor.total_time);
- if (res.result)
- res.result += '\n\n' + msg;
- else
- res.result = msg;
- sqlEditor.update_msg_history(true, res.result, false);
- sqlEditor.reset_data_store();
- if (isNotificationEnabled(sqlEditor)) {
- Notify.success(msg, sqlEditor.info_notifier_timeout);
- }
- sqlEditor.enable_disable_download_btn(true);
- }
-
- if (isQueryTool(sqlEditor)) {
- sqlEditor.disable_tool_buttons(false);
- }
-
- sqlEditor.trigger('pgadmin-sqleditor:check_synchronous_db_name_change', res);
-
- sqlEditor.setIsQueryRunning(false);
- sqlEditor.trigger('pgadmin-sqleditor:loading-icon:hide');
-}
diff --git a/web/pgadmin/static/js/sqleditor/execute_query.js b/web/pgadmin/static/js/sqleditor/execute_query.js
deleted file mode 100644
index e6a911d85..000000000
--- a/web/pgadmin/static/js/sqleditor/execute_query.js
+++ /dev/null
@@ -1,370 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////////////////
-
-import gettext from '../gettext';
-import $ from 'jquery';
-import url_for from '../url_for';
-import axios from 'axios';
-import * as httpErrorHandler from './query_tool_http_error_handler';
-import * as queryTxnStatus from 'sources/sqleditor/query_txn_status_constants';
-import * as SqlEditorUtils from 'sources/sqleditor_utils';
-
-class LoadingScreen {
- constructor(sqlEditor) {
- this.sqlEditor = sqlEditor;
- }
-
- setMessage(message) {
- this.sqlEditor.trigger(
- 'pgadmin-sqleditor:loading-icon:message',
- gettext(message)
- );
- }
-
- show(withMessage) {
- this.sqlEditor.trigger(
- 'pgadmin-sqleditor:loading-icon:show',
- withMessage
- );
- }
-
- hide() {
- this.sqlEditor.trigger('pgadmin-sqleditor:loading-icon:hide');
- }
-}
-
-class ExecuteQuery {
- constructor(sqlEditor, userManagement) {
- this.sqlServerObject = sqlEditor;
- this.loadingScreen = new LoadingScreen(sqlEditor);
- this.userManagement = userManagement;
- }
-
- delayedPoll() {
- const self = this;
- setTimeout(
- () => {
- self.poll();
- }, self.sqlServerObject.POLL_FALLBACK_TIME());
- }
-
- execute(sqlStatement, explainPlan, connect) {
- // If it is an empty query, do nothing.
- if (sqlStatement.length <= 0) {
- // Enable query execution button if user execute empty query.
- $('#btn-flash').prop('disabled', false);
- return;
- }
-
- const self = this;
- self.explainPlan = explainPlan;
-
- const sqlStatementWithAnalyze = ExecuteQuery.prepareAnalyzeSql(sqlStatement, explainPlan);
-
- self.initializeExecutionOnSqlEditor(sqlStatementWithAnalyze);
- axios.post(
- this.generateURLReconnectionFlag(connect),
- JSON.stringify(sqlStatementWithAnalyze),
- {headers: {'Content-Type': 'application/json'}})
- .then(function (result) {
- let httpMessageData = result.data;
- self.removeGridViewMarker();
-
- self.updateSqlEditorLastTransactionStatus(httpMessageData.data.transaction_status);
-
- if (ExecuteQuery.isSqlCorrect(httpMessageData)) {
- self.loadingScreen.setMessage('Waiting for the query to complete...');
-
- // Disable drop down arrow to change connections
- SqlEditorUtils.disable_connection_dropdown(true);
-
- self.updateSqlEditorStateWithInformationFromServer(httpMessageData.data);
-
- // If status is True then poll the result.
- self.delayedPoll();
- } else {
- self.loadingScreen.hide();
- self.enableSQLEditorButtons();
- self.disableDownloadButton();
- // Enable/Disable commit and rollback button.
- if (result.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_INTRANS
- || result.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_INERROR) {
- self.enableTransactionButtons();
- } else {
- self.disableTransactionButtons();
- }
- self.sqlServerObject.update_msg_history(false, httpMessageData.data.result);
- if ('notifies' in httpMessageData.data)
- self.sqlServerObject.update_notifications(httpMessageData.data.notifies);
-
- // Highlight the error in the sql panel
- self.sqlServerObject._highlight_error(httpMessageData.data.result);
- }
- }).catch(function (error) {
- self.onExecuteHTTPError(error);
- }
- );
- }
-
- generateURLReconnectionFlag(shouldReconnect) {
- let url = url_for('sqleditor.query_tool_start', {
- 'trans_id': this.sqlServerObject.transId,
- });
-
- if (shouldReconnect) {
- url += '?connect=1';
- }
- return url;
- }
-
- poll() {
- const self = this;
- axios.get(
- url_for('sqleditor.poll', {
- 'trans_id': self.sqlServerObject.transId,
- })
- ).then(
- (httpMessage) => {
- self.updateSqlEditorLastTransactionStatus(httpMessage.data.data.transaction_status);
-
- // Enable/Disable commit and rollback button.
- if (httpMessage.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_INTRANS
- || httpMessage.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_INERROR) {
- self.enableTransactionButtons();
- } else {
- self.disableTransactionButtons();
- }
-
- if (ExecuteQuery.isQueryFinished(httpMessage)) {
- if (this.sqlServerObject.close_on_idle_transaction &&
- httpMessage.data.data.transaction_status == queryTxnStatus.TRANSACTION_STATUS_IDLE)
- this.sqlServerObject.check_needed_confirmations_before_closing_panel();
-
- self.loadingScreen.setMessage('Loading data from the database server and rendering...');
-
- self.sqlServerObject.call_render_after_poll(httpMessage.data.data);
- if ('notifies' in httpMessage.data.data)
- self.sqlServerObject.update_notifications(httpMessage.data.data.notifies);
- } else if (ExecuteQuery.isQueryStillRunning(httpMessage)) {
- // If status is Busy then poll the result by recursive call to the poll function
- this.delayedPoll();
- self.sqlServerObject.setIsQueryRunning(true);
- if (httpMessage.data.data.result) {
- self.sqlServerObject.update_msg_history(httpMessage.data.data.status, httpMessage.data.data.result, false);
- }
- } else if (ExecuteQuery.isConnectionToServerLostWhilePolling(httpMessage)) {
- self.loadingScreen.hide();
- // Enable/Disable query tool button only if is_query_tool is true.
- if (self.sqlServerObject.is_query_tool) {
- self.enableSQLEditorButtons();
- }
- self.sqlServerObject.update_msg_history(false, httpMessage.data.data.result, true);
- } else if (ExecuteQuery.isQueryCancelled(httpMessage)) {
- self.loadingScreen.hide();
- self.sqlServerObject.update_msg_history(false, 'Execution Cancelled!', true);
- }
- // Enable connection list drop down again for query tool only
- if(self.sqlServerObject.is_query_tool && !ExecuteQuery.isQueryStillRunning(httpMessage)){
- SqlEditorUtils.disable_connection_dropdown(false);
- }
- }
- ).catch(
- error => {
- // Enable/Disable query tool button only if is_query_tool is true.
- self.sqlServerObject.resetQueryHistoryObject(self.sqlServerObject);
-
- self.loadingScreen.hide();
- self.sqlServerObject.setIsQueryRunning(false);
- if (self.sqlServerObject.is_query_tool) {
- self.enableSQLEditorButtons();
- SqlEditorUtils.disable_connection_dropdown(false);
- }
-
- if(error.response) {
- if(ExecuteQuery.wasConnectionLostToPythonServer(error.response)) {
- self.handleConnectionToServerLost();
- return;
- }
- const errorData = error.response.data;
-
- if (self.userManagement.isPgaLoginRequired(errorData)) {
- return self.userManagement.pgaLogin();
- }
-
- let msg = ExecuteQuery.extractErrorMessage(errorData);
-
- self.sqlServerObject.update_msg_history(false, msg);
- // Highlight the error in the sql panel
- self.sqlServerObject._highlight_error(msg);
- } else if(error.request) {
- self.handleConnectionToServerLost();
- return;
- } else {
- console.error(error);
- }
- });
- }
-
- initializeExecutionOnSqlEditor(sqlStatement) {
- this.loadingScreen.show(gettext('Running query...'));
-
- $('#btn-flash').prop('disabled', true);
- this.disableDownloadButton();
-
- this.sqlServerObject.query_start_time = new Date();
- if (typeof sqlStatement === 'object') {
- this.sqlServerObject.query = sqlStatement['sql'];
- } else {
- this.sqlServerObject.query = sqlStatement;
- }
-
- this.sqlServerObject.rows_affected = 0;
- this.sqlServerObject._init_polling_flags();
- this.disableSQLEditorButtons();
- this.disableTransactionButtons();
- }
-
- static prepareAnalyzeSql(sqlStatement, analyzeSql) {
- return {
- sql: sqlStatement,
- explain_plan: analyzeSql,
- };
- }
-
- onExecuteHTTPError(httpMessage) {
- this.loadingScreen.hide();
- this.enableSQLEditorButtons();
-
- if (ExecuteQuery.wasConnectionLostToPythonServer(httpMessage.response)) {
- this.handleConnectionToServerLost();
- return;
- }
-
- if (this.userManagement.isPgaLoginRequired(httpMessage.response)) {
- this.sqlServerObject.saveState('check_data_changes_to_execute_query', [this.explainPlan]);
- this.userManagement.pgaLogin();
- }
-
- if (httpErrorHandler.httpResponseRequiresNewTransaction(httpMessage.response)) {
- this.sqlServerObject.saveState('check_data_changes_to_execute_query', [this.explainPlan]);
- this.sqlServerObject.initTransaction();
- }
-
- if (this.wasDatabaseConnectionLost(httpMessage)) {
- this.sqlServerObject.saveState('check_data_changes_to_execute_query', [this.explainPlan]);
- this.sqlServerObject.handle_connection_lost(false, httpMessage);
- }
-
- if(this.isCryptKeyMissing(httpMessage)) {
- this.sqlServerObject.saveState('check_data_changes_to_execute_query', [this.explainPlan]);
- this.sqlServerObject.handle_cryptkey_missing();
- return;
- }
-
- let msg = httpMessage.response.data.errormsg;
- this.sqlServerObject.update_msg_history(false, msg);
- }
-
- wasDatabaseConnectionLost(httpMessage) {
- return httpMessage.response.status === 503 &&
- httpMessage.response.data.info !== undefined &&
- httpMessage.response.data.info === 'CONNECTION_LOST';
- }
-
- isCryptKeyMissing(httpMessage) {
- return httpMessage.response.status === 503 &&
- httpMessage.response.data.info !== undefined &&
- httpMessage.response.data.info === 'CRYPTKEY_MISSING';
- }
-
- removeGridViewMarker() {
- if (this.sqlServerObject.gridView.marker) {
- this.sqlServerObject.gridView.marker.clear();
- delete this.sqlServerObject.gridView.marker;
- this.sqlServerObject.gridView.marker = null;
-
- // Remove already existing marker
- this.sqlServerObject.gridView.query_tool_obj.removeLineClass(this.sqlServerObject.marked_line_no, 'wrap', 'CodeMirror-activeline-background');
- }
- }
-
- disableDownloadButton() {
- this.sqlServerObject.enable_disable_download_btn(true);
- }
-
- enableSQLEditorButtons() {
- this.sqlServerObject.disable_tool_buttons(false);
- }
-
- disableSQLEditorButtons() {
- this.sqlServerObject.disable_tool_buttons(true);
- }
-
- enableTransactionButtons() {
- this.sqlServerObject.disable_transaction_buttons(false);
- }
-
- disableTransactionButtons() {
- this.sqlServerObject.special_sql = undefined;
- this.sqlServerObject.disable_transaction_buttons(true);
- }
-
- static wasConnectionLostToPythonServer(httpResponse) {
- return _.isUndefined(httpResponse) || _.isUndefined(httpResponse.data);
- }
-
- handleConnectionToServerLost() {
- this.sqlServerObject.update_msg_history(false,
- gettext('Not connected to the server or the connection to the server has been closed.')
- );
- }
-
- updateSqlEditorStateWithInformationFromServer(messageData) {
- this.sqlServerObject.can_edit = messageData.can_edit;
- this.sqlServerObject.can_filter = messageData.can_filter;
- this.sqlServerObject.info_notifier_timeout = messageData.info_notifier_timeout;
- }
-
- updateSqlEditorLastTransactionStatus(transactionStatus) {
- this.sqlServerObject.last_transaction_status = transactionStatus;
- }
-
- static isSqlCorrect(httpMessageData) {
- return httpMessageData.data.status;
- }
-
- static extractErrorMessage(httpMessage) {
- let msg = httpMessage.errormsg;
- if (httpMessage.responseJSON !== undefined &&
- httpMessage.responseJSON.errormsg !== undefined)
- msg = httpMessage.responseJSON.errormsg;
-
- return msg;
- }
-
- static isQueryFinished(httpMessage) {
- return httpMessage.data.data.status === 'Success';
- }
-
- static isQueryStillRunning(httpMessage) {
- return httpMessage.data.data.status === 'Busy';
- }
-
- static isQueryCancelled(httpMessage) {
- return httpMessage.data.data.status === 'Cancel';
- }
-
- static isConnectionToServerLostWhilePolling(httpMessage) {
- return httpMessage.data.data.status === 'NotConnected';
- }
-}
-
-module.exports = {
- ExecuteQuery: ExecuteQuery,
-};
diff --git a/web/pgadmin/static/js/sqleditor/filter_dialog.js b/web/pgadmin/static/js/sqleditor/filter_dialog.js
deleted file mode 100644
index 76a187b71..000000000
--- a/web/pgadmin/static/js/sqleditor/filter_dialog.js
+++ /dev/null
@@ -1,278 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import gettext from 'sources/gettext';
-import url_for from 'sources/url_for';
-import $ from 'jquery';
-import Alertify from 'pgadmin.alertifyjs';
-import pgAdmin from 'sources/pgadmin';
-import Backform from 'pgadmin.backform';
-import axios from 'axios';
-var queryToolActions = require('sources/sqleditor/query_tool_actions');
-import filterDialogModel from 'sources/sqleditor/filter_dialog_model';
-import {handleQueryToolAjaxError} from 'sources/sqleditor/query_tool_http_error_handler';
-import Notify from '../../../static/js/helpers/Notifier';
-
-let FilterDialog = {
- geturl: function(transId, reconnect) {
- let url = url_for('sqleditor.get_filter_data', {
- 'trans_id': transId,
- });
-
- if(reconnect) {
- url += '?connect=1';
- }
-
- return url;
- },
-
- 'dialog': function(handler, reconnect) {
- let title = gettext('Sort/Filter options');
-
- $.ajax({
- url: this.geturl(handler.transId, reconnect),
- headers: {
- 'Cache-Control' : 'no-cache',
- },
- })
- .done(function (res) {
- let response = res.data.result;
-
- // Check the alertify dialog already loaded then delete it to clear
- // the cache
- if (Alertify.filterDialog) {
- delete Alertify.filterDialog;
- }
-
- // Create Dialog
- Alertify.dialog('filterDialog', function factory() {
- let $container = $('
');
- return {
- main: function() {
- this.set('title', gettext('Sort/Filter options'));
- },
- build: function() {
- this.elements.content.appendChild($container.get(0));
- Alertify.pgDialogBuild.apply(this);
- },
- setup: function() {
- return {
- buttons: [{
- text: '',
- key: 112,
- className: 'btn btn-primary-icon pull-left fa fa-question pg-alertify-icon-button',
- attrs: {
- name: 'dialog_help',
- type: 'button',
- label: gettext('Help'),
- 'aria-label': gettext('Help'),
- url: url_for('help.static', {
- 'filename': 'editgrid.html',
- }),
- },
- }, {
- text: gettext('Cancel'),
- key: 27,
- className: 'btn btn-secondary fa fa-times pg-alertify-button',
- 'data-btn-name': 'cancel',
- }, {
- text: gettext('OK'),
- className: 'btn btn-primary fa fa-check pg-alertify-button',
- 'data-btn-name': 'ok',
- }],
- // Set options for dialog
- options: {
- title: title,
- //disable both padding and overflow control.
- padding: !1,
- overflow: !1,
- model: 0,
- resizable: true,
- maximizable: true,
- pinnable: false,
- closableByDimmer: false,
- modal: false,
- autoReset: false,
- },
- };
- },
- hooks: {
- // triggered when the dialog is closed
- onclose: function() {
- if (this.view) {
- this.filterCollectionModel.stopSession();
- this.view.model.stopSession();
- this.view.remove({
- data: true,
- internal: true,
- silent: true,
- });
- }
- },
- },
- prepare: function() {
- let self = this;
- $container.html('');
- // Disable Ok button
- this.__internal.buttons[2].element.disabled = true;
-
- // Status bar
- this.statusBar = $(
- '
' +
- ' ' +
- '
').appendTo($container);
-
- // To show progress on filter Saving/Updating on AJAX
- this.showFilterProgress = $(
- `
-
-
-
` + gettext('Loading data...') + `
-
-
`
- ).appendTo($container);
- $(
- self.showFilterProgress[0]
- ).removeClass('d-none');
-
- self.filterCollectionModel = filterDialogModel(response);
-
- let fields = Backform.generateViewSchema(
- null, self.filterCollectionModel, 'create', null, null, true
- );
-
- let view = this.view = new Backform.Dialog({
- el: '
',
- model: self.filterCollectionModel,
- schema: fields,
- });
-
- $(this.elements.body.childNodes[0]).addClass(
- 'alertify_tools_dialog_properties obj_properties'
- );
-
- $container.append(view.render().$el);
-
- // Enable/disable save button and show/hide statusbar based on session
- view.listenTo(view.model, 'pgadmin-session:start', function() {
- view.listenTo(view.model, 'pgadmin-session:invalid', function(msg) {
- self.statusBar.removeClass('d-none');
- $(self.statusBar.find('.alert-text')).html(msg);
- // Disable Okay button
- self.__internal.buttons[2].element.disabled = true;
- });
-
- view.listenTo(view.model, 'pgadmin-session:valid', function() {
- self.statusBar.addClass('d-none');
- $(self.statusBar.find('.alert-text')).html('');
- // Enable Okay button
- self.__internal.buttons[2].element.disabled = false;
- });
- });
-
- view.listenTo(view.model, 'pgadmin-session:stop', function() {
- view.stopListening(view.model, 'pgadmin-session:invalid');
- view.stopListening(view.model, 'pgadmin-session:valid');
- });
-
- // Starts monitoring changes to model
- view.model.startNewSession();
-
- // Set data in collection
- let viewDataSortingModel = view.model.get('data_sorting');
- viewDataSortingModel.add(response['data_sorting']);
-
- // Hide Progress ...
- $(
- self.showFilterProgress[0]
- ).addClass('d-none');
-
- },
- // Callback functions when click on the buttons of the Alertify dialogs
- callback: function(e) {
- let self = this;
-
- if (e.button.element.name == 'dialog_help') {
- e.cancel = true;
- pgAdmin.Browser.showHelp(e.button.element.name, e.button.element.getAttribute('url'),
- null, null);
- } else if (e.button['data-btn-name'] === 'ok') {
- e.cancel = true; // Do not close dialog
-
- let filterCollectionModel = this.filterCollectionModel.toJSON();
-
- // Show Progress ...
- $(
- self.showFilterProgress[0]
- ).removeClass('d-none');
-
- axios.put(
- url_for('sqleditor.set_filter_data', {
- 'trans_id': handler.transId,
- }),
- filterCollectionModel
- ).then(function (result) {
- // Hide Progress ...
- $(
- self.showFilterProgress[0]
- ).addClass('d-none');
-
- let filterResponse = result.data.data;
-
- if (filterResponse.status) {
- setTimeout(
- function() {
- self.close(); // Close the dialog now
- Notify.success(gettext('Filter updated successfully'));
- queryToolActions.executeQuery(handler);
- }, 10
- );
- } else {
- Notify.alert(
- gettext('Validation Error'),
- filterResponse.result
- );
- }
-
- }).catch(function (error) {
- // Hide Progress ...
- $(
- self.showFilterProgress[0]
- ).addClass('d-none');
- handler.onExecuteHTTPError(error);
-
- setTimeout(
- function() {
- Notify.error(error);
- }, 10
- );
- });
- } else {
- self.close();
- }
- },
- };
- });
-
- Alertify.filterDialog(title).resizeTo(pgAdmin.Browser.stdW.md,pgAdmin.Browser.stdH.md);
- })
- .fail(function(e) {
- handleQueryToolAjaxError(pgAdmin, handler, e, '_show_filter', [], true);
- });
- },
-};
-
-module.exports = FilterDialog;
diff --git a/web/pgadmin/static/js/sqleditor/filter_dialog_model.js b/web/pgadmin/static/js/sqleditor/filter_dialog_model.js
deleted file mode 100644
index f5a66e34a..000000000
--- a/web/pgadmin/static/js/sqleditor/filter_dialog_model.js
+++ /dev/null
@@ -1,137 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import gettext from 'sources/gettext';
-import _ from 'underscore';
-import pgAdmin from 'sources/pgadmin';
-import Backgrid from 'pgadmin.backgrid';
-import Backform from 'pgadmin.backform';
-
-export default function filterDialogModel(response) {
-
- let order_mapping = {
- 'asc': gettext('ASC'),
- 'desc': gettext('DESC'),
- };
-
- let DataSortingModel = pgAdmin.Browser.DataModel.extend({
- idAttribute: 'name',
- defaults: {
- name: undefined,
- order: 'asc',
- },
- schema: [{
- id: 'name',
- name: 'name',
- label: gettext('Column'),
- cell: 'select2',
- editable: true,
- cellHeaderClasses: 'width_percent_60',
- headerCell: Backgrid.Extension.CustomHeaderCell,
- disabled: false,
- control: 'select2',
- select2: {
- allowClear: false,
- },
- options: function() {
- return _.map(response.column_list, (obj) => {
- return {
- value: obj,
- label: obj,
- };
- });
- },
- },
- {
- id: 'order',
- name: 'order',
- label: gettext('Order'),
- control: 'select2',
- cell: 'select2',
- cellHeaderClasses: 'width_percent_40',
- headerCell: Backgrid.Extension.CustomHeaderCell,
- editable: true,
- deps: ['type'],
- select2: {
- allowClear: false,
- },
- options: function() {
- return _.map(order_mapping, (val, key) => {
- return {
- value: key,
- label: val,
- };
- });
- },
- },
- ],
- validate: function() {
- let msg = null;
- this.errorModel.clear();
- if (_.isUndefined(this.get('name')) ||
- _.isNull(this.get('name')) ||
- String(this.get('name')).replace(/^\s+|\s+$/g, '') == '') {
- msg = gettext('Please select a column.');
- this.errorModel.set('name', msg);
- return msg;
- } else if (_.isUndefined(this.get('order')) ||
- _.isNull(this.get('order')) ||
- String(this.get('order')).replace(/^\s+|\s+$/g, '') == '') {
- msg = gettext('Please select the order.');
- this.errorModel.set('order', msg);
- return msg;
- }
- return null;
- },
- });
-
- let FilterCollectionModel = pgAdmin.Browser.DataModel.extend({
- idAttribute: 'sql',
- defaults: {
- sql: response.sql || null,
- },
- schema: [{
- id: 'sql',
- label: gettext('SQL Filter'),
- cell: 'string',
- type: 'text', mode: ['create'],
- control: Backform.SqlFieldControl.extend({
- render: function() {
- let obj = Backform.SqlFieldControl.prototype.render.apply(this, arguments);
- // We need to set focus on editor after the dialog renders
- setTimeout(() => {
- obj.sqlCtrl.focus();
- }, 1000);
- return obj;
- },
- }),
- extraClasses:['custom_height_css_class'],
- },{
- id: 'data_sorting',
- name: 'data_sorting',
- label: gettext('Data Sorting'),
- model: DataSortingModel,
- editable: true,
- type: 'collection',
- mode: ['create'],
- control: 'unique-col-collection',
- uniqueCol: ['name'],
- canAdd: true,
- canEdit: false,
- canDelete: true,
- visible: true,
- version_compatible: true,
- }],
- validate: function() {
- return null;
- },
- });
-
- return new FilterCollectionModel();
-}
diff --git a/web/pgadmin/static/js/sqleditor/geometry_viewer.js b/web/pgadmin/static/js/sqleditor/geometry_viewer.js
deleted file mode 100644
index 23a1d3843..000000000
--- a/web/pgadmin/static/js/sqleditor/geometry_viewer.js
+++ /dev/null
@@ -1,434 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import gettext from 'sources/gettext';
-import {Buffer} from 'buffer';
-import $ from 'jquery';
-
-var L = null;
-var Geometry = null;
-let GeometryViewer = {
- panel_closed: true,
-
- go_for_render: function(handler, items, columns, columnIndex) {
- let self = this;
-
- if (!self.map_component) {
- self.map_component = initMapComponent();
- }
-
- if (self.panel_closed) {
- let wcDocker = window.wcDocker;
- let geometry_viewer_panel = handler.gridView.geometry_viewer =
- handler.gridView.docker.addPanel('geometry_viewer',
- wcDocker.DOCK.STACKED, handler.gridView.data_output_panel);
- $('#geometry_viewer_panel')[0].appendChild(self.map_component.mapContainer.get(0));
- self.panel_closed = false;
-
- geometry_viewer_panel.on(wcDocker.EVENT.CLOSED, function () {
- $('#geometry_viewer_panel').empty();
- self.map_component.clearMap();
- self.panel_closed = true;
- });
-
- geometry_viewer_panel.on(wcDocker.EVENT.RESIZE_ENDED, function () {
- if (geometry_viewer_panel.isVisible()) {
- self.map_component.resizeMap();
- }
- });
-
- geometry_viewer_panel.on(wcDocker.EVENT.VISIBILITY_CHANGED, function (visible) {
- if (visible) {
- self.map_component.resizeMap();
- } else {
- self.map_component.loseFocus();
- }
- });
- }
-
- handler.gridView.geometry_viewer.focus();
- self.map_component.clearMap();
- let dataObj = parseData(items, columns, columnIndex, Geometry);
- self.map_component.renderMap(dataObj);
- },
-
- render_geometries: function (handler, items, columns, columnIndex) {
- let self = this;
- require.ensure(['leaflet', 'wkx'], function(require) {
- L = require('leaflet');
- Geometry = require('wkx').Geometry;
- self.go_for_render(handler, items, columns, columnIndex);
- }, function(error){
- throw(error);
- }, 'geometry');
- },
-
- add_header_button: function (columnDefinition) {
- columnDefinition.header = {
- buttons: [
- {
- cssClass: 'div-view-geometry-column',
- tooltip: 'View all geometries in this column',
- showOnHover: false,
- command: 'view-geometries',
- content: '
',
- },
- ],
- };
- },
-
- parse_data: parseData,
-};
-
-function initMapComponent() {
- const geojsonMarkerOptions = {
- radius: 4,
- weight: 3,
- };
- const geojsonStyle = {
- weight: 2,
- };
- const popupOption = {
- closeButton: false,
- minWidth: 260,
- maxWidth: 300,
- maxHeight: 300,
- };
-
- let mapContainer = $('
');
- let lmap = L.map(mapContainer.get(0), {
- preferCanvas: true,
- }).setZoom(0);
-
- // update default attribution
- lmap.attributionControl.setPrefix('');
-
- let vectorLayer = L.geoJSON([], {
- style: geojsonStyle,
- pointToLayer: function (feature, latlng) {
- return L.circleMarker(latlng, geojsonMarkerOptions);
- },
- });
- vectorLayer.addTo(lmap);
- let baseLayersObj = {
- 'Empty': L.tileLayer(''),
- 'Street': L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
- {
- maxZoom: 19,
- attribution: '©
OpenStreetMap ',
- }),
- 'Topography': L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png',
- {
- maxZoom: 17,
- attribution: '©
OpenStreetMap ,' +
- ' ©
SRTM ,' +
- ' ©
OpenTopoMap ',
- }),
- 'Gray Style': L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}{r}.png',
- {
- attribution: '©
OpenStreetMap ,' +
- ' ©
CartoDB ',
- subdomains: 'abcd',
- maxZoom: 19,
- }),
- 'Light Color': L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/rastertiles/voyager/{z}/{x}/{y}{r}.png',
- {
- attribution: '©
OpenStreetMap ,' +
- ' ©
CartoDB ',
- subdomains: 'abcd',
- maxZoom: 19,
- }),
- 'Dark Matter': L.tileLayer('https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}{r}.png',
- {
- attribution: '©
OpenStreetMap ,' +
- ' ©
CartoDB ',
- subdomains: 'abcd',
- maxZoom: 19,
- }),
- };
- let layerControl = L.control.layers(baseLayersObj);
- let defaultBaseLayer = baseLayersObj.Street;
- let baseLayers = _.values(baseLayersObj);
-
- let infoControl = L.control({position: 'topright'});
- infoControl.onAdd = function () {
- this._div = L.DomUtil.create('div', 'geometry-viewer-info-control');
- return this._div;
- };
- infoControl.update = function (content) {
- this._div.innerHTML = content;
- };
-
- let setEPSG3857 = function () {
- if (lmap.options.crs !== L.CRS.EPSG3857) {
- lmap.options.crs = L.CRS.EPSG3857;
- layerControl.addTo(lmap);
- lmap.addLayer(defaultBaseLayer);
- mapContainer.addClass('geometry-viewer-container-plain-background');
- lmap.setMinZoom(0);
- }
- };
-
- let setSimpleCRS = function () {
- if (lmap.options.crs !== L.CRS.Simple) {
- lmap.options.crs = L.CRS.Simple;
- layerControl.remove();
- _.each(baseLayers, function (layer) {
- if (lmap.hasLayer(layer)) {
- defaultBaseLayer = layer;
- layer.remove();
- }
- });
- mapContainer.removeClass('geometry-viewer-container-plain-background');
- }
- };
-
- setSimpleCRS();
- setEPSG3857();
-
- return {
- 'mapContainer': mapContainer,
- 'clearMap': function () {
- lmap.closePopup();
- infoControl.remove();
- vectorLayer.clearLayers();
- },
-
- 'loseFocus': function() {
- lmap.fire('blur');
- },
-
- 'renderMap': function (dataObj) {
- let geoJSONs = dataObj.geoJSONs,
- SRID = dataObj.selectedSRID,
- getPopupContent = dataObj.getPopupContent,
- infoList = dataObj.infoList;
-
- let isEmpty = false;
- if (geoJSONs.length === 0) {
- isEmpty = true;
- }
-
- try {
- vectorLayer.addData(geoJSONs);
- } catch (e) {
- // Invalid LatLng object: (NaN, NaN)
- infoList.push('An error occurred while rendering data.');
- isEmpty = true;
- }
-
- let bounds = vectorLayer.getBounds();
- if (!bounds.isValid()) {
- isEmpty = true;
- }
-
- if (infoList.length > 0) {
- if (lmap.options.crs === L.CRS.EPSG3857) {
- layerControl.remove();
- infoControl.addTo(lmap);
- layerControl.addTo(lmap);
- } else {
- infoControl.addTo(lmap);
- }
- let infoContent = generateInfoContent(infoList);
- infoControl.update(infoContent);
- }
-
- if (isEmpty) {
- setSimpleCRS();
- lmap.setView([0, 0], lmap.getZoom());
- return;
- }
-
- if (typeof getPopupContent === 'function') {
- let addPopup = function (layer) {
- layer.bindPopup(function () {
- return getPopupContent(layer.feature.geometry);
- }, popupOption);
- };
- vectorLayer.eachLayer(addPopup);
- }
-
- bounds = bounds.pad(0.1);
- let maxLength = Math.max(bounds.getNorth() - bounds.getSouth(),
- bounds.getEast() - bounds.getWest());
- if (SRID === 4326) {
- setEPSG3857();
- } else {
- setSimpleCRS();
- if (maxLength >= 180) {
- // calculate the min zoom level to enable the map to fit the whole geometry.
- let minZoom = Math.floor(Math.log2(360 / maxLength)) - 2;
- lmap.setMinZoom(minZoom);
- } else {
- lmap.setMinZoom(0);
- }
- }
-
- if (maxLength > 0) {
- lmap.fitBounds(bounds);
- } else {
- lmap.setView(bounds.getCenter(), lmap.getZoom());
- }
- },
-
- 'resizeMap': function () {
- setTimeout(function () {
- lmap.invalidateSize();
- }, 10);
- },
-
- };
-}
-
-function parseData(items, columns, columnIndex, GeometryLib) {
- const maxRenderByteLength = 20 * 1024 * 1024; //render geometry data up to 20MB
- const maxRenderGeometries = 100000; // render geometries up to 100000
- let field = columns[columnIndex].field;
- let geometries3D = [],
- supportedGeometries = [],
- unsupportedItems = [],
- infoList = [],
- geometryItemMap = new Map(),
- mixedSRID = false,
- geometryTotalByteLength = 0,
- tooLargeDataSize = false,
- tooManyGeometries = false;
-
- if (items.length === 0) {
- infoList.push('Empty row.');
- return {
- 'geoJSONs': [],
- 'selectedSRID': 0,
- 'getPopupContent': undefined,
- 'infoList': infoList,
- };
- }
-
- // parse ewkb data
- _.every(items, function (item) {
- try {
- let value = item[field];
- let buffer = Buffer.from(value, 'hex');
- let geometry = GeometryLib.parse(buffer);
- if (geometry.hasZ) {
- geometries3D.push(geometry);
- } else {
- geometryTotalByteLength += buffer.byteLength;
- if (geometryTotalByteLength > maxRenderByteLength) {
- tooLargeDataSize = true;
- return false;
- }
- if (supportedGeometries.length >= maxRenderGeometries) {
- tooManyGeometries = true;
- return false;
- }
-
- if (!geometry.srid) {
- geometry.srid = 0;
- }
- supportedGeometries.push(geometry);
- geometryItemMap.set(geometry, item);
- }
- } catch (e) {
- unsupportedItems.push(item);
- }
- return true;
- });
-
- // generate map info content
- if (tooLargeDataSize || tooManyGeometries) {
- infoList.push(supportedGeometries.length + ' of ' + items.length + ' geometries rendered.');
- }
- if (geometries3D.length > 0) {
- infoList.push(gettext('3D geometries not rendered.'));
- }
- if (unsupportedItems.length > 0) {
- infoList.push(gettext('Unsupported geometries not rendered.'));
- }
-
- if (supportedGeometries.length === 0) {
- return {
- 'geoJSONs': [],
- 'selectedSRID': 0,
- 'getPopupContent': undefined,
- 'infoList': infoList,
- };
- }
-
- // group geometries by SRID
- let geometriesGroupBySRID = _.groupBy(supportedGeometries, 'srid');
- let SRIDGeometriesPairs = _.pairs(geometriesGroupBySRID);
- if (SRIDGeometriesPairs.length > 1) {
- mixedSRID = true;
- }
- // select the largest group
- let selectedPair = _.max(SRIDGeometriesPairs, function (pair) {
- return pair[1].length;
- });
- let selectedSRID = parseInt(selectedPair[0]);
- let selectedGeometries = selectedPair[1];
-
- let geoJSONs = _.map(selectedGeometries, function (geometry) {
- return geometry.toGeoJSON();
- });
-
- let getPopupContent;
- if (columns.length >= 3) {
- // add popup when geometry has properties
- getPopupContent = function (geojson) {
- let geometry = selectedGeometries[geoJSONs.indexOf(geojson)];
- let item = geometryItemMap.get(geometry);
- return itemToTable(item, columns, columnIndex);
- };
- }
-
- if (mixedSRID) {
- infoList.push(gettext('Geometries with non-SRID %s not rendered.', selectedSRID));
- }
-
- return {
- 'geoJSONs': geoJSONs,
- 'selectedSRID': selectedSRID,
- 'getPopupContent': getPopupContent,
- 'infoList': infoList,
- };
-}
-
-function itemToTable(item, columns, ignoredColumnIndex) {
- let content = '
';
-
- // start from 1 because columns[0] is empty
- for (let i = 1; i < columns.length; i++) {
- if (i !== ignoredColumnIndex) {
- let columnDef = columns[i];
- content += '' + columnDef.display_name + ' ';
-
- let value = item[columnDef.field];
- if (_.isUndefined(value) && columnDef.has_default_val) {
- content += '[default] ';
- } else if ((_.isUndefined(value) && columnDef.not_null) ||
- (_.isUndefined(value) || value === null)) {
- content += '[null] ';
- } else {
- content += '' + value + ' ';
- }
-
- content += ' ';
- }
- }
- content += '
';
- return content;
-}
-
-function generateInfoContent(infoList) {
- return infoList.join('
');
-}
-
-module.exports = GeometryViewer;
diff --git a/web/pgadmin/static/js/sqleditor/history/history_collection.js b/web/pgadmin/static/js/sqleditor/history/history_collection.js
deleted file mode 100644
index 647d1d829..000000000
--- a/web/pgadmin/static/js/sqleditor/history/history_collection.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-export default class HistoryCollection {
-
- constructor(history_model) {
- this.historyList = _.sortBy(history_model, o=>o.start_time);
- this.onAdd(() => {/*This is intentional (SonarQube)*/});
- }
-
- length() {
- return this.historyList.length;
- }
-
- add(object) {
- /* add object in sorted order */
- let pushAt = _.sortedIndex(this.historyList, object, o=>o.start_time);
- this.historyList.splice(pushAt, 0, object);
- this.onAddHandler(object);
- }
-
- reset() {
- this.historyList = [];
- this.onResetHandler(this.historyList);
- }
-
- onAdd(onAddHandler) {
- this.onAddHandler = onAddHandler;
- }
-
- onReset(onResetHandler) {
- this.onResetHandler = onResetHandler;
- }
-}
diff --git a/web/pgadmin/static/js/sqleditor/history/query_history.js b/web/pgadmin/static/js/sqleditor/history/query_history.js
deleted file mode 100644
index e8e4e4d45..000000000
--- a/web/pgadmin/static/js/sqleditor/history/query_history.js
+++ /dev/null
@@ -1,96 +0,0 @@
-import QueryHistoryDetails from './query_history_details';
-import { QueryHistoryEntries } from './query_history_entries';
-import Split from 'split.js';
-import gettext from 'sources/gettext';
-import $ from 'jquery';
-
-export default class QueryHistory {
- constructor(parentNode, histModel) {
- this.parentNode = parentNode;
- this.histCollection = histModel;
- this.editorPref = {};
-
- this.onCopyToEditorHandler = ()=>{/*This is intentional (SonarQube)*/};
- this.histCollection.onAdd(this.onAddEntry.bind(this));
- this.histCollection.onReset(this.onResetEntries.bind(this));
- }
-
- focus() {
- if (this.queryHistEntries) {
- this.queryHistEntries.focus();
- }
- }
-
- onAddEntry(entry) {
- if (this.histCollection.length() == 1) {
- this.render();
- } else if (this.queryHistEntries) {
- this.queryHistEntries.addEntry(entry);
- }
- }
-
- onResetEntries() {
- this.isRendered = false;
- this.queryHistEntries = null;
- this.queryHistDetails = null;
- this.render();
- }
-
- onCopyToEditorClick(onCopyToEditorHandler) {
- this.onCopyToEditorHandler = onCopyToEditorHandler;
-
- if(this.queryHistDetails) {
- this.queryHistDetails.onCopyToEditorClick(this.onCopyToEditorHandler);
- }
- }
-
- setEditorPref(editorPref) {
- this.editorPref = {
- ...this.editorPref,
- ...editorPref,
- };
- if(this.queryHistDetails) {
- this.queryHistDetails.setEditorPref(this.editorPref);
- }
- }
-
- render() {
- if (this.histCollection.length() == 0) {
- this.parentNode.empty()
- .removeClass('d-flex')
- .append(
- '
' +
- gettext('No history found') +
- '
'
- );
- } else {
- this.parentNode.empty().addClass('d-flex');
- let $histEntries = $('
').appendTo(this.parentNode);
- let $histDetails = $('
').appendTo(this.parentNode);
-
- Split([$histEntries[0], $histDetails[0]], {
- gutterSize: 1,
- cursor: 'ew-resize',
- });
-
- $histDetails.css('overflow', 'auto');
-
- this.queryHistDetails = new QueryHistoryDetails($histDetails);
- this.queryHistDetails.setEditorPref(this.editorPref);
- this.queryHistDetails.onCopyToEditorClick(this.onCopyToEditorHandler);
- this.queryHistDetails.render();
-
- this.queryHistEntries = new QueryHistoryEntries($histEntries);
- this.queryHistEntries.onSelectedChange(
- (entry => {
- this.queryHistDetails.setEntry(entry);
- }).bind(this)
- );
- this.queryHistEntries.render();
-
- this.histCollection.historyList.map((entry)=>{
- this.queryHistEntries.addEntry(entry);
- });
- }
- }
-}
diff --git a/web/pgadmin/static/js/sqleditor/history/query_history_details.js b/web/pgadmin/static/js/sqleditor/history/query_history_details.js
deleted file mode 100644
index e77b71097..000000000
--- a/web/pgadmin/static/js/sqleditor/history/query_history_details.js
+++ /dev/null
@@ -1,216 +0,0 @@
-import CodeMirror from 'bundled_codemirror';
-import clipboard from 'sources/selection/clipboard';
-import gettext from 'sources/gettext';
-import $ from 'jquery';
-import _ from 'underscore';
-
-export default class QueryHistoryDetails {
- constructor(parentNode) {
- this.parentNode = parentNode;
- this.isCopied = false;
- this.timeout = null;
- this.isRendered = false;
- this.sqlFontSize = null;
- this.onCopyToEditorHandler = ()=>{/*This is intentional (SonarQube)*/};
-
- this.editorPref = {
- 'sql_font_size': '1em',
- 'copy_to_editor': true,
- };
- }
-
- setEntry(entry) {
- this.entry = entry;
- if (this.isRendered) {
- this.selectiveRender();
- } else {
- this.render();
- }
- }
-
- setEditorPref(editorPref={}) {
- this.editorPref = {
- ...this.editorPref,
- ...editorPref,
- };
-
- if(this.query_codemirror && !_.isUndefined(editorPref.sql_font_size)) {
- $(this.query_codemirror.getWrapperElement()).css(
- 'font-size',this.editorPref.sql_font_size
- );
-
- this.query_codemirror.refresh();
- }
-
- if(this.$copyToEditor && !_.isUndefined(editorPref.copy_to_editor)) {
- if(editorPref.copy_to_editor) {
- this.$copyToEditor.removeClass('d-none');
- } else {
- this.$copyToEditor.addClass('d-none');
- }
- }
- }
-
- parseErrorMessage(message) {
- return message.match(/ERROR:\s*([^\n\r]*)/i)
- ? message.match(/ERROR:\s*([^\n\r]*)/i)[1]
- : message;
- }
-
- formatDate(date) {
- return date.toLocaleDateString() + ' ' + date.toLocaleTimeString();
- }
-
- copyAllHandler() {
- clipboard.copyTextToClipboard(this.entry.query);
-
- this.clearPreviousTimeout();
-
- this.updateCopyButton(true);
-
- this.timeout = setTimeout(() => {
- this.updateCopyButton(false);
- }, 1500);
- }
-
- onCopyToEditorClick(onCopyToEditorHandler) {
- this.onCopyToEditorHandler = onCopyToEditorHandler;
- }
-
- clearPreviousTimeout() {
- if (this.timeout) {
- clearTimeout(this.timeout);
- this.timeout = null;
- }
- }
-
- updateCopyButton(copied) {
- if (copied) {
- this.$copyBtn.addClass('was-copied').removeClass('copy-all');
- this.$copyBtn.text(gettext('Copied!'));
- } else {
- this.$copyBtn.addClass('copy-all').removeClass('was-copied');
- this.$copyBtn.text(gettext('Copy'));
- }
- }
-
- updateQueryMetaData() {
- let itemTemplate = (data, description) => {
- if(data)
- return `
- ${data}
- ${description}
-
`;
- else
- return '';
- };
-
- this.$metaData.empty().append(
- '
' +
- itemTemplate(this.formatDate(this.entry.start_time), gettext('Date')) +
- itemTemplate(
- this.entry.row_affected.toLocaleString(),
- gettext('Rows Affected')
- ) +
- itemTemplate(this.entry.total_time, gettext('Duration')) +
- '
'
- );
- }
-
- updateMessageContent() {
- this.$message_content
- .empty()
- .append(`
${_.escape(this.entry.message)} `);
- }
-
- updateErrorMessage() {
- if (!this.entry.status) {
- this.$errMsgBlock.removeClass('d-none');
- this.$errMsgBlock.empty().append(
- `
- ` + gettext('Error Message') + ` ${_.escape(this.parseErrorMessage(this.entry.message))}
-
`
- );
- } else {
- this.$errMsgBlock.addClass('d-none');
- this.$errMsgBlock.empty();
- }
- }
-
- updateInfoMessage() {
- if (this.entry.info) {
- this.$infoMsgBlock.removeClass('d-none');
- this.$infoMsgBlock.empty().append(
- `
- ${this.entry.info}
-
`
- );
- } else {
- this.$infoMsgBlock.addClass('d-none');
- this.$infoMsgBlock.empty();
- }
- }
-
- selectiveRender() {
- this.updateErrorMessage();
- this.updateInfoMessage();
- this.updateCopyButton(false);
- this.updateQueryMetaData();
- this.query_codemirror.setValue(this.entry.query);
- this.updateMessageContent();
- }
-
- render() {
- if (this.entry) {
- this.parentNode.empty().append(
- `
-
-
-
-
-
-
-
` + gettext('Copy to Query Editor') + `
-
-
-
-
-
-
-
-
`
- );
-
- this.$errMsgBlock = this.parentNode.find('.error-message-block');
- this.$infoMsgBlock = this.parentNode.find('.info-message-block');
- this.$copyBtn = this.parentNode.find('#history-detail-query .btn-copy');
- this.$copyBtn.off('click').on('click', this.copyAllHandler.bind(this));
- this.$copyToEditor = this.parentNode.find('#history-detail-query .btn-copy-editor');
- this.$copyToEditor.off('click').on('click', () => {
- this.onCopyToEditorHandler(this.entry.query);
- });
- this.$copyToEditor.addClass(this.editorPref.copy_to_editor?'':'d-none');
- this.$metaData = this.parentNode.find('.metadata-block');
- this.query_codemirror = CodeMirror(
- this.parentNode.find('#history-detail-query div')[0],
- {
- tabindex: -1,
- mode: 'text/x-pgsql',
- readOnly: true,
- }
- );
- $(this.query_codemirror.getWrapperElement()).css(
- 'font-size',this.editorPref.sql_font_size
- );
- this.$message_content = this.parentNode.find('.message-block .content');
-
- this.isRendered = true;
- this.selectiveRender();
- }
- }
-}
diff --git a/web/pgadmin/static/js/sqleditor/history/query_history_entries.js b/web/pgadmin/static/js/sqleditor/history/query_history_entries.js
deleted file mode 100644
index 41d5cc310..000000000
--- a/web/pgadmin/static/js/sqleditor/history/query_history_entries.js
+++ /dev/null
@@ -1,296 +0,0 @@
-import moment from 'moment';
-import $ from 'jquery';
-import _ from 'underscore';
-import 'bootstrap.toggle';
-import gettext from 'sources/gettext';
-
-const ARROWUP = 38;
-const ARROWDOWN = 40;
-
-export class QueryHistoryEntryDateGroup {
- constructor(date, groupKey) {
- this.date = date;
- this.formatString = 'MMM DD YYYY';
- this.groupKey = groupKey;
- }
-
- getDatePrefix() {
- let prefix = '';
- if (this.isDaysBefore(0)) {
- prefix = 'Today - ';
- } else if (this.isDaysBefore(1)) {
- prefix = 'Yesterday - ';
- }
- return prefix;
- }
-
- getDateFormatted(date) {
- return date.toLocaleDateString();
- }
-
- isDaysBefore(before) {
- return (
- this.getDateFormatted(this.date) ===
- this.getDateFormatted(moment().subtract(before, 'days').toDate())
- );
- }
-
- render() {
- return $(`
-
${this.getDatePrefix()}${this.getDateFormatted(this.date)}
-
-
`);
- }
-}
-
-export class QueryHistoryItem {
- constructor(entry) {
- this.entry = entry;
- this.$el = null;
- this.onClickHandler = null;
- }
-
- onClick(onClickHandler) {
- this.onClickHandler = onClickHandler;
- if (this.$el) {
- this.$el.off('click').on('click', e => {
- this.onClickHandler($(e.currentTarget));
- });
- }
- }
-
- formatDate(date) {
- return moment(date).format('HH:mm:ss');
- }
-
- dataKey() {
- return this.formatDate(this.entry.start_time);
- }
-
- render(is_pgadmin_queries_shown) {
- this.$el = $(
- `
-
-
-
- ${_.escape(this.entry.query)}
-
-
-
${this.formatDate(this.entry.start_time)}
-
-
- `
- )
- .data('entrydata', this.entry)
- .on('click', e => {
- this.onClickHandler($(e.currentTarget));
- });
-
- let query_source = this.entry.query_source;
- if(query_source)
- this.$el.find('#query_source_icon')
- .addClass(query_source.ICON_CSS_CLASS)
- .attr('role', 'img');
-
- if(this.entry.is_pgadmin_query) {
- this.$el.addClass('pgadmin-query-history-entry');
- if(!is_pgadmin_queries_shown)
- this.$el.addClass('d-none');
- }
- }
-}
-
-export class QueryHistoryEntries {
- constructor(parentNode) {
- this.parentNode = parentNode;
- this.$selectedItem = null;
- this.groupKeyFormat = 'YYYY MM DD';
-
- this.$el = null;
- this.is_pgadmin_queries_shown = null;
- }
-
- onSelectedChange(onSelectedChangeHandler) {
- this.onSelectedChangeHandler = onSelectedChangeHandler;
- }
-
- focus() {
- if (!this.$selectedItem) {
- this.setSelectedListItem(this.$entriesEl.find('.list-item').first());
- }
- this.$selectedItem.trigger('click');
- this.$entriesEl.focus();
- }
-
- isArrowDown(event) {
- return (event.keyCode || event.which) === ARROWDOWN;
- }
-
- isArrowUp(event) {
- return (event.keyCode || event.which) === ARROWUP;
- }
-
- navigateUpAndDown(event) {
- let arrowKeys = [ARROWUP, ARROWDOWN];
- let key = event.keyCode || event.which;
- if (arrowKeys.indexOf(key) > -1) {
- event.preventDefault();
- this.onKeyDownHandler(event);
- return false;
- }
- return true;
- }
-
- onKeyDownHandler(event) {
- if (this.isArrowDown(event)) {
- if (this.$selectedItem.next().length > 0) {
- this.setSelectedListItem(this.$selectedItem.next());
- } else {
- /* if last, jump to next group */
- let $group = this.$selectedItem.closest('.query-group');
- if ($group.next().length > 0) {
- this.setSelectedListItem(
- $group.next().find('.list-item').first()
- );
- }
- }
- } else if (this.isArrowUp(event)) {
- if (this.$selectedItem.prev().length > 0) {
- this.setSelectedListItem(this.$selectedItem.prev());
- } else {
- /* if first, jump to prev group */
- let $group = this.$selectedItem.closest('.query-group');
- if ($group.prev().length > 0) {
- this.setSelectedListItem(
- $group.prev().find('.list-item').last()
- );
- }
- }
- }
- }
-
- onSelectListItem(event) {
- this.setSelectedListItem($(event.currentTarget));
- }
-
- dateAsGroupKey(date) {
- return moment(date).format(this.groupKeyFormat);
- }
-
- setSelectedListItem($listItem) {
- if (this.$selectedItem) {
- this.$selectedItem.removeClass('selected');
- }
- $listItem.addClass('selected');
- this.$selectedItem = $listItem;
-
- this.$selectedItem[0].scrollIntoView({block: 'center'});
-
- if (this.onSelectedChangeHandler) {
- this.onSelectedChangeHandler(this.$selectedItem.data('entrydata'));
- }
- }
-
- addEntry(entry) {
- /* Add the entry in respective date group in descending sorted order. */
- let groups = this.$entriesEl.find('.query-group');
- let groupsKeys = $.map(groups, group => {
- return $(group).attr('data-key');
- });
- let entryGroupKey = this.dateAsGroupKey(entry.start_time);
- let groupIdx = _.indexOf(groupsKeys, entryGroupKey);
-
- let $groupEl = null;
- /* if no groups present */
- if (groups.length == 0) {
- $groupEl = new QueryHistoryEntryDateGroup(
- entry.start_time,
- entryGroupKey
- ).render();
- this.$entriesEl.prepend($groupEl);
- } else if (groupIdx < 0 && groups.length != 0) {
- /* if groups are present, but this is a new group */
- $groupEl = new QueryHistoryEntryDateGroup(
- entry.start_time,
- entryGroupKey
- ).render();
-
- let i=0;
- while(i
groupsKeys[i]) {
- $groupEl.insertBefore(groups[i]);
- break;
- }
- i++;
- }
- if(i == groupsKeys.length) {
- this.$entriesEl.append($groupEl);
- }
- } else if (groupIdx >= 0) {
- /* if the group is present */
- $groupEl = $(groups[groupIdx]);
- }
-
- let newItem = new QueryHistoryItem(entry);
- newItem.onClick(this.setSelectedListItem.bind(this));
- newItem.render(this.is_pgadmin_queries_shown);
-
- if (!_.isUndefined($groupEl)){
- let entries = $groupEl.find('.query-entries').find('.list-item');
- let i=0;
- if(entries.length > 0)
- {
- while(i $(entries[i]).attr('data-key')) {
- $(newItem.$el).insertBefore(entries[i]);
- break;
- }else{
- $(newItem.$el).insertAfter(entries[i]);
- }
- i++;
- }
- } else{
- $groupEl.find('.query-entries').append(newItem.$el);
- }
- }
- this.setSelectedListItem(newItem.$el);
- }
-
- toggleGeneratedQueries() {
- this.$el.find('.pgadmin-query-history-entry').each(function() {
- $(this).toggleClass('d-none');
- });
- this.is_pgadmin_queries_shown = !this.is_pgadmin_queries_shown;
- }
-
- render() {
- let self = this;
- self.$el = $(`
-
-
-
- ` + gettext('Show queries generated internally by pgAdmin?') + `
-
-
-
-
-
- `);
-
- self.$entriesEl = self.$el.find('#query_list');
- self.$entriesEl.on('keydown', this.navigateUpAndDown.bind(this));
-
- self.is_pgadmin_queries_shown = true;
-
- self.$el.find('#generated-queries-toggle').bootstrapToggle().change(
- function() {
- self.toggleGeneratedQueries();
- }
- );
-
- self.parentNode.empty().append(self.$el);
- }
-}
diff --git a/web/pgadmin/static/js/sqleditor/history/query_sources.js b/web/pgadmin/static/js/sqleditor/history/query_sources.js
deleted file mode 100644
index a3e3a3792..000000000
--- a/web/pgadmin/static/js/sqleditor/history/query_sources.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-/* This file contains the source of the queries in the history and their
- respective icons css classes */
-
-export const QuerySources = {
- EXECUTE: {
- ICON_CSS_CLASS: 'fa fa-play',
- },
- EXPLAIN: {
- ICON_CSS_CLASS: 'fa fa-hand-pointer',
- },
- EXPLAIN_ANALYZE: {
- ICON_CSS_CLASS: 'fa fa-list-alt',
- },
- COMMIT: {
- ICON_CSS_CLASS: 'pg-font-icon icon-commit',
- },
- ROLLBACK: {
- ICON_CSS_CLASS: 'pg-font-icon icon-rollback',
- },
- SAVE_DATA: {
- ICON_CSS_CLASS: 'pg-font-icon icon-save_data_changes',
- },
- VIEW_DATA: {
- ICON_CSS_CLASS: 'pg-font-icon picon-view_data',
- },
-};
diff --git a/web/pgadmin/static/js/sqleditor/macro.js b/web/pgadmin/static/js/sqleditor/macro.js
deleted file mode 100644
index ff470c9d5..000000000
--- a/web/pgadmin/static/js/sqleditor/macro.js
+++ /dev/null
@@ -1,341 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import gettext from 'sources/gettext';
-import url_for from 'sources/url_for';
-import $ from 'jquery';
-import _ from 'underscore';
-import Alertify from 'pgadmin.alertifyjs';
-import pgAdmin from 'sources/pgadmin';
-import Backform from 'pgadmin.backform';
-import macroModel from 'sources/sqleditor/macro_model';
-import axios from 'axios';
-import Notify from '../../../static/js/helpers/Notifier';
-
-let MacroDialog = {
- 'dialog': function(handler) {
- let title = gettext('Manage Macros');
-
- // Check the alertify dialog already loaded then delete it to clear
- // the cache
- if (Alertify.macroDialog) {
- delete Alertify.macroDialog;
- }
-
- // Create Dialog
- Alertify.dialog('macroDialog', function factory() {
- let $container = $('
');
- return {
- main: function() {
- this.set('title', ' ' + gettext('Manage Macros'));
- },
- build: function() {
- this.elements.content.appendChild($container.get(0));
- Alertify.pgDialogBuild.apply(this);
- },
- setup: function() {
- return {
- buttons: [{
- text: '',
- key: 112,
- className: 'btn btn-primary-icon pull-left fa fa-question pg-alertify-icon-button',
- attrs: {
- name: 'dialog_help',
- type: 'button',
- label: gettext('Help'),
- 'aria-label': gettext('Help'),
- url: url_for('help.static', {
- 'filename': 'query_tool.html',
- }),
- },
- }, {
- text: gettext('Cancel'),
- key: 27,
- className: 'btn btn-secondary fa fa-times pg-alertify-button',
- 'data-btn-name': 'cancel',
- }, {
- text: gettext('Save'),
- className: 'btn btn-primary fa fa-save pg-alertify-button',
- 'data-btn-name': 'ok',
- }],
- focus: {
- element: function(){
- /*
- returning false will focus nothing, but it will make
- contents behind the modal accessible via Tab key,
- so focus the dialog itself instead.
- */
- return $(this.elements.dialog).find('.header-icon-cell button')[0];
- },
- select: true,
- },
- // Set options for dialog
- options: {
- title: title,
- //disable both padding and overflow control.
- padding: !1,
- overflow: !1,
- model: 0,
- resizable: true,
- maximizable: true,
- pinnable: false,
- closableByDimmer: false,
- modal: false,
- autoReset: false,
- },
- };
- },
- hooks: {
- // triggered when the dialog is closed
- onclose: function() {
- if (this.view) {
- this.macroCollectionModel.stopSession();
- this.view.model.stopSession();
- this.view.remove({
- data: true,
- internal: true,
- silent: true,
- });
- }
- },
- },
- prepare: function() {
- let self = this;
- $container.html('');
- // Status bar
- this.statusBar = $(
- '' +
- ' ' +
- '
').appendTo($container);
-
- // To show progress on filter Saving/Updating on AJAX
- this.showFilterProgress = $(
- `
-
-
-
` + gettext('Loading data...') + `
-
-
`
- ).appendTo($container);
-
- self.macroCollectionModel = macroModel(handler.transId);
-
- let fields = Backform.generateViewSchema(
- null, self.macroCollectionModel, 'edit', null, null, true
- );
-
- let ManageMacroDialog = Backform.Dialog.extend({
- template: {
- 'panel': _.template(
- '
'
- ),
- },
- render: function() {
- this.cleanup();
-
- var m = this.model,
- controls = this.controls,
- tmpls = this.template,
- dialog_obj = this,
- idx = (this.tabIndex * 100),
- evalF = function(f, d, model) {
- return (_.isFunction(f) ? !!f.apply(d, [model]) : !!f);
- };
-
- this.$el
- .empty()
- .attr('role', 'tabpanel')
- .attr('class', _.result(this, 'tabPanelClassName'));
- m.panelEl = this.$el;
-
- var tabContent = $('
')
- .appendTo(this.$el);
-
- _.each(this.schema, function(o) {
- idx++;
- if (!o.version_compatible || !evalF(o.visible, o, m)) {
- return;
- }
- var el = $((tmpls['panel'])(_.extend(o, {
- 'tabIndex': idx,
- 'tabPanelCodeClass': o.tabPanelCodeClass ? o.tabPanelCodeClass : '',
- })))
- .appendTo(tabContent)
- .removeClass('collapse').addClass('collapse');
-
- o.fields.each(function(f) {
- var cntr = new(f.get('control'))({
- field: f,
- model: m,
- dialog: dialog_obj,
- tabIndex: idx,
- });
- el.append(cntr.render().$el);
- controls.push(cntr);
- });
- });
-
- tabContent.find('.tab-pane').first().addClass('active show');
-
- return this;
- },
- });
-
- let view = self.view = new ManageMacroDialog({
- el: '
',
- model: self.macroCollectionModel,
- schema: fields,
- });
-
- self.macroCollectionModel.fetch({
- success: function() {
-
- // We got the latest attributes of the object. Render the view
- // now.
- $container.append(self.view.render().$el);
- self.__internal.buttons[2].element.disabled = true;
-
-
- // Enable/disable save button and show/hide statusbar based on session
- self.view.listenTo(self.view.model, 'pgadmin-session:start', function() {
- self.view.listenTo(self.view.model, 'pgadmin-session:invalid', function(msg) {
- self.statusBar.removeClass('d-none');
- $(self.statusBar.find('.alert-text')).html(msg);
- // Disable Okay button
- self.__internal.buttons[2].element.disabled = true;
- });
-
- view.listenTo(self.view.model, 'pgadmin-session:valid', function() {
- self.statusBar.addClass('d-none');
- $(self.statusBar.find('.alert-text')).html('');
- // Enable Okay button
- self.__internal.buttons[2].element.disabled = false;
- });
- });
-
- view.listenTo(self.view.model, 'pgadmin-session:stop', function() {
- view.stopListening(self.view.model, 'pgadmin-session:invalid');
- view.stopListening(self.view.model, 'pgadmin-session:valid');
- });
-
- // Starts monitoring changes to model
- self.view.model.startNewSession();
-
- }});
-
- $(this.elements.body.childNodes[0]).addClass(
- 'alertify_tools_dialog_properties obj_properties'
- );
-
-
-
- },
- // Callback functions when click on the buttons of the Alertify dialogs
- callback: function(e) {
- let self = this;
-
- if (e.button.element.name == 'dialog_help') {
- e.cancel = true;
- pgAdmin.Browser.showHelp(e.button.element.name, e.button.element.getAttribute('url'),
- null, null);
- } else if (e.button['data-btn-name'] === 'ok') {
- e.cancel = true; // Do not close dialog
-
- let data = self.view.model.get('macro').toJSON(true);
-
- if (data == undefined || data == null) {
- self.close();
- return;
- }
-
- axios.put(
- url_for('sqleditor.set_macros', {
- 'trans_id': handler.transId,
- }),
- data
- ).then(function (result) {
- // Hide Progress ...
- $(
- self.showFilterProgress[0]
- ).addClass('d-none');
-
- let macroResponse = result;
-
- if (macroResponse.status) {
- setTimeout(
- function() {
- // Update Macro Menu
- let macros = self.view.model.get('macro').toJSON().filter(m => m.name !== undefined || m.name !== null);
- handler.macros = macros;
- var str = `
-
-
- ${gettext('Manage Macros...')}
-
- `;
-
- let macro_list_tmpl = '';
- _.each(macros, function(m) {
- if (m.name) {
- macro_list_tmpl += `
-
- ${_.escape(m.name)}
- (${m.key_label})
-
- `;
- }
- });
-
- if (macro_list_tmpl.length > 0) str += ' ' + macro_list_tmpl;
- $($.find('div.btn-group.mr-1.user_macros ul.dropdown-menu')).html($(str));
-
- self.close(); // Close the dialog now
- Notify.success(gettext('Macro updated successfully'));
- }, 10
- );
- } else {
- Notify.alert(
- gettext('Validation Error'),
- macroResponse.result
- );
- }
-
- }).catch(function (error) {
- // Hide Progress ...
- $(
- self.showFilterProgress[0]
- ).addClass('d-none');
-
- setTimeout(
- function() {
- Notify.error(error.response.data.errormsg);
- }, 10
- );
- });
-
- } else {
- self.close();
- }
- },
- };
- });
-
- Alertify.macroDialog(title).resizeTo(pgAdmin.Browser.stdW.calc(pgAdmin.Browser.stdW.lg),
- pgAdmin.Browser.stdH.calc(pgAdmin.Browser.stdH.lg));
- },
-};
-
-module.exports = MacroDialog;
diff --git a/web/pgadmin/static/js/sqleditor/macro_model.js b/web/pgadmin/static/js/sqleditor/macro_model.js
deleted file mode 100644
index a9c316e68..000000000
--- a/web/pgadmin/static/js/sqleditor/macro_model.js
+++ /dev/null
@@ -1,225 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import gettext from 'sources/gettext';
-import pgAdmin from 'sources/pgadmin';
-import Backform from 'pgadmin.backform';
-import Backgrid from 'pgadmin.backgrid';
-import url_for from 'sources/url_for';
-import $ from 'jquery';
-import _ from 'underscore';
-import Notify from '../helpers/Notifier';
-
-export default function macroModel(transId) {
-
- let MacroModel = pgAdmin.Browser.DataModel.extend({
- idAttribute: 'id',
- defaults: {
- id: undefined,
- key: undefined,
- name: undefined,
- sql: undefined,
- key_label: undefined,
- },
- schema: [{
- id: 'key_label',
- name: 'key_label',
- label: gettext('Key'),
- type: 'text',
- cell: 'string',
- editable: false,
- cellHeaderClasses: 'width_percent_10',
- headerCell: Backgrid.Extension.CustomHeaderCell,
- disabled: false,
- }, {
- id: 'name',
- name: 'name',
- label: gettext('Name'),
- cell: 'string',
- type: 'text',
- editable: true,
- cellHeaderClasses: 'width_percent_20',
- headerCell: Backgrid.Extension.CustomHeaderCell,
- disabled: false,
- }, {
- id: 'sql',
- name: 'sql',
- label: gettext('SQL'),
- cell: Backgrid.Extension.SqlCell,
- type: 'multiline',
- control: Backform.SqlCodeControl,
- editable: true,
- cellHeaderClasses: 'width_percent_70',
- headerCell: Backgrid.Extension.CustomHeaderCell,
- disabled: false,
- },
- ],
- validate: function() {
- let msg = null;
- this.errorModel.clear();
- if (_.isEmpty(this.get('name')) && !(_.isEmpty(this.get('sql')))) {
- msg = gettext('Please enter macro name.');
- this.errorModel.set('name', msg);
- return msg;
- } else if (_.isEmpty(this.get('sql')) && !(_.isEmpty(this.get('name')))) {
- msg = gettext('Please enter macro sql.');
- this.errorModel.set('sql', msg);
- return msg;
- }
- return null;
- },
- });
-
- let MacroCollectionModel = pgAdmin.Browser.DataModel.extend({
- defaults: {
- macro: undefined,
- },
- urlRoot: url_for('sqleditor.get_macros', {'trans_id': transId}),
- schema: [{
- id: 'macro',
- name: 'macro',
- label: gettext('Macros'),
- model: MacroModel,
- editable: true,
- type: 'collection',
- control: Backform.SubNodeCollectionControl.extend({
- showGridControl: function(data) {
- var self = this,
- gridBody = $('
');
-
- var subnode = data.subnode.schema ? data.subnode : data.subnode.prototype,
- gridSchema = Backform.generateGridColumnsFromModel(
- data.node_info, subnode, this.field.get('mode'), data.columns, data.schema_node
- );
-
- // Clean up existing grid if any (in case of re-render)
- if (self.grid) {
- self.grid.remove();
- }
-
- // Set visibility of Add button
- if (data.disabled || data.canAdd == false) {
- $(gridBody).find('button.add').remove();
- }
-
- // Insert Clear Cell into Grid
- gridSchema.columns.unshift({
- name: 'pg-backform-clear',
- label: ' ',
- cell: Backgrid.Extension.ClearCell,
- editable: false,
- cell_priority: -1,
- sortable: false,
- headerCell: Backgrid.Extension.CustomHeaderCell.extend({
- className: 'header-icon-cell',
- events: {
- 'click': 'clearrAll',
- },
- clearrAll: function(e) {
- e.preventDefault();
- var that = this;
- // We will check if row is deletable or not
-
- let macros = that.collection.toJSON().filter(m => m.name !== undefined && m.name !== null);
-
- if (macros.length > 0) {
- Notify.confirm(
- gettext('Clear All Rows'),
- gettext('Are you sure you wish to clear all rows?'),
- function() {
- _.each(that.collection.toJSON(), function(m) {
- that.collection.get(m.id).set({'name': null, 'sql': null});
- });
- },
- function() {
- return true;
- }
- );
- }
- },
- render: function() {
- this.$el.empty();
- var column = this.column;
- var label = $('').html(column.get('label')).append(' ');
-
- this.$el.append(label);
- this.$el.addClass(column.get('name'));
- this.$el.addClass(column.get('direction'));
- this.$el.attr('role', 'columnheader');
- this.$el.attr('aria-label', 'columnheader');
- this.$el.attr('alt', 'columnheader');
- this.delegateEvents();
- return this;
-
- },
- }),
- });
-
-
- var collection = self.model.get(data.name);
-
- if (!collection) {
- collection = new(pgAdmin.Browser.Node.Collection)(null, {
- handler: self.model.handler || self.model,
- model: data.model,
- top: self.model.top || self.model,
- silent: true,
- });
- self.model.set(data.name, collection, {
- silent: true,
- });
- }
-
- var cellEditing = function(args) {
- var ctx = this,
- cell = args[0];
- // Search for any other rows which are open.
- this.each(function(m) {
- // Check if row which we are about to close is not current row.
- if (cell.model != m) {
- var idx = ctx.indexOf(m);
- if (idx > -1) {
- var row = grid.body.rows[idx],
- rowEditCell = row.$el.find('.subnode-edit-in-process').parent();
- // Only close row if it's open.
- if (rowEditCell.length > 0) {
- var event = new Event('click');
- rowEditCell[0].dispatchEvent(event);
- }
- }
- }
- });
- };
- // Listen for any row which is about to enter in edit mode.
- collection.on('enteringEditMode', cellEditing, collection);
-
- // Initialize a new Grid instance
- var grid = self.grid = new Backgrid.Grid({
- columns: gridSchema.columns,
- collection: collection,
- row: this.row,
- className: 'backgrid table presentation table-bordered table-noouter-border table-hover',
- });
-
- // Render subNode grid
- var subNodeGrid = grid.render().$el;
-
- return gridBody.append(subNodeGrid);
- },
- }),
- columns: ['key_label', 'name', 'sql'],
- visible: true,
- }],
- validate: function() {
- return null;
- },
- });
-
- return new MacroCollectionModel();
-}
diff --git a/web/pgadmin/static/js/sqleditor/new_connection_dialog.js b/web/pgadmin/static/js/sqleditor/new_connection_dialog.js
deleted file mode 100644
index 6752ec3d4..000000000
--- a/web/pgadmin/static/js/sqleditor/new_connection_dialog.js
+++ /dev/null
@@ -1,289 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import gettext from 'sources/gettext';
-import url_for from 'sources/url_for';
-import $ from 'jquery';
-import Alertify from 'pgadmin.alertifyjs';
-import pgAdmin from 'sources/pgadmin';
-import Backform from 'pgadmin.backform';
-import newConnectionDialogModel from 'sources/sqleditor/new_connection_dialog_model';
-import Notify from 'static/js/helpers/Notifier';
-
-
-let NewConnectionDialog = {
- 'dialog': function(handler, reconnect, preferences) {
- let url = url_for('sqleditor.get_new_connection_data', {
- 'sid': handler.url_params.sid,
- 'sgid': handler.url_params.sgid,
- });
-
- if(reconnect) {
- url += '?connect=1';
- }
-
- let title = gettext('Connect to server');
-
- $.ajax({
- url: url,
- headers: {
- 'Cache-Control' : 'no-cache',
- },
- }).done(function (res) {
- let response = res.data.result;
- response.database_list = [];
- response.user_list = [];
- if (Alertify.newConnectionDialog) {
- delete Alertify.newConnectionDialog;
- }
-
- // Create Dialog
- Alertify.dialog('newConnectionDialog', function factory() {
- let $container = $('
');
- return {
- main: function(message) {
- this.msg = message;
- },
- build: function() {
- this.elements.content.appendChild($container.get(0));
- Alertify.pgDialogBuild.apply(this);
- },
- setup: function(){
- return {
- buttons: [
- {
- text: '',
- key: 112,
- className: 'btn btn-primary-icon pull-left fa fa-question pg-alertify-icon-button',
- attrs: {
- name: 'dialog_help',
- type: 'button',
- label: gettext('Help'),
- 'aria-label': gettext('Help'),
- url: url_for('help.static', {
- 'filename': 'query_tool.html',
- }),
- },
- },
- {
- text: gettext('Cancel'),
- key: 27,
- className: 'btn btn-secondary fa fa-times pg-alertify-button',
- 'data-btn-name': 'cancel',
- }, {
- text: gettext('OK'),
- key: 13,
- className: 'btn btn-primary fa fa-check pg-alertify-button',
- 'data-btn-name': 'ok',
- },
- ],
- focus: {
- element: function(){
- /*
- returning false will focus nothing, but it will make
- contents behind the modal accessible via Tab key,
- so focus the dialog itself instead.
- */
- return $(this.elements.dialog).find('.new-connection-dialog .nav-link.active.show');
- },
- select: true,
- },
- // Set options for dialog
- options: {
- title: title,
- //disable both padding and overflow control.
- padding: !1,
- overflow: !1,
- model: 0,
- resizable: true,
- maximizable: false,
- pinnable: false,
- closableByDimmer: false,
- modal: false,
- autoReset: false,
- closable: false,
- },
- };
- },
- prepare: function() {
- let self = this;
- $container.html('');
- // Disable Ok button
- this.__internal.buttons[2].element.disabled = true;
-
- // Status bar
- this.statusBar = $(
- '' +
- ' ' +
- '
').appendTo($container);
-
- // To show progress on filter Saving/Updating on AJAX
- this.showNewConnectionProgress = $(
- `
-
-
-
` + gettext('Loading data...') + `
-
-
`
- ).appendTo($container);
- $(
- self.showNewConnectionProgress[0]
- ).removeClass('d-none');
-
- self.newConnCollectionModel = newConnectionDialogModel(response, handler.url_params.sgid, handler.url_params.sid, handler, self);
- let fields = Backform.generateViewSchema(null, self.newConnCollectionModel, 'create', null, null, true);
-
- let view = this.view = new Backform.Dialog({
- el: '
',
- model: self.newConnCollectionModel,
- schema: fields,
- });
-
- $(this.elements.body.childNodes[0]).addClass(
- 'alertify_tools_dialog_properties obj_properties'
- );
-
- $container.append(view.render().$el);
-
- // Enable/disable save button and show/hide statusbar based on session
- view.listenTo(view.model, 'pgadmin-session:start', function() {
- view.listenTo(view.model, 'pgadmin-session:invalid', function(msg) {
- self.statusBar.removeClass('d-none');
- $(self.statusBar.find('.alert-text')).html(msg);
- // Disable Okay button
- if(self.__internal){
- self.__internal.buttons[2].element.disabled = true;
- }
- });
-
- view.listenTo(view.model, 'pgadmin-session:valid', function() {
- self.statusBar.addClass('d-none');
- $(self.statusBar.find('.alert-text')).html('');
- // Enable Okay button
- if(self.__internal) {
- self.__internal.buttons[2].element.disabled = false;
- }
- });
- });
-
- view.listenTo(view.model, 'pgadmin-session:stop', function() {
- view.stopListening(view.model, 'pgadmin-session:invalid');
- view.stopListening(view.model, 'pgadmin-session:valid');
- });
-
- // Starts monitoring changes to model
- view.model.startNewSession();
-
- // Hide Progress ...
- $(
- self.showNewConnectionProgress[0]
- ).addClass('d-none');
- },
- get_title: function(qt_title_placeholder, selected_database_name, newConnCollectionModel, tmpResponse) {
- qt_title_placeholder = qt_title_placeholder.replace(new RegExp('%DATABASE%'), selected_database_name);
- if(newConnCollectionModel['role']) {
- qt_title_placeholder = qt_title_placeholder.replace(new RegExp('%USERNAME%'), newConnCollectionModel['role']);
- } else {
- qt_title_placeholder = qt_title_placeholder.replace(new RegExp('%USERNAME%'), newConnCollectionModel['user']);
- }
-
- qt_title_placeholder = qt_title_placeholder.replace(new RegExp('%SERVER%'), tmpResponse.server_name);
- return qt_title_placeholder;
- },
- callback: function(e) {
- let self = this;
- if (e.button.element.name == 'dialog_help') {
- e.cancel = true;
- pgAdmin.Browser.showHelp(e.button.element.name, e.button.element.getAttribute('url'),
- null, null);
- } else if (e.button['data-btn-name'] === 'ok') {
- e.cancel = true; // Do not close dialog
- let newConnCollectionModel = this.newConnCollectionModel.toJSON();
-
- let selected_database_name = null;
- response.database_list.forEach(function(data){
- if(newConnCollectionModel['database'] == data['value']) {
- selected_database_name = data['label'];
- return false;
- }
- });
- let tab_title = '';
- var qt_title_placeholder = preferences['qt_tab_title_placeholder'];
-
- tab_title = this.get_title(qt_title_placeholder, selected_database_name, newConnCollectionModel, response);
- let qt_default_placeholder = pgAdmin['qt_default_placeholder'];
- let conn_title = this.get_title(qt_default_placeholder, selected_database_name, newConnCollectionModel, response);
-
- if(!newConnCollectionModel['role']) {
- newConnCollectionModel['role'] = null;
- }
-
- let is_create_connection = true;
-
- handler.gridView.connection_list.forEach(function(connection_data) {
- if(parseInt(connection_data['server']) == newConnCollectionModel['server']
- && parseInt(connection_data['database']) == newConnCollectionModel['database']
- && connection_data['user'] == newConnCollectionModel['user'] && connection_data['role'] == newConnCollectionModel['role']) {
- is_create_connection = false;
- return false;
- }
- });
- if(!is_create_connection) {
- let errmsg = 'Connection with this configuration already present.';
- Notify.info(errmsg);
- } else {
- let connection_details = {
- 'server_group': handler.gridView.handler.url_params.sgid,
- 'server': newConnCollectionModel['server'],
- 'database': newConnCollectionModel['database'],
- 'title': _.escape(tab_title),
- 'conn_title': _.escape(conn_title),
- 'user': newConnCollectionModel['user'],
- 'role': newConnCollectionModel['role'],
- 'server_name': _.escape(response.server_name),
- 'database_name': _.escape(selected_database_name),
- 'password': response.password,
- 'is_selected': false,
- };
- handler.gridView.on_change_connection(connection_details, self);
- }
- } else {
- Alertify.newConnectionDialog().destroy();
- }
- },
- };
- });
-
- setTimeout(function(){
- Alertify.newConnectionDialog('Connect to server.').resizeTo(pgAdmin.Browser.stdW.md,pgAdmin.Browser.stdH.md);
- }, 500);
- }).fail(function() {
- Notify.alert().setting({
- 'title': gettext('Connection lost'),
- 'label':gettext('OK'),
- 'message': gettext('Connection to the server has been lost.'),
- 'onok': function(){
- //Close the window after connection is lost
- window.close();
- },
- }).show();
- });
-
- },
-
-};
-
-module.exports = NewConnectionDialog;
diff --git a/web/pgadmin/static/js/sqleditor/new_connection_dialog_model.js b/web/pgadmin/static/js/sqleditor/new_connection_dialog_model.js
deleted file mode 100644
index 6ee34ff86..000000000
--- a/web/pgadmin/static/js/sqleditor/new_connection_dialog_model.js
+++ /dev/null
@@ -1,477 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import gettext from 'sources/gettext';
-import _ from 'underscore';
-import $ from 'jquery';
-import pgAdmin from 'sources/pgadmin';
-import Backform from 'pgadmin.backform';
-import url_for from 'sources/url_for';
-import alertify from 'pgadmin.alertifyjs';
-import Notify from '../helpers/Notifier';
-
-
-export default function newConnectionDialogModel(response, sgid, sid, handler, conn_self) {
-
- let server_name = '';
- let database_name = '';
-
- let NewConnectionSelect2Control = Backform.Select2Control.extend({
- fetchData: function(){
- let self = this;
- let url = self.field.get('url');
-
- url = url_for(url, {
- 'sid': self.model.attributes.server,
- 'sgid': sgid,
- });
-
- $.ajax({
- url: url,
- headers: {
- 'Cache-Control' : 'no-cache',
- },
- }).done(function (res) {
- var transform = self.field.get('transform');
- if(res.data.status){
- let data = res.data.result.data;
-
- if (transform && _.isFunction(transform)) {
- self.field.set('options', transform.bind(self, data));
- } else {
- self.field.set('options', data);
- }
- } else {
- if (transform && _.isFunction(transform)) {
- self.field.set('options', transform.bind(self, []));
- } else {
- self.field.set('options', []);
- }
- }
- Backform.Select2Control.prototype.render.apply(self, arguments);
- }).fail(function(e){
- let msg = '';
- if(e.status == 404) {
- msg = 'Unable to find url.';
- } else {
- msg = e.responseJSON.errormsg;
- }
- Notify.error(msg);
- });
- },
- render: function() {
- this.fetchData();
- return Backform.Select2Control.prototype.render.apply(this, arguments);
- },
- onChange: function() {
- Backform.Select2Control.prototype.onChange.apply(this, arguments);
- },
- });
-
- var formatNode = function (opt) {
- if (!opt.id) {
- return opt.text;
- }
-
- var optimage = $(opt.element).data('image');
-
- if (!optimage) {
- return opt.text;
- } else {
- return $(' ').append(
- $(' ', {
- class: 'wcTabIcon ' + optimage,
- })
- ).append($(' ').text(opt.text));
- }
- };
-
- let newConnectionModel = pgAdmin.Browser.DataModel.extend({
- idAttribute: 'name',
- defaults: {
- server: parseInt(sid),
- database: null,
- user: null,
- server_name: server_name,
- database_name: database_name,
- },
- schema: [
- {
- id: 'server',
- name: 'server',
- label: gettext('Server'),
- type: 'text',
- editable: true,
- disabled: false,
- select2: {
- allowClear: false,
- width: 'style',
- templateResult: formatNode,
- templateSelection: formatNode,
- },
- events: {
- 'focus select': 'clearInvalid',
- 'keydown :input': 'processTab',
- 'select2:select': 'onSelect',
- 'select2:selecting': 'beforeSelect',
- 'select2:clear': 'onChange',
- },
- transform: function(data) {
- let group_template_options = [];
- for (let key in data) {
- if (data.hasOwnProperty(key)) {
- group_template_options.push({'group': key, 'optval': data[key]});
- }
- }
- return group_template_options;
- },
- control: Backform.Select2Control.extend({
- template: _.template([
- '<% if(label == false) {} else {%>',
- ' <%=label%> ',
- '<% }%>',
- '',
- ' ',
- ' <% if (helpMessage && helpMessage.length) { %>',
- ' <%=helpMessage%> ',
- ' <% } %>',
- '
',
- ].join('\n')),
- beforeSelect: function() {
- var selVal = arguments[0].params.args.data.id;
-
- if(this.field.get('connect') && this.$el.find('option[value="'+selVal+'"]').attr('data-connected') !== 'connected') {
- this.field.get('connect').apply(this, [selVal, this.changeIcon.bind(this)]);
- } else {
- $(this.$sel).trigger('change');
- setTimeout(function(){ this.onChange.apply(this); }.bind(this), 200);
- }
- },
- changeIcon: function(data) {
- let span = this.$el.find('.select2-selection .select2-selection__rendered span.wcTabIcon'),
- selSpan = this.$el.find('option:selected');
-
- if (span.hasClass('icon-server-not-connected') || span.hasClass('icon-shared-server-not-connected')) {
- let icon = (data.icon) ? data.icon : 'icon-pg';
- span.removeClass('icon-server-not-connected');
- span.addClass(icon);
- span.attr('data-connected', 'connected');
-
- selSpan.data().image = icon;
- selSpan.attr('data-connected', 'connected');
- alertify.connectServer().destroy();
- this.onChange.apply(this);
- }
- else if (span.hasClass('icon-database-not-connected')) {
- let icon = (data.icon) ? data.icon : 'pg-icon-database';
-
- span.removeClass('icon-database-not-connected');
- span.addClass(icon);
- span.attr('data-connected', 'connected');
-
- selSpan.removeClass('icon-database-not-connected');
- selSpan.data().image = icon;
- selSpan.attr('data-connected', 'connected');
- alertify.connectServer().destroy();
- this.onChange.apply(this);
- }
- },
- connect: function(self) {
- let local_self = self;
-
- if(alertify.connectServer) {
- delete alertify.connectServer;
- }
-
- alertify.dialog('connectServer', function factory() {
- return {
- main: function(
- title, message, server_id, submit_password=true, connect_server=null,
- ) {
- this.set('title', title);
- this.message = message;
- this.server_id = server_id;
- this.submit_password = submit_password;
- this.connect_server = connect_server;
- },
- setup:function() {
- return {
- buttons:[{
- text: gettext('Cancel'), className: 'btn btn-secondary fa fa-times pg-alertify-button',
- key: 27,
- },{
- text: gettext('OK'), key: 13, className: 'btn btn-primary fa fa-check pg-alertify-button',
- }],
- focus: {element: '#password', select: true},
- options: {
- modal: 0, resizable: false, maximizable: false, pinnable: false,
- },
- };
- },
- build:function() { /*This is intentional (SonarQube)*/
- },
- prepare:function() {
- this.setContent(this.message);
- },
- callback: function(closeEvent) {
- var loadingDiv = $('#show_filter_progress');
- if (closeEvent.button.text == gettext('OK')) {
- if(this.submit_password) {
- var _url = url_for('sqleditor.connect_server', {'sid': this.server_id});
-
- loadingDiv.removeClass('d-none');
- $.ajax({
- type: 'POST',
- timeout: 30000,
- url: _url,
- data: $('#frmPassword').serialize(),
- })
- .done(function(res) {
-
- local_self.model.attributes.database = null;
- local_self.changeIcon(res.data);
- local_self.model.attributes.user = null;
- local_self.model.attributes.role = null;
- Backform.Select2Control.prototype.onChange.apply(local_self, arguments);
- Object.keys(response.server_list).forEach(key => {
- response.server_list[key].forEach(option => {
- if (option.value == local_self.getValueFromDOM()) {
- response.server_name = option.label;
- }
- });
- });
-
- loadingDiv.addClass('d-none');
- alertify.connectServer().destroy();
- })
- .fail(function(xhr) {
- loadingDiv.addClass('d-none');
- alertify.connectServer().destroy();
- alertify.connectServer('Connect to server', xhr.responseJSON.result, local_self.getValueFromDOM());
- });
- } else {
- if(Object.keys(this.connect_server).length > 0) {
- this.connect_server['password'] = $('#password').val();
- this.connect_server['is_selected'] = false;
- handler.gridView.on_change_connection(this.connect_server, conn_self, false);
- loadingDiv = $('#fetching_data');
- loadingDiv.addClass('d-none');
- } else {
- response.password = $('#password').val();
- loadingDiv.addClass('d-none');
- }
- }
- } else {
- local_self.model.attributes.database = null;
- local_self.model.attributes.user = null;
- local_self.model.attributes.role = null;
- Backform.Select2Control.prototype.onChange.apply(local_self, arguments);
- loadingDiv.addClass('d-none');
- alertify.connectServer().destroy();
-
- }
- closeEvent.close = true;
- },
- };
- });
- },
- render: function() {
- let self = this;
- self.connect(self);
- Object.keys(response.server_list).forEach(key => {
- response.server_list[key].forEach(option => {
- if (option.value == parseInt(sid)) {
- response.server_name = option.label;
- }
- });
- });
- var transform = self.field.get('transform') || self.defaults.transform;
- if (transform && _.isFunction(transform)) {
- self.field.set('options', transform.bind(self, response.server_list));
- } else {
- self.field.set('options', response.server_list);
- }
- return Backform.Select2Control.prototype.render.apply(self, arguments);
- },
- onChange: function() {
- this.model.attributes.database = null;
- this.model.attributes.user = null;
- let self = this;
- self.connect(self);
-
- let url = url_for('sqleditor.connect_server', {
- 'sid': self.getValueFromDOM(),
- 'usr': self.model.attributes.user,
- });
- var loadingDiv = $('#show_filter_progress');
- loadingDiv.removeClass('d-none');
- $.ajax({
- url: url,
- type: 'POST',
- headers: {
- 'Cache-Control' : 'no-cache',
- },
- }).done(function () {
- Backform.Select2Control.prototype.onChange.apply(self, arguments);
- Object.keys(response.server_list).forEach(key => {
- response.server_list[key].forEach(option => {
- if (option.value == self.getValueFromDOM()) {
- response.server_name = option.label;
- }
- });
- });
- loadingDiv.addClass('d-none');
- }).fail(function(xhr){
- loadingDiv.addClass('d-none');
- alertify.connectServer('Connect to server', xhr.responseJSON.result, self.getValueFromDOM());
- });
-
- },
- }),
- },
- {
- id: 'database',
- name: 'database',
- label: gettext('Database'),
- type: 'text',
- editable: true,
- disabled: function(m) {
- let self_local = this;
- if (!_.isUndefined(m.get('server')) && !_.isNull(m.get('server'))
- && m.get('server') !== '') {
- setTimeout(function() {
- if(self_local.options.length) {
- self_local.options.forEach(db => {
- if (db.selected) {
- m.set('database', db.value);
- }
- });
- }
- }, 10);
- return false;
- }
-
- return true;
- },
- deps: ['server'],
- url: 'sqleditor.get_new_connection_database',
- select2: {
- allowClear: false,
- width: '100%',
- first_empty: true,
- select_first: false,
- },
- extraClasses:['new-connection-dialog-style'],
- control: NewConnectionSelect2Control,
- transform: function(data) {
- response.database_list = data;
- return data;
- },
- },
- {
- id: 'user',
- name: 'user',
- label: gettext('User'),
- type: 'text',
- editable: true,
- deps: ['server'],
- select2: {
- allowClear: false,
- width: '100%',
- },
- control: NewConnectionSelect2Control,
- url: 'sqleditor.get_new_connection_user',
- disabled: function(m) {
- let self_local = this;
- if (!_.isUndefined(m.get('server')) && !_.isNull(m.get('server'))
- && m.get('server') !== '') {
- setTimeout(function() {
- if(self_local.options.length) {
- self_local.options.forEach(user => {
- if (user.selected) {
- m.set('user', user.value);
- }
- });
- }
- }, 10);
- return false;
- }
- return true;
- },
- },{
- id: 'role',
- name: 'role',
- label: gettext('Role'),
- type: 'text',
- editable: true,
- deps: ['server'],
- select2: {
- allowClear: false,
- width: '100%',
- first_empty: true,
- },
- control: NewConnectionSelect2Control,
- url: 'sqleditor.get_new_connection_role',
- disabled: false,
- },
- ],
- validate: function() {
- let msg = null;
- this.errorModel.clear();
- if(_.isUndefined(this.get('database')) || _.isNull(this.get('database'))){
- msg = gettext('Please select database');
- this.errorModel.set('database', msg);
- return msg;
- } else if(_.isUndefined(this.get('database')) || _.isUndefined(this.get('user'))|| _.isNull(this.get('user'))) {
- msg = gettext('Please select user');
- this.errorModel.set('user', msg);
- return msg;
- }
- return null;
- },
- });
-
- return new newConnectionModel();
-}
diff --git a/web/pgadmin/static/js/sqleditor/query_tool_actions.js b/web/pgadmin/static/js/sqleditor/query_tool_actions.js
deleted file mode 100644
index 379c8c4d1..000000000
--- a/web/pgadmin/static/js/sqleditor/query_tool_actions.js
+++ /dev/null
@@ -1,172 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import $ from 'jquery';
-import pgWindow from 'sources/window';
-
-let queryToolActions = {
- _verbose: function () {
- return !$('.explain-verbose').hasClass('visibility-hidden');
- },
-
- _costsEnabled: function () {
- return !$('.explain-costs').hasClass('visibility-hidden');
- },
-
- _buffers: function () {
- return !$('.explain-buffers').hasClass('visibility-hidden');
- },
-
- _timing: function () {
- return !$('.explain-timing').hasClass('visibility-hidden');
- },
-
- _summary: function () {
- return !$('.explain-summary').hasClass('visibility-hidden');
- },
-
- _settings: function () {
- return !$('.explain-settings').hasClass('visibility-hidden');
- },
-
- _clearMessageTab: function () {
- $('.sql-editor-message').html('');
- },
-
- executeMacro: function (sqlEditorController, MacroId) {
- this._clearMessageTab();
- sqlEditorController.check_data_changes_to_execute_query(null, false, MacroId);
- },
-
- executeQuery: function (sqlEditorController) {
- this._clearMessageTab();
- sqlEditorController.check_data_changes_to_execute_query();
- },
-
- explainAnalyze: function (sqlEditorController) {
- const explainObject = {
- format: 'json',
- analyze: true,
- verbose: this._verbose(),
- costs: this._costsEnabled(),
- buffers: this._buffers(),
- timing: this._timing(),
- summary: this._summary(),
- settings: this._settings(),
- };
- this._clearMessageTab();
- sqlEditorController.check_data_changes_to_execute_query(explainObject);
- },
-
- explain: function (sqlEditorController) {
- const explainObject = {
- format: 'json',
- analyze: false,
- verbose: this._verbose(),
- costs: this._costsEnabled(),
- buffers: false,
- timing: false,
- summary: this._summary(),
- settings: this._settings(),
- };
- this._clearMessageTab();
- sqlEditorController.check_data_changes_to_execute_query(explainObject);
- },
-
- download: function (sqlEditorController) {
-
- let extension = sqlEditorController.preferences.csv_field_separator === ',' ? '.csv': '.txt';
- let filename = 'data-' + new Date().getTime() + extension;
-
- if (!sqlEditorController.is_query_tool) {
- filename = sqlEditorController.table_name + extension;
- }
-
- sqlEditorController.trigger_csv_download(filename);
- },
-
- commentBlockCode: function (sqlEditorController) {
- let codeMirrorObj = sqlEditorController.gridView.query_tool_obj;
-
- if (!codeMirrorObj.getValue()) return;
-
- codeMirrorObj.toggleComment(codeMirrorObj.getCursor(true), codeMirrorObj.getCursor(false));
- },
-
- commentLineCode: function (sqlEditorController) {
- let codeMirrorObj = sqlEditorController.gridView.query_tool_obj;
-
- if (!codeMirrorObj.getValue()) return;
-
- codeMirrorObj.lineComment(codeMirrorObj.getCursor(true),
- codeMirrorObj.getCursor(false),
- {lineComment: '--'}
- );
- },
-
- uncommentLineCode: function (sqlEditorController) {
- let codeMirrorObj = sqlEditorController.gridView.query_tool_obj;
-
- if (!codeMirrorObj.getValue()) return;
-
- codeMirrorObj.uncomment(codeMirrorObj.getCursor(true),
- codeMirrorObj.getCursor(false),
- {lineComment: '--'}
- );
- },
-
- formatSql: function (sqlEditorController) {
- sqlEditorController.gridView.on_format_sql();
- },
-
- focusOut: function () {
- document.activeElement.blur();
- pgWindow.document.activeElement.blur();
- },
-
- toggleCaseOfSelectedText: function (sqlEditorController) {
- let codeMirrorObj = sqlEditorController.gridView.query_tool_obj;
- let selectedText = codeMirrorObj.getSelection();
-
- if (!selectedText) return;
-
- if (selectedText === selectedText.toUpperCase()) {
- codeMirrorObj.replaceSelection(selectedText.toLowerCase());
- } else {
- codeMirrorObj.replaceSelection(selectedText.toUpperCase());
- }
- },
-
- executeCommit: function (sqlEditorController) {
- var self = this;
- sqlEditorController.special_sql = 'COMMIT;';
- self.executeQuery(sqlEditorController);
- },
-
- executeRollback: function (sqlEditorController) {
- var self = this;
- sqlEditorController.special_sql = 'ROLLBACK;';
- self.executeQuery(sqlEditorController);
- },
-
- saveDataChanges: function (sqlEditorController) {
- sqlEditorController.close_on_save = false;
- sqlEditorController.save_data();
- },
-
- openQueryTool: function (sqlEditorController) {
- sqlEditorController.gridView.handler.trigger(
- 'pgadmin-sqleditor:button:show_query_tool',
- sqlEditorController.gridView,
- sqlEditorController.gridView.handler
- );
- },
-};
-
-module.exports = queryToolActions;
diff --git a/web/pgadmin/static/js/sqleditor/query_tool_http_error_handler.js b/web/pgadmin/static/js/sqleditor/query_tool_http_error_handler.js
deleted file mode 100644
index c5060434e..000000000
--- a/web/pgadmin/static/js/sqleditor/query_tool_http_error_handler.js
+++ /dev/null
@@ -1,78 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////////////////
-import gettext from 'sources/gettext';
-
-export function httpResponseRequiresNewTransaction(xhr) {
- /* If responseJSON is undefined then it could be object of
- * axios(Promise HTTP) response, so we should check accordingly.
- */
- if (xhr.responseJSON === undefined && xhr.data !== undefined) {
- return xhr.status === 404 && xhr.data &&
- xhr.data.info &&
- xhr.data.info === 'DATAGRID_TRANSACTION_REQUIRED';
- }
-
- return xhr.status === 404 && xhr.responseJSON &&
- xhr.responseJSON.info &&
- xhr.responseJSON.info === 'DATAGRID_TRANSACTION_REQUIRED';
-}
-
-// Allow us to redirect to login dialog and if required then re-initiate the transaction
-export function handleLoginRequiredAndTransactionRequired(
- pgAdmin, handler, exception, stateToSave, stateParameters, checkTransaction
-) {
- stateParameters = stateParameters && stateParameters.length > 0 ? stateParameters : [];
- if (pgAdmin.Browser.UserManagement.isPgaLoginRequired(exception)) {
- if (stateToSave) {
- handler.saveState(stateToSave, stateParameters);
- }
- return pgAdmin.Browser.UserManagement.pgaLogin();
- }
-
- if(checkTransaction && httpResponseRequiresNewTransaction(exception)) {
- if (stateToSave) {
- handler.saveState(stateToSave, stateParameters);
- }
- return handler.initTransaction();
- }
-}
-
-// Allow us to handle the AJAX error from Query tool
-export function handleQueryToolAjaxError(
- pgAdmin, handler, exception, stateToSave, stateParameters, checkTransaction
-) {
- if (exception.readyState === 0) {
- return gettext('Not connected to the server or the connection to the server has been closed.');
- }
-
- handleLoginRequiredAndTransactionRequired(
- pgAdmin, handler, exception, stateToSave, stateParameters, checkTransaction
- );
-
- let msg = exception.responseText;
- if (exception.responseJSON !== undefined) {
- if(exception.responseJSON.errormsg !== undefined) {
- msg = exception.responseJSON.errormsg;
- }
-
- if(exception.status === 503 && exception.responseJSON.info !== undefined &&
- exception.responseJSON.info == 'CONNECTION_LOST') {
- // We will display re-connect dialog, no need to display error message again
- msg = null;
- setTimeout(function() {
- if (stateToSave) {
- handler.saveState(stateToSave, stateParameters);
- }
- handler.handle_connection_lost(false, exception);
- });
- }
- }
-
- return msg;
-}
diff --git a/web/pgadmin/static/js/sqleditor/query_tool_notifications.js b/web/pgadmin/static/js/sqleditor/query_tool_notifications.js
deleted file mode 100644
index ddf3ad852..000000000
--- a/web/pgadmin/static/js/sqleditor/query_tool_notifications.js
+++ /dev/null
@@ -1,133 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import gettext from 'sources/gettext';
-import Backgrid from 'pgadmin.backgrid';
-import Backbone from 'backbone';
-import Notify from '../helpers/Notifier';
-
-let NotificationsModel = Backbone.Model.extend({
- defaults: {
- recorded_time: undefined,
- event: undefined,
- pid: undefined,
- payload: undefined,
- },
- schema: [{
- id: 'recorded_time',
- label: gettext('Recorded time'),
- cell: 'string',
- type: 'text',
- editable: false,
- cellHeaderClasses: 'width_percent_20',
- headerCell: Backgrid.Extension.CustomHeaderCell,
- },{
- id: 'channel',
- label: gettext('Event'),
- cell: 'string',
- type: 'text',
- editable: false,
- cellHeaderClasses: 'width_percent_20',
- headerCell: Backgrid.Extension.CustomHeaderCell,
- },{
- id: 'pid',
- label: gettext('Process ID'),
- cell: 'string',
- type: 'text',
- editable: false,
- cellHeaderClasses: 'width_percent_20',
- headerCell: Backgrid.Extension.CustomHeaderCell,
- },{
- id: 'payload',
- label: gettext('Payload'),
- cell: 'string',
- type: 'text',
- editable: false,
- cellHeaderClasses: 'width_percent_40',
- headerCell: Backgrid.Extension.CustomHeaderCell,
- }],
-});
-
-let NotificationCollection = Backbone.Collection.extend({
- model: NotificationsModel,
-});
-
-let queryToolNotifications = {
-
- collection: null,
-
- /* This function is responsible to create and render the
- * new backgrid for the notification tab.
- */
- renderNotificationsGrid: function(notifications_panel) {
- if (!queryToolNotifications.collection)
- queryToolNotifications.collection = new NotificationCollection();
-
- let gridCols = [{
- name: 'recorded_time',
- label: gettext('Recorded time'),
- type: 'text',
- editable: false,
- cell: 'string',
- }, {
- name: 'channel',
- label: gettext('Event'),
- type: 'text',
- editable: false,
- cell: 'string',
- }, {
- name: 'pid',
- label: gettext('Process ID'),
- type: 'text',
- editable: false,
- cell: 'string',
- }, {
- name: 'payload',
- label: gettext('Payload'),
- type: 'text',
- editable: false,
- cell: 'string',
- }];
-
- // Set up the grid
- let notifications_grid = new Backgrid.Grid({
- emptyText: gettext('No data found'),
- columns: gridCols,
- collection: queryToolNotifications.collection,
- className: 'backgrid presentation table table-bordered table-hover table-noouter-border table-bottom-border',
- });
-
- // Render the grid
- if (notifications_panel)
- notifications_panel.$container.find('.sql-editor-notifications').append(notifications_grid.render().el);
- },
-
- // This function is used to raise notify messages and update the
- // notification grid.
- updateNotifications: function(notify_messages) {
- if (notify_messages != null && notify_messages.length > 0) {
- for (let i in notify_messages) {
- let notify_msg = '';
- if (notify_messages[i].payload != '') {
- notify_msg = gettext('Asynchronous notification "%s" with payload "%s" received from server process with PID %s', notify_messages[i].channel, notify_messages[i].payload, notify_messages[i].pid);
- }
- else {
- notify_msg = gettext('Asynchronous notification "%s" received from server process with PID %s', notify_messages[i].channel, notify_messages[i].pid);
- }
-
- Notify.info(notify_msg);
- }
-
- // Add notify messages to the collection.
- queryToolNotifications.collection.add(notify_messages);
- }
- },
-};
-
-module.exports = queryToolNotifications;
diff --git a/web/pgadmin/static/js/sqleditor/query_tool_preferences.js b/web/pgadmin/static/js/sqleditor/query_tool_preferences.js
deleted file mode 100644
index d4cf5ec6a..000000000
--- a/web/pgadmin/static/js/sqleditor/query_tool_preferences.js
+++ /dev/null
@@ -1,241 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import {shortcut_key, shortcut_accesskey_title, shortcut_title}
- from 'sources/keyboard_shortcuts';
-import * as SqlEditorUtils from 'sources/sqleditor_utils';
-import $ from 'jquery';
-import gettext from 'sources/gettext';
-
-function updateUIPreferences(sqlEditor) {
- let $el = sqlEditor.$el,
- preferences = sqlEditor.preferences;
-
- if(sqlEditor.handler.slickgrid) {
- sqlEditor.handler.slickgrid.CSVOptions = {
- quoting: sqlEditor.preferences.results_grid_quoting,
- quote_char: sqlEditor.preferences.results_grid_quote_char,
- field_separator: sqlEditor.preferences.results_grid_field_separator,
- };
- }
-
- /* Accessed using accesskey direct w/o ctrl,atl,shift */
- $el.find('#btn-load-file')
- .attr('title', shortcut_accesskey_title(gettext('Open File'),preferences.btn_open_file))
- .attr('aria-label', shortcut_accesskey_title(gettext('Open File'),preferences.btn_open_file))
- .attr('accesskey', shortcut_key(preferences.btn_open_file));
-
- $el.find('#btn-save-file')
- .attr('title', shortcut_accesskey_title(gettext('Save File'),preferences.btn_save_file))
- .attr('aria-label', shortcut_accesskey_title(gettext('Save File'),preferences.btn_save_file))
- .attr('accesskey', shortcut_key(preferences.btn_save_file));
-
- $el.find('#btn-find-menu-dropdown')
- .attr('title', shortcut_accesskey_title(gettext('Find'),preferences.btn_find_options))
- .attr('aria-label',shortcut_accesskey_title(gettext('Find'),preferences.btn_find_options))
- .attr('accesskey', shortcut_key(preferences.btn_find_options));
-
- $el.find('#btn-copy-row')
- .attr('title', shortcut_accesskey_title(gettext('Copy'),preferences.btn_copy_row))
- .attr('aria-label', shortcut_accesskey_title(gettext('Copy'),preferences.btn_copy_row))
- .attr('accesskey', shortcut_key(preferences.btn_copy_row));
-
- $el.find('#btn-paste-row')
- .attr('title', shortcut_accesskey_title(gettext('Paste'),preferences.btn_paste_row))
- .attr('aria-label', shortcut_accesskey_title(gettext('Paste'),preferences.btn_paste_row))
- .attr('accesskey', shortcut_key(preferences.btn_paste_row));
-
- $el.find('#btn-delete-row')
- .attr('title', shortcut_accesskey_title(gettext('Delete'),preferences.btn_delete_row))
- .attr('aria-label', shortcut_accesskey_title(gettext('Delete'),preferences.btn_delete_row))
- .attr('accesskey', shortcut_key(preferences.btn_delete_row));
-
- $el.find('#btn-filter')
- .attr('title', shortcut_accesskey_title(gettext('Filter'),preferences.btn_filter_dialog))
- .attr('aria-label', shortcut_accesskey_title(gettext('Filter'),preferences.btn_filter_dialog))
- .attr('accesskey', shortcut_key(preferences.btn_filter_dialog));
-
- $el.find('#btn-filter-dropdown')
- .attr('title', shortcut_accesskey_title(gettext('Filter options'),preferences.btn_filter_options))
- .attr('aria-label', shortcut_accesskey_title(gettext('Filter options'),preferences.btn_filter_options))
- .attr('accesskey', shortcut_key(preferences.btn_filter_options));
-
- $el.find('#btn-rows-limit')
- .attr('title', shortcut_accesskey_title(gettext('Rows limit'),preferences.btn_rows_limit))
- .attr('aria-label', shortcut_accesskey_title(gettext('Rows limit'),preferences.btn_rows_limit))
- .attr('accesskey', shortcut_key(preferences.btn_rows_limit));
-
- $el.find('#btn-query-dropdown')
- .attr('title', shortcut_accesskey_title(gettext('Execute options'),preferences.btn_execute_options))
- .attr('aria-label', shortcut_accesskey_title(gettext('Execute options'),preferences.btn_execute_options))
- .attr('accesskey', shortcut_key(preferences.btn_execute_options));
-
- $el.find('#btn-cancel-query')
- .attr('title', shortcut_accesskey_title(gettext('Cancel query'),preferences.btn_cancel_query))
- .attr('aria-label', shortcut_accesskey_title(gettext('Cancel query'),preferences.btn_cancel_query))
- .attr('accesskey', shortcut_key(preferences.btn_cancel_query));
-
- $el.find('#btn-clear-dropdown')
- .attr('title', shortcut_accesskey_title(gettext('Clear'),preferences.btn_clear_options))
- .attr('aria-label', shortcut_accesskey_title(gettext('Clear'),preferences.btn_clear_options))
- .attr('accesskey', shortcut_key(preferences.btn_clear_options));
-
- $el.find('#btn-conn-status')
- .attr('accesskey', shortcut_key(preferences.btn_conn_status))
- .find('i')
- .attr('title',
- shortcut_accesskey_title(gettext('Connection status (click for details)'),
- preferences.btn_conn_status));
-
- /* Accessed using ctrl,atl,shift and key */
- $el.find('#btn-flash')
- .attr('title',
- shortcut_title(gettext('Execute/Refresh'),preferences.execute_query))
- .attr('aria-label',
- shortcut_title(gettext('Execute/Refresh'),preferences.execute_query));
-
- $el.find('#btn-explain')
- .attr('title',
- shortcut_title(gettext('Explain'),preferences.explain_query))
- .attr('aria-label',
- shortcut_title(gettext('Explain'),preferences.explain_query));
-
- $el.find('#btn-explain-analyze')
- .attr('title',
- shortcut_title(gettext('Explain Analyze'),preferences.explain_analyze_query))
- .attr('aria-label',
- shortcut_title(gettext('Explain Analyze'),preferences.explain_analyze_query));
-
- $el.find('#btn-save-results-to-file')
- .attr('title',
- shortcut_title(gettext('Save results to file'),preferences.download_results))
- .attr('aria-label',
- shortcut_title(gettext('Save results to file'),preferences.download_results));
-
- $el.find('#btn-save-data')
- .attr('title',
- shortcut_title(gettext('Save Data Changes'),preferences.save_data))
- .attr('aria-label',
- shortcut_title(gettext('Save Data Changes'),preferences.save_data));
-
- $el.find('#btn-commit')
- .attr('title',
- shortcut_title(gettext('Commit'),preferences.commit_transaction))
- .attr('aria-label',
- shortcut_title(gettext('Commit'),preferences.commit_transaction));
-
- $el.find('#btn-rollback')
- .attr('title',
- shortcut_title(gettext('Rollback'),preferences.rollback_transaction))
- .attr('aria-label',
- shortcut_title(gettext('Rollback'),preferences.rollback_transaction));
-
- $el.find('#btn-show-query-tool')
- .attr('title',
- shortcut_title(gettext('Query tool'),preferences.show_query_tool))
- .attr('aria-label',
- shortcut_title(gettext('Query tool'),preferences.show_query_tool));
-
- /* Set explain options on query editor */
- if (preferences.explain_verbose){
- $el.find('.explain-verbose').removeClass('visibility-hidden');
- }
- else {
- $el.find('.explain-verbose').addClass('visibility-hidden');
- }
-
- if (preferences.explain_costs){
- $el.find('.explain-costs').removeClass('visibility-hidden');
- }
- else {
- $el.find('.explain-costs').addClass('visibility-hidden');
- }
-
- if (preferences.explain_buffers){
- $el.find('.explain-buffers').removeClass('visibility-hidden');
- }
- else {
- $el.find('.explain-buffers').addClass('visibility-hidden');
- }
-
- if (preferences.explain_timing) {
- $el.find('.explain-timing').removeClass('visibility-hidden');
- }
- else {
- $el.find('.explain-timing').addClass('visibility-hidden');
- }
-
- if (preferences.explain_summary) {
- $el.find('.explain-summary').removeClass('visibility-hidden');
- }
- else {
- $el.find('.explain-summary').addClass('visibility-hidden');
- }
-
- if (preferences.explain_settings) {
- $el.find('.explain-settings').removeClass('visibility-hidden');
- }
- else {
- $el.find('.explain-settings').addClass('visibility-hidden');
- }
-
- /* Connection status check */
- /* remove the status checker if present */
- if(sqlEditor.connIntervalId != null) {
- clearInterval(sqlEditor.connIntervalId);
- sqlEditor.connIntervalId = null;
- }
- if (preferences.connection_status) {
- let $conn_status = $el.find('#btn-conn-status'),
- $status_el = $conn_status.find('i');
- $conn_status.popover();
-
- $conn_status.removeClass('connection-status-hide');
-
- // To set initial connection
- SqlEditorUtils.fetchConnectionStatus(sqlEditor.handler, $conn_status, $status_el);
-
- // Calling it again in specified interval
- sqlEditor.connIntervalId = setInterval(
- SqlEditorUtils.fetchConnectionStatus.bind(null, sqlEditor.handler, $conn_status, $status_el),
- preferences.connection_status_fetch_time * 1000
- );
- }
- else {
- $el.find('#btn-conn-status').addClass('connection-status-hide');
- }
-
- /* Code Mirror Preferences */
- let sql_font_size = SqlEditorUtils.calcFontSize(preferences.sql_font_size);
- $(sqlEditor.query_tool_obj.getWrapperElement()).css('font-size', sql_font_size);
-
- if(preferences.plain_editor_mode) {
- sqlEditor.query_tool_obj.setOption('mode', 'text/plain');
- /* Although not required, setting explicitly as codemirror will remove code folding only on next edit */
- sqlEditor.query_tool_obj.setOption('foldGutter', false);
- } else {
- sqlEditor.query_tool_obj.setOption('mode', 'text/x-pgsql');
- sqlEditor.query_tool_obj.setOption('foldGutter', preferences.code_folding);
- }
- sqlEditor.query_tool_obj.setOption('foldGutter', preferences.code_folding);
- sqlEditor.query_tool_obj.setOption('indentWithTabs', !preferences.use_spaces);
- sqlEditor.query_tool_obj.setOption('indentUnit', preferences.use_spaces ? preferences.tab_size : 4);
- sqlEditor.query_tool_obj.setOption('tabSize', preferences.use_spaces ? preferences.tab_size : 4);
- sqlEditor.query_tool_obj.setOption('lineWrapping', preferences.wrap_code);
- sqlEditor.query_tool_obj.setOption('autoCloseBrackets', preferences.insert_pair_brackets);
- sqlEditor.query_tool_obj.setOption('matchBrackets', preferences.brace_matching);
- sqlEditor.query_tool_obj.refresh();
-
- /* Render history to reflect Font size change */
- sqlEditor.historyComponent.setEditorPref({
- 'sql_font_size' : sql_font_size,
- });
-}
-
-export {updateUIPreferences};
diff --git a/web/pgadmin/static/js/sqleditor/query_txn_status_constants.js b/web/pgadmin/static/js/sqleditor/query_txn_status_constants.js
deleted file mode 100644
index 075264296..000000000
--- a/web/pgadmin/static/js/sqleditor/query_txn_status_constants.js
+++ /dev/null
@@ -1,11 +0,0 @@
-/* psycopg2 transaction status constants
- * http://initd.org/psycopg/docs/extensions.html#transaction-status-constants
- */
-
-module.exports = {
- TRANSACTION_STATUS_IDLE: 0,
- TRANSACTION_STATUS_ACTIVE: 1,
- TRANSACTION_STATUS_INTRANS: 2,
- TRANSACTION_STATUS_INERROR: 3,
- TRANSACTION_STATUS_UNKNOWN: 5,
-};
diff --git a/web/pgadmin/static/js/sqleditor_utils.js b/web/pgadmin/static/js/sqleditor_utils.js
index 663745c9f..fa63a9ab2 100644
--- a/web/pgadmin/static/js/sqleditor_utils.js
+++ b/web/pgadmin/static/js/sqleditor_utils.js
@@ -8,251 +8,15 @@
//////////////////////////////////////////////////////////////////////////
// This file contains common utilities functions used in sqleditor modules
-define(['jquery', 'underscore', 'sources/gettext', 'sources/url_for', 'pgadmin.alertifyjs'],
- function ($, _, gettext, url_for, alertify) {
- var sqlEditorUtils = {
- /* Reference link http://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript
- * Modified as per requirement.
- */
- epicRandomString: function(length) {
- var s = [];
- var hexDigits = '0123456789abcdef';
- for (var i = 0; i < 36; i++) {
- s[i] = hexDigits.substr(
- Math.floor(Math.random() * 0x10), 1
- );
- }
- // bits 12-15 of the time_hi_and_version field to 0010
- s[14] = '4';
- // bits 6-7 of the clock_seq_hi_and_reserved to 01
- s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1);
- s[8] = s[13] = s[18] = s[23] = '-';
-
- var uuid = s.join('');
- return uuid.replace(/-/g, '').substr(0, length);
- },
-
- // Returns a unique hash for input string
- getHash: function(input) {
- var hash = 0, len = input.length;
- for (var i = 0; i < len; i++) {
- hash = ((hash << 5) - hash) + input.charCodeAt(i);
- hash |= 0; // to 32bit integer
- }
- return hash;
- },
- calculateColumnWidth: function (text) {
- // Calculate column header width based on column name or type
- // Create a temporary element with given label, append to body
- // calculate its width and remove the element.
- $('body').append(
- ''+ text + ' '
- );
- var width = $('#pg_text').width() + 23;
- $('#pg_text').remove(); // remove element
-
- return width;
- },
- capitalizeFirstLetter: function (string) {
- return string.charAt(0).toUpperCase() + string.slice(1);
- },
-
- // Disables arrow to change connection
- disable_connection_dropdown: function (status) {
- if (status){
- $('.conn-info-dd').prop('disabled',true);
- $('.connection-data').css({pointerEvents: 'none', cursor: 'arrow'});
- }else{
- $('.conn-info-dd').prop('disabled',false);
- $('.connection-data').css({pointerEvents: 'auto', cursor: 'pointer'});
- }
- },
-
- // Status flag
- previousStatus: null,
-
- // This function will fetch the connection status via ajax
- fetchConnectionStatus: function(target, $el, $status_el) {
- // If user has switch the browser Tab or Minimized window or
- // if wcDocker panel is not in focus then don't fire AJAX
- var url = url_for('sqleditor.connection_status', {
- 'trans_id': target.transId,
- });
-
- if (document.visibilityState !== 'visible' ||
- $el.data('panel-visible') !== 'visible' ) {
- return;
- }
-
- if($status_el.hasClass('obtaining-conn')){
- return;
- }
- let sqleditor_obj = target;
-
- // Start polling..
- $.ajax({
- url: url,
- method: 'GET',
- })
- .done(function (res) {
- if(res && res.data) {
- var status = res.data.status,
- msg = res.data.message,
- is_status_changed = false;
-
- // Raise notify messages comes from database server.
- sqleditor_obj.update_notifications(res.data.notifies);
-
- // Inject CSS as required
- switch(status) {
- // Busy
- case 1:
- // if received busy status more than once then only
- if(status == sqlEditorUtils.previousStatus &&
- !$status_el.hasClass('fa-hourglass-half')) {
- $status_el.removeClass()
- .addClass('fa fa-hourglass-half');
- is_status_changed = true;
- }
- break;
- // Idle in transaction
- case 2:
- if(sqlEditorUtils.previousStatus != status &&
- !$status_el.hasClass('fa-clock')) {
- $status_el.removeClass()
- .addClass('fa fa-clock');
- is_status_changed = true;
- }
- break;
- // Failed in transaction
- case 3:
- if(sqlEditorUtils.previousStatus != status &&
- !$status_el.hasClass('fa-exclamation-circle')) {
- $status_el.removeClass()
- .addClass('fa fa-exclamation-circle');
- is_status_changed = true;
- }
- break;
- // Failed in transaction with unknown server side error
- case 4:
- if(sqlEditorUtils.previousStatus != status &&
- !$status_el.hasClass('fa-exclamation-triangle')) {
- $status_el.removeClass()
- .addClass('fa fa-exclamation-triangle');
- is_status_changed = true;
- }
- break;
- default:
- if(sqlEditorUtils.previousStatus != status &&
- !$status_el.hasClass('fa-query_tool_connected')) {
- $status_el.removeClass()
- .addClass('pg-font-icon icon-connected');
- is_status_changed = true;
- }
- }
-
- sqlEditorUtils.previousStatus = status;
- // Set bootstrap popover message
- if(is_status_changed) {
- $el.popover('hide');
- $el.attr('data-content', msg);
- }
- } else {
- // We come here means we did not receive expected response
- // from server, we need to error out
- sqlEditorUtils.previousStatus = -99;
- msg = gettext('An unexpected error occurred - ' +
- 'ensure you are logged into the application.');
- $el.attr('data-content', msg);
- if(!$status_el.hasClass('icon-disconnected')) {
- $el.popover('hide');
- $status_el.removeClass()
- .addClass('pg-icon-font icon-disconnected');
- }
- }
- })
- .fail(function (e) {
- sqlEditorUtils.previousStatus = -1;
- var msg = gettext('Transaction status check failed.');
- if (e.readyState == 0) {
- msg = gettext('Not connected to the server or the connection to ' +
- 'the server has been closed.');
- } else if (e.responseJSON && e.responseJSON.errormsg) {
- msg = e.responseJSON.errormsg;
- }
-
- // Set bootstrap popover
- $el.attr('data-content', msg);
- // Add error class
- if(!$status_el.hasClass('icon-disconnected')) {
- $el.popover('hide');
- $status_el.removeClass()
- .addClass('pg-font-icon icon-disconnected');
- }
- });
- },
-
- // Updates the flag for connection status poll
- updateConnectionStatusFlag: function(status) {
- var $el = $('.connection_status');
- if ($el.data('panel-visible') != status) {
- $el.data('panel-visible', status);
- }
- },
-
- calcFontSize: function(fontSize) {
- if(fontSize) {
- fontSize = parseFloat((Math.round(parseFloat(fontSize + 'e+2')) + 'e-2'));
- let rounded = Number(fontSize);
- if(rounded > 0) {
- return rounded + 'em';
- }
- }
- return '1em';
- },
-
- addEditableIcon: function(columnDefinition, is_editable) {
- /* This uses Slickgrid.HeaderButtons plugin to add an icon to the
- columns headers. Instead of a button, an icon is created */
- let content = null;
- if(is_editable) {
- content = ' ';
- }
- else {
- content = ' ';
- }
- let button = {
- cssClass: 'editable-column-header-icon',
- content: content,
- };
- // Check for existing buttons
- if(!_.isUndefined(columnDefinition.header) &&
- !_.isUndefined(columnDefinition.header.buttons)) {
- columnDefinition.header.buttons.push(button);
- }
- else {
- columnDefinition.header = {
- buttons: [button],
- };
- }
- },
-
- isModalOpen: function(dialog_list) {
- /* check the modals inside the sqleditor are open or not */
- if(Array.isArray(dialog_list)) {
- for(let d of dialog_list) {
- try {
- if(alertify.dialog(d) && alertify.dialog(d).isOpen())
- return true;
- }
- catch (err) {
- // Do nothing
- console.warn(err.stack || err);
- }
- }
- }
- return false;
- },
- };
- return sqlEditorUtils;
- });
+module.exports = {
+ calcFontSize: function(fontSize) {
+ if(fontSize) {
+ fontSize = parseFloat((Math.round(parseFloat(fontSize + 'e+2')) + 'e-2'));
+ let rounded = Number(fontSize);
+ if(rounded > 0) {
+ return rounded + 'em';
+ }
+ }
+ return '1em';
+ },
+};
diff --git a/web/pgadmin/static/js/utils.js b/web/pgadmin/static/js/utils.js
index 9d6716533..2221997a2 100644
--- a/web/pgadmin/static/js/utils.js
+++ b/web/pgadmin/static/js/utils.js
@@ -302,7 +302,7 @@ export function sprintf(i_str) {
// Modified ref: http://stackoverflow.com/a/1293163/2343 to suite pgAdmin.
// This will parse a delimited string into an array of arrays.
-export function CSVToArray( strData, strDelimiter, quoteChar){
+export function CSVToArray(strData, strDelimiter, quoteChar){
strDelimiter = strDelimiter || ',';
quoteChar = quoteChar || '"';
@@ -323,6 +323,12 @@ export function CSVToArray( strData, strDelimiter, quoteChar){
// a default empty first row.
var arrData = [[]];
+ // The regex doesn't handle and skips start value if
+ // string starts with delimiter
+ if(strData.startsWith(strDelimiter)) {
+ arrData[ arrData.length - 1 ].push(null);
+ }
+
// Create an array to hold our individual pattern
// matching groups.
var arrMatches = null;
diff --git a/web/pgadmin/static/scss/_codemirror.overrides.scss b/web/pgadmin/static/scss/_codemirror.overrides.scss
index fd449ccf4..14c08a5f9 100644
--- a/web/pgadmin/static/scss/_codemirror.overrides.scss
+++ b/web/pgadmin/static/scss/_codemirror.overrides.scss
@@ -167,6 +167,9 @@
background: $sql-hint-active-bg;
color: $sql-hint-active-fg;
}
+ & .sqleditor-hint {
+ padding-left: 20px;
+ }
}
}
@@ -208,3 +211,5 @@
background-color: $sql-editor-disable-bg !important;
}
+
+
diff --git a/web/pgadmin/static/scss/_pgadmin.style.scss b/web/pgadmin/static/scss/_pgadmin.style.scss
index e75fa7261..7a7e89e08 100644
--- a/web/pgadmin/static/scss/_pgadmin.style.scss
+++ b/web/pgadmin/static/scss/_pgadmin.style.scss
@@ -1160,3 +1160,7 @@ select:-webkit-autofill:focus {
.text-wrap {
word-break: break-word;
}
+
+.sql_textarea {
+ height: 100%;
+}
diff --git a/web/pgadmin/static/scss/resources/_default.variables.scss b/web/pgadmin/static/scss/resources/_default.variables.scss
index dbc7e12ab..9e1583ee9 100644
--- a/web/pgadmin/static/scss/resources/_default.variables.scss
+++ b/web/pgadmin/static/scss/resources/_default.variables.scss
@@ -197,7 +197,7 @@ $color-editor-comment: #a50 !default;
$color-editor-bracket: #737373 !default;
$color-editor-operator: $color-fg !default;
$color-editor-foldmarker: #0000FF !default;
-$color-editor-activeline: #50B0F0 !default;
+$color-editor-activeline: #EDF9FF !default;
$color-editor-activeline-light: #EDF9FF !default;
$color-editor-activeline-border-color: #BCDEF3 !default;
diff --git a/web/pgadmin/tools/datagrid/__init__.py b/web/pgadmin/tools/datagrid/__init__.py
deleted file mode 100644
index b3f1371b4..000000000
--- a/web/pgadmin/tools/datagrid/__init__.py
+++ /dev/null
@@ -1,617 +0,0 @@
-##########################################################################
-#
-# pgAdmin 4 - PostgreSQL Tools
-#
-# Copyright (C) 2013 - 2022, The pgAdmin Development Team
-# This software is released under the PostgreSQL Licence
-#
-##########################################################################
-
-"""A blueprint module implementing the datagrid frame."""
-
-import simplejson as json
-import pickle
-import random
-
-from threading import Lock
-from flask import Response, url_for, session, request, make_response
-from werkzeug.useragents import UserAgent
-from flask import current_app as app, render_template
-from flask_babel import gettext
-from flask_security import login_required, current_user
-from pgadmin.tools.sqleditor.command import ObjectRegistry, SQLFilter
-from pgadmin.tools.sqleditor import check_transaction_status
-from pgadmin.utils import PgAdminModule
-from pgadmin.utils.ajax import make_json_response, bad_request, \
- internal_server_error, unauthorized
-
-from config import PG_DEFAULT_DRIVER, ALLOW_SAVE_PASSWORD
-from pgadmin.model import Server, User
-from pgadmin.utils.driver import get_driver
-from pgadmin.utils.exception import ConnectionLost, SSHTunnelConnectionLost
-from pgadmin.utils.preferences import Preferences
-from pgadmin.settings import get_setting
-from pgadmin.browser.utils import underscore_unescape
-from pgadmin.utils.exception import ObjectGone
-from pgadmin.tools.sqleditor.utils.macros import get_user_macros
-from pgadmin.utils.constants import MIMETYPE_APP_JS, UNAUTH_REQ
-
-MODULE_NAME = 'datagrid'
-
-query_tool_close_session_lock = Lock()
-
-
-class DataGridModule(PgAdminModule):
- """
- class DataGridModule(PgAdminModule)
-
- A module class for Edit Grid derived from PgAdminModule.
- """
-
- LABEL = "Data Grid"
-
- def get_own_menuitems(self):
- return {}
-
- def get_own_javascripts(self):
- return [{
- 'name': 'pgadmin.datagrid',
- 'path': url_for('datagrid.index') + "datagrid",
- 'when': None
- }]
-
- def get_panels(self):
- return []
-
- def get_exposed_url_endpoints(self):
- """
- Returns:
- list: URL endpoints for backup module
- """
- return [
- 'datagrid.initialize_datagrid',
- 'datagrid.initialize_query_tool',
- 'datagrid.initialize_query_tool_with_did',
- 'datagrid.filter_validate',
- 'datagrid.filter',
- 'datagrid.panel',
- 'datagrid.close',
- 'datagrid.update_query_tool_connection'
- ]
-
- def on_logout(self, user):
- """
- This is a callback function when user logout from pgAdmin
- :param user:
- :return:
- """
- with query_tool_close_session_lock:
- if 'gridData' in session:
- for trans_id in session['gridData']:
- close_query_tool_session(trans_id)
-
- # Delete all grid data from session variable
- del session['gridData']
-
-
-blueprint = DataGridModule(MODULE_NAME, __name__, static_url_path='/static')
-
-
-@blueprint.route("/")
-@login_required
-def index():
- return bad_request(
- errormsg=gettext('This URL cannot be requested directly.')
- )
-
-
-@blueprint.route("/css/datagrid.css")
-def datagrid_css():
- return make_response(
- render_template('datagrid/css/datagrid.css'),
- 200, {'Content-Type': 'text/css'}
- )
-
-
-@blueprint.route("/filter", endpoint='filter')
-@login_required
-def show_filter():
- return render_template(MODULE_NAME + '/filter.html')
-
-
-@blueprint.route(
- '/initialize/datagrid////'
- '///',
- methods=["PUT", "POST"],
- endpoint="initialize_datagrid"
-)
-@login_required
-def initialize_datagrid(trans_id, cmd_type, obj_type, sgid, sid, did, obj_id):
- """
- This method is responsible for creating an asynchronous connection.
- After creating the connection it will instantiate and initialize
- the object as per the object type. It will also create a unique
- transaction id and store the information into session variable.
-
- Args:
- cmd_type: Contains value for which menu item is clicked.
- obj_type: Contains type of selected object for which data grid to
- be render
- sgid: Server group Id
- sid: Server Id
- did: Database Id
- obj_id: Id of currently selected object
- """
-
- if request.data:
- filter_sql = json.loads(request.data, encoding='utf-8')
- else:
- filter_sql = request.args or request.form
-
- # Create asynchronous connection using random connection id.
- conn_id = str(random.randint(1, 9999999))
- try:
- manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
- # default_conn is same connection which is created when user connect to
- # database from tree
- default_conn = manager.connection(did=did)
- conn = manager.connection(did=did, conn_id=conn_id,
- auto_reconnect=False,
- use_binary_placeholder=True,
- array_to_string=True)
- except (ConnectionLost, SSHTunnelConnectionLost):
- raise
- except Exception as e:
- app.logger.error(e)
- return internal_server_error(errormsg=str(e))
-
- status, msg = default_conn.connect()
- if not status:
- app.logger.error(msg)
- return internal_server_error(errormsg=str(msg))
-
- status, msg = conn.connect()
- if not status:
- app.logger.error(msg)
- return internal_server_error(errormsg=str(msg))
- try:
- # if object type is partition then it is nothing but a table.
- if obj_type == 'partition':
- obj_type = 'table'
-
- # Get the object as per the object type
- command_obj = ObjectRegistry.get_object(
- obj_type, conn_id=conn_id, sgid=sgid, sid=sid,
- did=did, obj_id=obj_id, cmd_type=cmd_type,
- sql_filter=filter_sql
- )
- except ObjectGone:
- raise
- except Exception as e:
- app.logger.error(e)
- return internal_server_error(errormsg=str(e))
-
- if 'gridData' not in session:
- sql_grid_data = dict()
- else:
- sql_grid_data = session['gridData']
-
- # Use pickle to store the command object which will be used later by the
- # sql grid module.
- sql_grid_data[str(trans_id)] = {
- # -1 specify the highest protocol version available
- 'command_obj': pickle.dumps(command_obj, -1)
- }
-
- # Store the grid dictionary into the session variable
- session['gridData'] = sql_grid_data
-
- return make_json_response(
- data={
- 'conn_id': conn_id
- }
- )
-
-
-@blueprint.route(
- '/panel/',
- methods=["POST"],
- endpoint='panel'
-)
-def panel(trans_id):
- """
- This method calls index.html to render the data grid.
-
- Args:
- trans_id: unique transaction id
- """
-
- url_params = None
- if request.args:
- url_params = {k: v for k, v in request.args.items()}
-
- if request.form:
- url_params['title'] = request.form['title']
- if 'sql_filter' in request.form:
- url_params['sql_filter'] = request.form['sql_filter']
- if 'query_url' in request.form:
- url_params['query_url'] = request.form['query_url']
-
- # We need client OS information to render correct Keyboard shortcuts
- user_agent = UserAgent(request.headers.get('User-Agent'))
-
- """
- Animations and transitions are not automatically GPU accelerated and by
- default use browser's slow rendering engine. We need to set 'translate3d'
- value of '-webkit-transform' property in order to use GPU. After applying
- this property under linux, Webkit calculates wrong position of the
- elements so panel contents are not visible. To make it work, we need to
- explicitly set '-webkit-transform' property to 'none' for .ajs-notifier,
- .ajs-message, .ajs-modal classes.
-
- This issue is only with linux runtime application and observed in Query
- tool and debugger. When we open 'Open File' dialog then whole Query tool
- panel content is not visible though it contains HTML element in back end.
-
- The port number should have already been set by the runtime if we're
- running in desktop mode.
- """
- is_linux_platform = False
-
- from sys import platform as _platform
- if "linux" in _platform:
- is_linux_platform = True
-
- # Fetch the server details
- bgcolor = None
- fgcolor = None
-
- s = Server.query.filter_by(id=url_params['sid']).first()
- if s and s.bgcolor:
- # If background is set to white means we do not have to change
- # the title background else change it as per user specified
- # background
- if s.bgcolor != '#ffffff':
- bgcolor = s.bgcolor
- fgcolor = s.fgcolor or 'black'
-
- layout = get_setting('SQLEditor/Layout')
-
- macros = get_user_macros()
-
- return render_template(
- "datagrid/index.html",
- _=gettext,
- uniqueId=trans_id,
- is_desktop_mode=app.PGADMIN_RUNTIME,
- is_linux=is_linux_platform,
- title=underscore_unescape(url_params['title']),
- url_params=json.dumps(url_params),
- client_platform=user_agent.platform,
- bgcolor=bgcolor,
- fgcolor=fgcolor,
- layout=layout,
- requirejs=True,
- basejs=True,
- macros=macros
- )
-
-
-@blueprint.route(
- '/initialize/query_tool////',
- methods=["POST"], endpoint='initialize_query_tool_with_did'
-)
-@blueprint.route(
- '/initialize/query_tool///',
- methods=["POST"], endpoint='initialize_query_tool'
-)
-@login_required
-def initialize_query_tool(trans_id, sgid, sid, did=None):
- """
- This method is responsible for instantiating and initializing
- the query tool object. It will also create a unique
- transaction id and store the information into session variable.
-
- Args:
- sgid: Server group Id
- sid: Server Id
- did: Database Id
- """
- connect = True
- # Read the data if present. Skipping read may cause connection
- # reset error if data is sent from the client
- if request.data:
- _ = request.data
-
- req_args = request.args
- if ('recreate' in req_args and
- req_args['recreate'] == '1'):
- connect = False
-
- is_error, errmsg, conn_id, version = _init_query_tool(trans_id, connect,
- sgid, sid, did)
- if is_error:
- return errmsg
-
- return make_json_response(
- data={
- 'connId': str(conn_id),
- 'serverVersion': version,
- }
- )
-
-
-def _connect(conn, **kwargs):
- """
- Connect the database.
- :param conn: Connection instance.
- :param kwargs: user, role and password data from user.
- :return:
- """
- user = None
- role = None
- password = None
- is_ask_password = False
- if 'user' in kwargs and 'role' in kwargs:
- user = kwargs['user']
- role = kwargs['role'] if kwargs['role'] else None
- password = kwargs['password'] if kwargs['password'] else None
- is_ask_password = True
- if user:
- status, msg = conn.connect(user=user, role=role,
- password=password)
- else:
- status, msg = conn.connect()
-
- return status, msg, is_ask_password, user, role, password
-
-
-def _init_query_tool(trans_id, connect, sgid, sid, did, **kwargs):
- # Create asynchronous connection using random connection id.
- conn_id = str(random.randint(1, 9999999))
-
- manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
-
- if did is None:
- did = manager.did
- try:
- command_obj = ObjectRegistry.get_object(
- 'query_tool', conn_id=conn_id, sgid=sgid, sid=sid, did=did
- )
- except Exception as e:
- app.logger.error(e)
- return True, internal_server_error(errormsg=str(e)), '', ''
-
- try:
- conn = manager.connection(did=did, conn_id=conn_id,
- auto_reconnect=False,
- use_binary_placeholder=True,
- array_to_string=True)
-
- if connect:
- status, msg, is_ask_password, user, role, password = _connect(
- conn, **kwargs)
- if not status:
- app.logger.error(msg)
- if is_ask_password:
- server = Server.query.filter_by(id=sid).first()
- return True, make_json_response(
- success=0,
- status=428,
- result=render_template(
- 'servers/password.html',
- server_label=server.name,
- username=user,
- errmsg=msg,
- _=gettext,
- allow_save_password=True if
- ALLOW_SAVE_PASSWORD and
- session['allow_save_password'] else False,
- )
- ), '', ''
- else:
- return True, internal_server_error(
- errormsg=str(msg)), '', ''
- except (ConnectionLost, SSHTunnelConnectionLost) as e:
- app.logger.error(e)
- raise
- except Exception as e:
- app.logger.error(e)
- return True, internal_server_error(errormsg=str(e)), '', ''
-
- if 'gridData' not in session:
- sql_grid_data = dict()
- else:
- sql_grid_data = session['gridData']
-
- # Set the value of auto commit and auto rollback specified in Preferences
- pref = Preferences.module('sqleditor')
- command_obj.set_auto_commit(pref.preference('auto_commit').get())
- command_obj.set_auto_rollback(pref.preference('auto_rollback').get())
-
- # Use pickle to store the command object which will be used
- # later by the sql grid module.
- sql_grid_data[str(trans_id)] = {
- # -1 specify the highest protocol version available
- 'command_obj': pickle.dumps(command_obj, -1)
- }
-
- # Store the grid dictionary into the session variable
- session['gridData'] = sql_grid_data
-
- return False, '', conn_id, manager.version
-
-
-@blueprint.route(
- '/initialize/query_tool/update_connection//'
- '//',
- methods=["POST"], endpoint='update_query_tool_connection'
-)
-def update_query_tool_connection(trans_id, sgid, sid, did):
- # Remove transaction Id.
- with query_tool_close_session_lock:
- data = json.loads(request.data, encoding='utf-8')
-
- if 'gridData' not in session:
- return make_json_response(data={'status': True})
-
- grid_data = session['gridData']
-
- # Return from the function if transaction id not found
- if str(trans_id) not in grid_data:
- return make_json_response(data={'status': True})
-
- connect = True
-
- req_args = request.args
- if ('recreate' in req_args and
- req_args['recreate'] == '1'):
- connect = False
-
- new_trans_id = str(random.randint(1, 9999999))
- kwargs = {
- 'user': data['user'],
- 'role': data['role'] if 'role' in data else None,
- 'password': data['password'] if 'password' in data else None
- }
-
- is_error, errmsg, conn_id, version = _init_query_tool(
- new_trans_id, connect, sgid, sid, did, **kwargs)
-
- if is_error:
- return errmsg
- else:
- try:
- # Check the transaction and connection status
- status, error_msg, conn, trans_obj, session_obj = \
- check_transaction_status(trans_id)
-
- status, error_msg, new_conn, new_trans_obj, new_session_obj = \
- check_transaction_status(new_trans_id)
-
- new_session_obj['primary_keys'] = session_obj[
- 'primary_keys'] if 'primary_keys' in session_obj else None
- new_session_obj['columns_info'] = session_obj[
- 'columns_info'] if 'columns_info' in session_obj else None
- new_session_obj['client_primary_key'] = session_obj[
- 'client_primary_key'] if 'client_primary_key'\
- in session_obj else None
-
- close_query_tool_session(trans_id)
- # Remove the information of unique transaction id from the
- # session variable.
- grid_data.pop(str(trans_id), None)
- session['gridData'] = grid_data
- except Exception as e:
- app.logger.error(e)
-
- return make_json_response(
- data={
- 'connId': str(conn_id),
- 'serverVersion': version,
- 'tran_id': new_trans_id
- }
- )
-
-
-@blueprint.route('/close/', methods=["DELETE"], endpoint='close')
-def close(trans_id):
- """
- This method is used to close the asynchronous connection
- and remove the information of unique transaction id from
- the session variable.
-
- Args:
- trans_id: unique transaction id
- """
- with query_tool_close_session_lock:
- if 'gridData' not in session:
- return make_json_response(data={'status': True})
-
- grid_data = session['gridData']
- # Return from the function if transaction id not found
- if str(trans_id) not in grid_data:
- return make_json_response(data={'status': True})
-
- try:
- close_query_tool_session(trans_id)
- # Remove the information of unique transaction id from the
- # session variable.
- grid_data.pop(str(trans_id), None)
- session['gridData'] = grid_data
- except Exception as e:
- app.logger.error(e)
- return internal_server_error(errormsg=str(e))
-
- return make_json_response(data={'status': True})
-
-
-@blueprint.route(
- '/filter/validate///',
- methods=["PUT", "POST"], endpoint='filter_validate'
-)
-@login_required
-def validate_filter(sid, did, obj_id):
- """
- This method is used to validate the sql filter.
-
- Args:
- sid: Server Id
- did: Database Id
- obj_id: Id of currently selected object
- """
- if request.data:
- filter_sql = json.loads(request.data, encoding='utf-8')
- else:
- filter_sql = request.args or request.form
-
- try:
- # Create object of SQLFilter class
- sql_filter_obj = SQLFilter(sid=sid, did=did, obj_id=obj_id)
-
- # Call validate_filter method to validate the SQL.
- status, res = sql_filter_obj.validate_filter(filter_sql)
- except ObjectGone:
- raise
- except Exception as e:
- app.logger.error(e)
- return internal_server_error(errormsg=str(e))
-
- return make_json_response(data={'status': status, 'result': res})
-
-
-@blueprint.route("/datagrid.js")
-@login_required
-def script():
- """render the required javascript"""
- return Response(
- response=render_template("datagrid/js/datagrid.js", _=gettext),
- status=200,
- mimetype=MIMETYPE_APP_JS
- )
-
-
-def close_query_tool_session(trans_id):
- """
- This function is used to cancel the transaction and release the connection.
-
- :param trans_id: Transaction id
- :return:
- """
- if 'gridData' in session and str(trans_id) in session['gridData']:
- cmd_obj_str = session['gridData'][str(trans_id)]['command_obj']
- # Use pickle.loads function to get the command object
- cmd_obj = pickle.loads(cmd_obj_str)
-
- # if connection id is None then no need to release the connection
- if cmd_obj.conn_id is not None:
- manager = get_driver(
- PG_DEFAULT_DRIVER).connection_manager(cmd_obj.sid)
- if manager is not None:
- conn = manager.connection(
- did=cmd_obj.did, conn_id=cmd_obj.conn_id)
-
- # Release the connection
- if conn.connected():
- conn.cancel_transaction(cmd_obj.conn_id, cmd_obj.did)
- manager.release(did=cmd_obj.did, conn_id=cmd_obj.conn_id)
diff --git a/web/pgadmin/tools/datagrid/static/js/datagrid.js b/web/pgadmin/tools/datagrid/static/js/datagrid.js
deleted file mode 100644
index 4438f8a5f..000000000
--- a/web/pgadmin/tools/datagrid/static/js/datagrid.js
+++ /dev/null
@@ -1,370 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-define('pgadmin.datagrid', [
- 'sources/gettext', 'sources/url_for', 'jquery', 'underscore',
- 'pgadmin.alertifyjs', 'sources/pgadmin', 'bundled_codemirror',
- 'sources/sqleditor_utils', 'backbone',
- 'tools/datagrid/static/js/show_data',
- 'tools/datagrid/static/js/show_query_tool', 'pgadmin.browser.toolbar',
- 'tools/datagrid/static/js/datagrid_panel_title', 'sources/utils', 'wcdocker',
-], function(
- gettext, url_for, $, _, alertify, pgAdmin, codemirror, sqlEditorUtils,
- Backbone, showData, showQueryTool, toolBar, panelTitleFunc, commonUtils
-) {
- // Some scripts do export their object in the window only.
- // Generally the one, which do no have AMD support.
- var wcDocker = window.wcDocker,
- pgBrowser = pgAdmin.Browser;
-
- /* Return back, this has been called more than once */
- if (pgAdmin.DataGrid)
- return pgAdmin.DataGrid;
-
- pgAdmin.DataGrid =
- _.extend(
- {
- init: function() {
- if (this.initialized)
- return;
- this.initialized = true;
- this.title_index = 1;
-
-
- let self = this;
- /* Cache may take time to load for the first time
- * Keep trying till available
- */
- let cacheIntervalId = setInterval(function() {
- if(pgBrowser.preference_version() > 0) {
- self.preferences = pgBrowser.get_preferences_for_module('sqleditor');
- clearInterval(cacheIntervalId);
- }
- },0);
-
- pgBrowser.onPreferencesChange('sqleditor', function() {
- self.preferences = pgBrowser.get_preferences_for_module('sqleditor');
- });
-
- // Define list of nodes on which view data option appears
- var supported_nodes = [
- 'table', 'view', 'mview',
- 'foreign_table', 'catalog_object', 'partition',
- ],
-
- /* Enable/disable View data menu in tools based
- * on node selected. if selected node is present
- * in supported_nodes, menu will be enabled
- * otherwise disabled.
- */
- view_menu_enabled = function(obj) {
- var isEnabled = (() => {
- if (!_.isUndefined(obj) && !_.isNull(obj))
- return (_.indexOf(supported_nodes, obj._type) !== -1 ? true : false);
- else
- return false;
- })();
-
- toolBar.enable(gettext('View Data'), isEnabled);
- toolBar.enable(gettext('Filtered Rows'), isEnabled);
- return isEnabled;
- },
-
- /* Enable/disable Query tool menu in tools based
- * on node selected. if selected node is present
- * in unsupported_nodes, menu will be disabled
- * otherwise enabled.
- */
- query_tool_menu_enabled = function(obj) {
- var isEnabled = (() => {
- if (!_.isUndefined(obj) && !_.isNull(obj)) {
- if (_.indexOf(pgAdmin.unsupported_nodes, obj._type) == -1) {
- if (obj._type == 'database' && obj.allowConn) {
- return true;
- } else if (obj._type != 'database') {
- return true;
- } else {
- return false;
- }
- } else {
- return false;
- }
- } else {
- return false;
- }
- })();
-
- toolBar.enable(gettext('Query Tool'), isEnabled);
- return isEnabled;
- };
-
- // Define the nodes on which the menus to be appear
- var menus = [{
- name: 'query_tool',
- module: this,
- applies: ['tools'],
- callback: 'show_query_tool',
- enable: query_tool_menu_enabled,
- priority: 1,
- label: gettext('Query Tool'),
- icon: 'pg-font-icon icon-query_tool',
- data:{
- applies: 'tools',
- data_disabled: gettext('Please select a database from the browser tree to access Query Tool.'),
- },
- }];
-
- // Create context menu
- for (let node_val of supported_nodes) {
- menus.push({
- name: 'view_all_rows_context_' + node_val,
- node: node_val,
- module: this,
- data: {
- mnuid: 3,
- },
- applies: ['context', 'object'],
- callback: 'show_data_grid',
- enable: view_menu_enabled,
- category: 'view_data',
- priority: 101,
- label: gettext('All Rows'),
- }, {
- name: 'view_first_100_rows_context_' + node_val,
- node: node_val,
- module: this,
- data: {
- mnuid: 1,
- },
- applies: ['context', 'object'],
- callback: 'show_data_grid',
- enable: view_menu_enabled,
- category: 'view_data',
- priority: 102,
- label: gettext('First 100 Rows'),
- }, {
- name: 'view_last_100_rows_context_' + node_val,
- node: node_val,
- module: this,
- data: {
- mnuid: 2,
- },
- applies: ['context', 'object'],
- callback: 'show_data_grid',
- enable: view_menu_enabled,
- category: 'view_data',
- priority: 103,
- label: gettext('Last 100 Rows'),
- }, {
- name: 'view_filtered_rows_context_' + node_val,
- node: node_val,
- module: this,
- data: {
- mnuid: 4,
- },
- applies: ['context', 'object'],
- callback: 'show_filtered_row',
- enable: view_menu_enabled,
- category: 'view_data',
- priority: 104,
- label: gettext('Filtered Rows...'),
- });
- }
-
- pgAdmin.Browser.add_menu_category('view_data', gettext('View/Edit Data'), 100, '');
- pgAdmin.Browser.add_menus(menus);
-
- // Creating a new pgAdmin.Browser frame to show the data.
- var dataGridFrameType = new pgAdmin.Browser.Frame({
- name: 'frm_datagrid',
- showTitle: true,
- isCloseable: true,
- isRenamable: true,
- isPrivate: true,
- url: 'about:blank',
- });
-
- // Load the newly created frame
- dataGridFrameType.load(pgBrowser.docker);
- this.on('pgadmin-datagrid:transaction:created', function(trans_obj) {
- this.launch_grid(trans_obj);
- });
- },
-
- // This is a callback function to show data when user click on menu item.
- show_data_grid: function(data, i) {
- const transId = commonUtils.getRandomInt(1, 9999999);
- showData.showDataGrid(this, pgBrowser, alertify, data, i, transId);
- },
-
- // This is a callback function to show filtered data when user click on menu item.
- show_filtered_row: function(data, i) {
- const transId = commonUtils.getRandomInt(1, 9999999);
- showData.showDataGrid(this, pgBrowser, alertify, data, i, transId, true, this.preferences);
- },
-
- // This is a callback function to show query tool when user click on menu item.
- show_query_tool: function(url, aciTreeIdentifier) {
- const transId = commonUtils.getRandomInt(1, 9999999);
- var t = pgBrowser.tree,
- i = aciTreeIdentifier || t.selected(),
- d = i ? t.itemData(i) : undefined;
-
- //Open query tool with create script if copy_sql_to_query_tool is true else open blank query tool
- var preference = pgBrowser.get_preference('sqleditor', 'copy_sql_to_query_tool');
- if(preference.value && !d._type.includes('coll-') && (url === '' || url['applies'] === 'tools')){
- var stype = d._type.toLowerCase();
- var data = {
- 'script': stype,
- data_disabled: gettext('The selected tree node does not support this option.'),
- };
- pgBrowser.Node.callbacks.show_script(data);
- }else{
- if(d._type.includes('coll-')){
- url = '';
- }
- showQueryTool.showQueryTool(this, pgBrowser, url, aciTreeIdentifier, transId);
- }
- },
-
- launch_grid: function(trans_id, panel_url, is_query_tool, panel_title, sURL=null, sql_filter=null) {
-
- let queryToolForm = `
-
-
- `;
-
- var browser_preferences = pgBrowser.get_preferences_for_module('browser');
- var open_new_tab = browser_preferences.new_browser_tab_open;
- if (open_new_tab && open_new_tab.includes('qt')) {
- var newWin = window.open('', '_blank');
- if(newWin) {
- newWin.document.write(queryToolForm);
- newWin.document.title = panel_title;
- // Send the signal to runtime, so that proper zoom level will be set.
- setTimeout(function() {
- pgBrowser.send_signal_to_runtime('Runtime new window opened');
- }, 500);
- } else {
- return false;
- }
- } else {
- /* On successfully initialization find the dashboard panel,
- * create new panel and add it to the dashboard panel.
- */
- var propertiesPanel = pgBrowser.docker.findPanels('properties');
- var queryToolPanel = pgBrowser.docker.addPanel('frm_datagrid', wcDocker.DOCK.STACKED, propertiesPanel[0]);
- queryToolPanel.trans_id = trans_id;
- showQueryTool._set_dynamic_tab(pgBrowser, browser_preferences['dynamic_tabs']);
-
- // Set panel title and icon
- panelTitleFunc.setQueryToolDockerTitle(queryToolPanel, is_query_tool, _.unescape(panel_title));
- queryToolPanel.focus();
-
- // Listen on the panel closed event.
- if (queryToolPanel.isVisible()) {
- queryToolPanel.on(wcDocker.EVENT.CLOSED, function() {
- $.ajax({
- url: url_for('datagrid.close', {'trans_id': trans_id}),
- method: 'DELETE',
- });
- });
- }
-
- queryToolPanel.on(wcDocker.EVENT.VISIBILITY_CHANGED, function() {
- queryToolPanel.trigger(wcDocker.EVENT.RESIZED);
- });
-
- commonUtils.registerDetachEvent(queryToolPanel);
-
- // Listen on the panelRename event.
- queryToolPanel.on(wcDocker.EVENT.RENAME, function(panel_data) {
- var temp_title = panel_data.$titleText[0].textContent;
- var is_dirty_editor = queryToolPanel.is_dirty_editor ? queryToolPanel.is_dirty_editor : false;
- var title = queryToolPanel.is_dirty_editor ? panel_data.$titleText[0].textContent.replace(/.$/, '') : temp_title;
- alertify.prompt('', title,
- // We will execute this function when user clicks on the OK button
- function(evt, value) {
- // Remove the leading and trailing white spaces.
- value = value.trim();
- if(value) {
- var is_file = false;
- if(panel_data.$titleText[0].innerHTML.includes('File - ')) {
- is_file = true;
- }
- var selected_item = pgBrowser.tree.selected();
- var panel_titles = '';
-
- if(is_query_tool) {
- panel_titles = panelTitleFunc.getPanelTitle(pgBrowser, selected_item, value);
- } else {
- panel_titles = showData.generateDatagridTitle(pgBrowser, selected_item, value);
- }
- // Set title to the selected tab.
- if (is_dirty_editor) {
- panel_titles = panel_titles + ' *';
- }
- panelTitleFunc.setQueryToolDockerTitle(queryToolPanel, is_query_tool, _.unescape(panel_titles), is_file);
- }
- },
- // We will execute this function when user clicks on the Cancel
- // button. Do nothing just close it.
- function(evt) { evt.cancel = false; }
- ).set({'title': gettext('Rename Panel')});
- });
-
- var openQueryToolURL = function(j) {
- // add spinner element
- let $spinner_el =
- $(``).appendTo($(j).data('embeddedFrame').$container);
-
- let init_poller_id = setInterval(function() {
- var frameInitialized = $(j).data('frameInitialized');
- if (frameInitialized) {
- clearInterval(init_poller_id);
- var frame = $(j).data('embeddedFrame');
- if (frame) {
- frame.onLoaded(()=>{
- $spinner_el.remove();
- });
- frame.openHTML(queryToolForm);
- }
- }
- }, 100);
- };
-
- openQueryToolURL(queryToolPanel);
- }
- return true;
- },
- },
- Backbone.Events);
-
- return pgAdmin.DataGrid;
-});
diff --git a/web/pgadmin/tools/datagrid/templates/datagrid/index.html b/web/pgadmin/tools/datagrid/templates/datagrid/index.html
deleted file mode 100644
index 1cb3b3cd2..000000000
--- a/web/pgadmin/tools/datagrid/templates/datagrid/index.html
+++ /dev/null
@@ -1,507 +0,0 @@
-{% extends "base.html" %}
-{% block title %}{{title}}{% endblock %}
-{% block body %}
-
-{% block css_link %}
-
-{% endblock %}
-
-{% endblock %}
-
-{% block init_script %}
-require(['sources/generated/browser_nodes', 'sources/generated/codemirror', 'sources/generated/slickgrid'], function() {
- require(['sources/generated/sqleditor'], function(ctx) {
- var $ = pgAdmin.SqlEditor.jquery,
- S = pgAdmin.SqlEditor.S,
- editorPanel = $('.sql-editor');
-
- // Register unload event on window close.
- /* If opened in new tab, close the connection only on tab/window close and
- * not on refresh attempt because the user may cancel the reload
- */
- if(window.opener) {
- $(window).on('unload', function(ev) {
- $.ajax({
- method: 'DELETE',
- url: "{{ url_for('datagrid.index') }}" + "close/" + {{ uniqueId }}
- });
- });
- } else {
- $(window).on('beforeunload', function(ev) {
- $.ajax({
- method: 'DELETE',
- url: "{{ url_for('datagrid.index') }}" + "close/" + {{ uniqueId }}
- });
- });
- }
-
- // Get the controller object from pgAdmin.SqlEditor
- var sqlEditorController = pgAdmin.SqlEditor.create(editorPanel);
-
- // Listen on events to show/hide loading-icon and change messages.
- {% if script_type_url %}
- var script_type_url = '{{ script_type_url }}';
- {% else %}
- var script_type_url = '';
- {% endif %}
- // Start the query tool.
-
- sqlEditorController.start(
- {{ uniqueId }},
- {{ url_params|safe}},
- '{{ layout|safe }}',
- {{ macros|safe }}
- );
-
- // If opening from schema diff, set the generated script to the SQL Editor
-
- var schema_ddl_diff = (window.opener !== null) ? window.opener.pgAdmin.ddl_diff : (window.parent !== null) ? window.parent.pgAdmin.ddl_diff : window.top.pgAdmin.ddl_diff;
- sqlEditorController.set_value_to_editor(schema_ddl_diff);
- if (window.opener !== null) window.opener.pgAdmin.ddl_diff = '';
- else if (window.parent !== null) window.parent.pgAdmin.ddl_diff = '';
- else if (window.top !== null) window.top.pgAdmin.ddl_diff = '';
-
- });
-});
-{% endblock %}
diff --git a/web/pgadmin/tools/datagrid/tests/__init__.py b/web/pgadmin/tools/datagrid/tests/__init__.py
deleted file mode 100644
index e69de29bb..000000000
diff --git a/web/pgadmin/tools/datagrid/tests/datagrid_test_data.json b/web/pgadmin/tools/datagrid/tests/datagrid_test_data.json
deleted file mode 100644
index 0075f35e3..000000000
--- a/web/pgadmin/tools/datagrid/tests/datagrid_test_data.json
+++ /dev/null
@@ -1,134 +0,0 @@
-{
- "data_grid_init_query_tool": [
- {
- "name": "Datagrid init query tool",
- "url": "/datagrid/initialize/query_tool/",
- "is_positive_test": true,
- "mocking_required": false,
- "test_data": {},
- "mock_data": {},
- "expected_data": {
- "status_code": 200
- }
- }
- ],
- "data_grid_query_tool_close": [
- {
- "name": "Datagrid query tool close",
- "url": "/datagrid/close/",
- "is_positive_test": true,
- "mocking_required": false,
- "test_data": {},
- "mock_data": {},
- "expected_data": {
- "status_code": 200
- }
- }
- ],
- "data_grid_validate_filter": [
- {
- "name": "Datagrid validate filter",
- "url": "/datagrid/filter/validate/",
- "is_positive_test": true,
- "mocking_required": false,
- "test_data": "id = 1",
- "mock_data": {},
- "expected_data": {
- "status_code": 200
- }
- },
- {
- "name": "Datagrid validate filter",
- "url": "/datagrid/filter/validate/",
- "is_positive_test": false,
- "mocking_required": true,
- "test_data": "id = 1",
- "mock_data": {
- "function_name": "pgadmin.utils.driver.psycopg2.connection.Connection.execute_scalar",
- "return_value": "(False, 'Mocked Internal Server Error while validate filter')"
- },
- "expected_data": {
- "status_code": 200
- }
- }
- ],
- "data_grid_update_connection": [
- {
- "name": "Datagrid update connection positive",
- "url": "/datagrid/initialize/query_tool/update_connection/",
- "is_positive_test": true,
- "mocking_required": false,
- "is_create_role": false,
- "test_data": {},
- "mock_data": {},
- "expected_data": {
- "status_code": 200
- }
- },
- {
- "name": "Datagrid update connection with new user",
- "url": "/datagrid/initialize/query_tool/update_connection/",
- "is_positive_test": true,
- "mocking_required": false,
- "is_create_role": true,
- "test_data": {},
- "mock_data": {},
- "expected_data": {
- "status_code": 200
- }
- }
- ],
- "data_grid_panel": [
- {
- "name": "Datagrid Panel",
- "url": "/datagrid/panel/",
- "is_positive_test": true,
- "mocking_required": false,
- "test_data": {},
- "mock_data": {
- },
- "expected_data": {
- "status_code": 200
- }
- }
- ],
- "data_grid_initialize": [
- {
- "name": "Datagrid Initialize",
- "url": "/datagrid/initialize/datagrid/",
- "is_positive_test": true,
- "mocking_required": false,
- "test_data": "id=1",
- "mock_data": {
-
- },
- "expected_data": {
- "status_code": 200
- }
- },{
- "name": "Datagrid Initialize",
- "url": "/datagrid/initialize/datagrid/",
- "is_positive_test": true,
- "mocking_required": false,
- "test_data": null,
- "mock_data": {},
- "expected_data": {
- "status_code": 200
- }
- },
- {
- "name": "Datagrid Initialize",
- "url": "/datagrid/initialize/datagrid/",
- "is_positive_test": false,
- "mocking_required": true,
- "test_data": "id=1",
- "mock_data": {
- "function_name": "pgadmin.utils.driver.psycopg2.connection.Connection.execute_dict",
- "return_value": "(False, 'Mocked Internal Server Error while initialize datagrid.')"
- },
- "expected_data": {
- "status_code": 500
- }
- }
- ]
-}
diff --git a/web/pgadmin/tools/datagrid/tests/test_data_grid_init_query_tool.py b/web/pgadmin/tools/datagrid/tests/test_data_grid_init_query_tool.py
deleted file mode 100644
index bc7946be5..000000000
--- a/web/pgadmin/tools/datagrid/tests/test_data_grid_init_query_tool.py
+++ /dev/null
@@ -1,73 +0,0 @@
-##########################################################################
-#
-# pgAdmin 4 - PostgreSQL Tools
-#
-# Copyright (C) 2013 - 2022, The pgAdmin Development Team
-# This software is released under the PostgreSQL Licence
-#
-##########################################################################
-
-
-import json
-import uuid
-import random
-
-from unittest.mock import patch
-from pgadmin.browser.server_groups.servers.databases.tests import utils as \
- database_utils
-
-from pgadmin.utils.route import BaseTestGenerator
-from pgadmin.utils.exception import ExecuteError
-from regression import parent_node_dict
-from regression.python_test_utils import test_utils as utils
-from regression.test_setup import config_data
-from . import utils as data_grid_utils
-
-
-class DatagridInitQueryToolTestCase(BaseTestGenerator):
- """
- This will init query-tool connection.
- """
-
- scenarios = utils.generate_scenarios(
- 'data_grid_init_query_tool',
- data_grid_utils.test_cases
- )
-
- def setUp(self):
- self.database_info = parent_node_dict["database"][-1]
- self.db_name = self.database_info["db_name"]
- self.did = self.database_info["db_id"]
- self.sid = parent_node_dict["server"][-1]["server_id"]
- self.sgid = config_data['server_group']
-
- db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
- self.sid, self.did)
-
- self.trans_id = str(random.randint(1, 9999999))
-
- if not db_con['data']["connected"]:
- raise ExecuteError("Could not connect to database to add a table.")
-
- def init_query_tool(self):
- response = self.tester.post(
- self.url + str(self.trans_id) + '/' + str(self.sgid) + '/' + str(
- self.sid) + '/' + str(self.did),
- content_type='html/json'
- )
- return response
-
- def runTest(self):
- """ This function will init query tool connection."""
-
- if self.is_positive_test:
- response = self.init_query_tool()
- actual_response_code = response.status_code
- expected_response_code = self.expected_data['status_code']
-
- self.assertEqual(actual_response_code, expected_response_code)
-
- def tearDown(self):
- """This function disconnect database."""
- database_utils.disconnect_database(self, self.sid,
- self.did)
diff --git a/web/pgadmin/tools/datagrid/tests/test_data_grid_panel.py b/web/pgadmin/tools/datagrid/tests/test_data_grid_panel.py
deleted file mode 100644
index 5511a021c..000000000
--- a/web/pgadmin/tools/datagrid/tests/test_data_grid_panel.py
+++ /dev/null
@@ -1,90 +0,0 @@
-##########################################################################
-#
-# pgAdmin 4 - PostgreSQL Tools
-#
-# Copyright (C) 2013 - 2022, The pgAdmin Development Team
-# This software is released under the PostgreSQL Licence
-#
-##########################################################################
-
-
-import json
-import uuid
-import random
-
-from unittest.mock import patch
-from pgadmin.browser.server_groups.servers.databases.tests import utils as \
- database_utils
-
-from pgadmin.utils.route import BaseTestGenerator
-from pgadmin.utils.exception import ExecuteError
-from regression import parent_node_dict
-from regression.python_test_utils import test_utils as utils
-from regression.test_setup import config_data
-from . import utils as data_grid_utils
-
-
-class DatagridPanelTestCase(BaseTestGenerator):
- """
- This will data grid panel.
- """
-
- scenarios = utils.generate_scenarios(
- 'data_grid_panel',
- data_grid_utils.test_cases
- )
-
- def setUp(self):
- self.database_info = parent_node_dict["database"][-1]
- self.db_name = self.database_info["db_name"]
- self.did = self.database_info["db_id"]
- self.sid = parent_node_dict["server"][-1]["server_id"]
- self.sgid = config_data['server_group']
-
- db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
- self.sid, self.did)
- if not db_con['data']["connected"]:
- raise ExecuteError("Could not connect to database to add a table.")
-
- self.trans_id = str(random.randint(1, 9999999))
- qt_init = data_grid_utils._init_query_tool(self, self.trans_id,
- self.sgid, self.sid,
- self.did)
-
- if not qt_init['success']:
- raise ExecuteError("Could not initialize querty tool.")
-
- def panel(self):
- query_param = \
- '?is_query_tool={0}&sgid={1}&sid={2}&server_type={3}' \
- '&did={4}&title={5}'.format(True, self.sgid, self.sid,
- self.server_information['type'],
- self.did, 'Query panel')
-
- response = self.tester.post(
- self.url + str(self.trans_id) + query_param,
- data=json.dumps(self.test_data),
- content_type='html/json'
- )
- return response
-
- def runTest(self):
- """ This function will update query tool connection."""
-
- if self.is_positive_test:
- response = self.panel()
- actual_response_code = response.status_code
- expected_response_code = self.expected_data['status_code']
- else:
- with patch(self.mock_data["function_name"],
- return_value=eval(self.mock_data["return_value"])):
- response = self.panel()
- actual_response_code = response.status_code
- expected_response_code = self.expected_data['status_code']
-
- self.assertEqual(actual_response_code, expected_response_code)
-
- def tearDown(self):
- """This function disconnect database."""
- database_utils.disconnect_database(self, self.sid,
- self.did)
diff --git a/web/pgadmin/tools/datagrid/tests/test_data_grid_query_tool_close.py b/web/pgadmin/tools/datagrid/tests/test_data_grid_query_tool_close.py
deleted file mode 100644
index 440ea7c51..000000000
--- a/web/pgadmin/tools/datagrid/tests/test_data_grid_query_tool_close.py
+++ /dev/null
@@ -1,78 +0,0 @@
-##########################################################################
-#
-# pgAdmin 4 - PostgreSQL Tools
-#
-# Copyright (C) 2013 - 2022, The pgAdmin Development Team
-# This software is released under the PostgreSQL Licence
-#
-##########################################################################
-
-
-import json
-import uuid
-import random
-
-from unittest.mock import patch
-from pgadmin.browser.server_groups.servers.databases.tests import utils as \
- database_utils
-
-from pgadmin.utils.route import BaseTestGenerator
-from regression import parent_node_dict
-from regression.python_test_utils import test_utils as utils
-from regression.test_setup import config_data
-from . import utils as data_grid_utils
-from pgadmin.utils.exception import ExecuteError
-
-
-class DatagridQueryToolCloseTestCase(BaseTestGenerator):
- """
- This will close query-tool connection.
- """
-
- scenarios = utils.generate_scenarios(
- 'data_grid_query_tool_close',
- data_grid_utils.test_cases
- )
-
- def setUp(self):
- self.database_info = parent_node_dict["database"][-1]
- self.db_name = self.database_info["db_name"]
- self.did = self.database_info["db_id"]
- self.sid = parent_node_dict["server"][-1]["server_id"]
- self.sgid = config_data['server_group']
-
- db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
- self.sid, self.did)
-
- if not db_con['data']["connected"]:
- raise ExecuteError("Could not connect to database to add a table.")
-
- self.trans_id = str(random.randint(1, 9999999))
- qt_init = data_grid_utils._init_query_tool(self, self.trans_id,
- self.sgid, self.sid,
- self.did)
-
- if not qt_init['success']:
- raise ExecuteError("Could not initialize querty tool.")
-
- def close_connection(self):
- response = self.tester.delete(
- self.url + str(self.trans_id),
- content_type='html/json'
- )
- return response
-
- def runTest(self):
- """ This function will update query tool connection."""
-
- if self.is_positive_test:
- response = self.close_connection()
- actual_response_code = response.status_code
- expected_response_code = self.expected_data['status_code']
-
- self.assertEqual(actual_response_code, expected_response_code)
-
- def tearDown(self):
- """This function disconnect database."""
- database_utils.disconnect_database(self, self.sid,
- self.did)
diff --git a/web/pgadmin/tools/datagrid/tests/test_data_grid_update_connection.py b/web/pgadmin/tools/datagrid/tests/test_data_grid_update_connection.py
deleted file mode 100644
index 5dd7fff38..000000000
--- a/web/pgadmin/tools/datagrid/tests/test_data_grid_update_connection.py
+++ /dev/null
@@ -1,121 +0,0 @@
-##########################################################################
-#
-# pgAdmin 4 - PostgreSQL Tools
-#
-# Copyright (C) 2013 - 2022, The pgAdmin Development Team
-# This software is released under the PostgreSQL Licence
-#
-##########################################################################
-
-
-import json
-import uuid
-import random
-
-from unittest.mock import patch
-from pgadmin.browser.server_groups.servers.databases.tests import utils as \
- database_utils
-
-from pgadmin.utils.route import BaseTestGenerator
-from regression import parent_node_dict
-from regression.python_test_utils import test_utils as utils
-from regression.test_setup import config_data
-from pgadmin.browser.server_groups.servers.roles.tests import \
- utils as roles_utils
-from . import utils as data_grid_utils
-from pgadmin.utils.exception import ExecuteError
-
-
-class DatagridUpdateConnectionTestCase(BaseTestGenerator):
- """
- This will update query-tool connection.
- """
-
- scenarios = utils.generate_scenarios(
- 'data_grid_update_connection',
- data_grid_utils.test_cases
- )
-
- def setUp(self):
- self.database_info = parent_node_dict["database"][-1]
- self.db_name = self.database_info["db_name"]
- self.did = self.database_info["db_id"]
- self.sid = parent_node_dict["server"][-1]["server_id"]
- self.sgid = config_data['server_group']
-
- db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
- self.sid, self.did)
-
- self.trans_id = str(random.randint(1, 9999999))
- self.roles = None
-
- if self.is_create_role:
- data = roles_utils.get_role_data(self.server['db_password'])
- self.role_name = data['rolname']
- self.role_password = data['rolpassword']
- roles_utils.create_role_with_password(
- self.server, self.role_name, self.role_password)
-
- if not self.is_positive_test or self.is_create_role:
- qt_init = data_grid_utils._init_query_tool(self, self.trans_id,
- self.sgid, self.sid,
- self.did)
-
- if not qt_init['success']:
- raise ExecuteError("Could not initialize querty tool.")
-
- self.test_data = {
- "database": self.did,
- "server": self.sid,
- }
-
- if self.server_information['type'] == 'ppas':
- self.test_data['password'] = 'enterprisedb'
- self.test_data['user'] = 'enterprisedb'
- else:
- self.test_data['password'] = 'postgres'
- self.test_data['user'] = 'postgres'
-
- if not db_con['data']["connected"]:
- raise ExecuteError("Could not connect to database to add a table.")
-
- def update_connection(self, user_data=None):
- if user_data:
- response = self.tester.post(
- self.url + str(self.trans_id) + '/' + str(self.sgid) +
- '/' + str(self.sid) + '/' + str(self.did),
- data=json.dumps(user_data),
- content_type='html/json'
- )
- else:
- response = self.tester.post(
- self.url + str(self.trans_id) + '/' + str(self.sgid) + '/' +
- str(self.sid) + '/' + str(self.did),
- data=json.dumps(self.test_data),
- content_type='html/json'
- )
- return response
-
- def runTest(self):
- """ This function will update query tool connection."""
-
- if self.is_positive_test:
- user_data = dict()
- if self.is_create_role:
- user_data['user'] = self.role_name
- user_data['password'] = self.role_password
- user_data['role'] = None
- response = self.update_connection(user_data=user_data)
- actual_response_code = response.status_code
- expected_response_code = self.expected_data['status_code']
- else:
- response = self.update_connection()
- actual_response_code = response.status_code
- expected_response_code = self.expected_data['status_code']
-
- self.assertEqual(actual_response_code, expected_response_code)
-
- def tearDown(self):
- """This function disconnect database."""
- database_utils.disconnect_database(self, self.sid,
- self.did)
diff --git a/web/pgadmin/tools/datagrid/tests/test_data_grid_validate_filter.py b/web/pgadmin/tools/datagrid/tests/test_data_grid_validate_filter.py
deleted file mode 100644
index ef31f0716..000000000
--- a/web/pgadmin/tools/datagrid/tests/test_data_grid_validate_filter.py
+++ /dev/null
@@ -1,92 +0,0 @@
-##########################################################################
-#
-# pgAdmin 4 - PostgreSQL Tools
-#
-# Copyright (C) 2013 - 2022, The pgAdmin Development Team
-# This software is released under the PostgreSQL Licence
-#
-##########################################################################
-
-
-import json
-import uuid
-import random
-
-from unittest.mock import patch
-from pgadmin.browser.server_groups.servers.databases.tests import utils as \
- database_utils
-
-from pgadmin.utils.route import BaseTestGenerator
-from regression import parent_node_dict
-from regression.python_test_utils import test_utils as utils
-from regression.test_setup import config_data
-from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
- utils as schema_utils
-from pgadmin.browser.server_groups.servers.databases.schemas.tables.tests \
- import utils as tables_utils
-from . import utils as data_grid_utils
-from pgadmin.utils.exception import ExecuteError
-
-
-class DatagridValidateFilterTestCase(BaseTestGenerator):
- """
- This will validate filter connection.
- """
-
- scenarios = utils.generate_scenarios(
- 'data_grid_validate_filter',
- data_grid_utils.test_cases
- )
-
- def setUp(self):
- self.database_info = parent_node_dict["database"][-1]
- self.db_name = self.database_info["db_name"]
- self.did = self.database_info["db_id"]
- self.sid = parent_node_dict["server"][-1]["server_id"]
- self.sgid = config_data['server_group']
-
- db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
- self.sid, self.did)
- if not db_con['data']["connected"]:
- raise ExecuteError("Could not connect to database to add a table.")
- self.schema_id = parent_node_dict['schema'][-1]["schema_id"]
- self.schema_name = parent_node_dict['schema'][-1]["schema_name"]
- schema_response = schema_utils.verify_schemas(self.server,
- self.db_name,
- self.schema_name)
- if not schema_response:
- raise ExecuteError("Could not find the schema to add a table.")
- self.table_name = "table_for_wizard%s" % (str(uuid.uuid4())[1:8])
- self.table_id = tables_utils.create_table(self.server, self.db_name,
- self.schema_name,
- self.table_name)
-
- def validate_filter(self):
- response = self.tester.post(
- self.url + str(self.sid) + '/' + str(self.did) + '/' +
- str(self.table_id),
- data=json.dumps(self.test_data),
- content_type='html/json'
- )
- return response
-
- def runTest(self):
- """ This function will update query tool connection."""
-
- if self.is_positive_test:
- response = self.validate_filter()
- actual_response_code = response.status_code
- expected_response_code = self.expected_data['status_code']
- else:
- with patch(self.mock_data["function_name"],
- return_value=eval(self.mock_data["return_value"])):
- response = self.validate_filter()
- actual_response_code = response.status_code
- expected_response_code = self.expected_data['status_code']
-
- self.assertEqual(actual_response_code, expected_response_code)
-
- def tearDown(self):
- """This function disconnect database."""
- database_utils.disconnect_database(self, self.sid,
- self.did)
diff --git a/web/pgadmin/tools/datagrid/tests/test_initialize_data_grid.py b/web/pgadmin/tools/datagrid/tests/test_initialize_data_grid.py
deleted file mode 100644
index 08c253be1..000000000
--- a/web/pgadmin/tools/datagrid/tests/test_initialize_data_grid.py
+++ /dev/null
@@ -1,109 +0,0 @@
-##########################################################################
-#
-# pgAdmin 4 - PostgreSQL Tools
-#
-# Copyright (C) 2013 - 2022, The pgAdmin Development Team
-# This software is released under the PostgreSQL Licence
-#
-##########################################################################
-
-
-import json
-import uuid
-import random
-
-from unittest.mock import patch
-from pgadmin.browser.server_groups.servers.databases.tests import utils as \
- database_utils
-
-from pgadmin.utils.route import BaseTestGenerator
-from regression import parent_node_dict
-from regression.python_test_utils import test_utils as utils
-from regression.test_setup import config_data
-from pgadmin.browser.server_groups.servers.databases.schemas.tests import \
- utils as schema_utils
-from pgadmin.browser.server_groups.servers.databases.schemas.tables.tests \
- import utils as tables_utils
-from . import utils as data_grid_utils
-from pgadmin.utils.exception import ExecuteError
-
-
-class DatagridInitializeTestCase(BaseTestGenerator):
- """
- This will Initialize datagrid
- """
-
- scenarios = utils.generate_scenarios(
- 'data_grid_initialize',
- data_grid_utils.test_cases
- )
-
- def setUp(self):
- self.database_info = parent_node_dict["database"][-1]
- self.db_name = self.database_info["db_name"]
- self.did = self.database_info["db_id"]
- self.sid = parent_node_dict["server"][-1]["server_id"]
- self.sgid = config_data['server_group']
-
- db_con = database_utils.connect_database(self, utils.SERVER_GROUP,
- self.sid, self.did)
- if not db_con['data']["connected"]:
- raise ExecuteError("Could not connect to database to add a table.")
-
- self.schema_id = parent_node_dict['schema'][-1]["schema_id"]
- self.schema_name = parent_node_dict['schema'][-1]["schema_name"]
- schema_response = schema_utils.verify_schemas(self.server,
- self.db_name,
- self.schema_name)
- if not schema_response:
- raise ExecuteError("Could not find the schema to add a table.")
- self.table_name = "table_for_wizard%s" % (str(uuid.uuid4())[1:8])
- self.table_id = tables_utils.create_table(self.server, self.db_name,
- self.schema_name,
- self.table_name)
- self.trans_id = str(random.randint(1, 9999999))
- qt_init = data_grid_utils._init_query_tool(self, self.trans_id,
- self.sgid, self.sid,
- self.did)
-
- if not qt_init['success']:
- raise ExecuteError("Could not initialize query tool.")
-
- def initialize_datagrid(self):
- if self.test_data:
- response = self.tester.post(
- self.url + str(self.trans_id) + '/4/table/' +
- str(self.sgid) + '/' + str(self.sid) + '/' +
- str(self.did) + '/' + str(self.table_id),
- data=json.dumps(self.test_data),
- content_type='html/json'
- )
- else:
- response = self.tester.post(
- self.url + str(self.trans_id) + '/4/table/' +
- str(self.sgid) + '/' + str(self.sid) + '/' +
- str(self.did) + '/' + str(self.table_id),
- content_type='html/json'
- )
- return response
-
- def runTest(self):
- """ This function will update query tool connection."""
-
- if self.is_positive_test:
- response = self.initialize_datagrid()
- actual_response_code = response.status_code
- expected_response_code = self.expected_data['status_code']
- else:
- with patch(self.mock_data["function_name"],
- return_value=eval(self.mock_data["return_value"])):
- response = self.initialize_datagrid()
- actual_response_code = response.status_code
- expected_response_code = self.expected_data['status_code']
-
- self.assertEqual(actual_response_code, expected_response_code)
-
- def tearDown(self):
- """This function disconnect database."""
- database_utils.disconnect_database(self, self.sid,
- self.did)
diff --git a/web/pgadmin/tools/datagrid/tests/utils.py b/web/pgadmin/tools/datagrid/tests/utils.py
deleted file mode 100644
index 78831abce..000000000
--- a/web/pgadmin/tools/datagrid/tests/utils.py
+++ /dev/null
@@ -1,33 +0,0 @@
-##########################################################################
-#
-# pgAdmin 4 - PostgreSQL Tools
-#
-# Copyright (C) 2013 - 2022, The pgAdmin Development Team
-# This software is released under the PostgreSQL Licence
-#
-##########################################################################
-import os
-import json
-
-file_name = os.path.basename(__file__)
-CURRENT_PATH = os.path.dirname(os.path.realpath(__file__))
-with open(CURRENT_PATH + "/datagrid_test_data.json") as data_file:
- test_cases = json.load(data_file)
-
-
-def _init_query_tool(self, trans_id, server_group, server_id, db_id):
- QUERY_TOOL_INIT_URL = '/datagrid/initialize/query_tool'
-
- qt_init = self.tester.post(
- '{0}/{1}/{2}/{3}/{4}'.format(
- QUERY_TOOL_INIT_URL,
- trans_id,
- server_group,
- server_id,
- db_id
- ),
- follow_redirects=True
- )
- assert qt_init.status_code == 200
- qt_init = json.loads(qt_init.data.decode('utf-8'))
- return qt_init
diff --git a/web/pgadmin/tools/debugger/static/js/debugger.js b/web/pgadmin/tools/debugger/static/js/debugger.js
index 44cd53c47..0ac8293c3 100644
--- a/web/pgadmin/tools/debugger/static/js/debugger.js
+++ b/web/pgadmin/tools/debugger/static/js/debugger.js
@@ -14,8 +14,8 @@ define([
'alertify', 'sources/pgadmin', 'pgadmin.browser',
'backbone', 'pgadmin.backgrid', 'codemirror', 'pgadmin.backform',
'pgadmin.tools.debugger.ui', 'pgadmin.tools.debugger.utils',
- 'tools/datagrid/static/js/show_query_tool', 'sources/utils',
- 'pgadmin.authenticate.kerberos', 'tools/datagrid/static/js/datagrid_panel_title',
+ 'tools/sqleditor/static/js/show_query_tool', 'sources/utils',
+ 'pgadmin.authenticate.kerberos', 'tools/sqleditor/static/js/sqleditor_title',
'wcdocker', 'pgadmin.browser.frame',
], function(
gettext, url_for, $, _, Alertify, pgAdmin, pgBrowser, Backbone, Backgrid,
diff --git a/web/pgadmin/tools/debugger/static/js/debugger_utils.js b/web/pgadmin/tools/debugger/static/js/debugger_utils.js
index 8352ae895..fbc2f4b7c 100644
--- a/web/pgadmin/tools/debugger/static/js/debugger_utils.js
+++ b/web/pgadmin/tools/debugger/static/js/debugger_utils.js
@@ -6,8 +6,8 @@
// This software is released under the PostgreSQL Licence
//
//////////////////////////////////////////////////////////////////////////
-import {generateTitle} from '../../../datagrid/static/js/datagrid_panel_title';
-import {_set_dynamic_tab} from '../../../datagrid/static/js/show_query_tool';
+import {generateTitle} from '../../../sqleditor/static/js/sqleditor_title';
+import {_set_dynamic_tab} from '../../../sqleditor/static/js/show_query_tool';
function setFocusToDebuggerEditor(editor, command) {
const TAB = 9;
diff --git a/web/pgadmin/tools/erd/static/js/erd_module.js b/web/pgadmin/tools/erd/static/js/erd_module.js
index b418885e3..9a0e7309b 100644
--- a/web/pgadmin/tools/erd/static/js/erd_module.js
+++ b/web/pgadmin/tools/erd/static/js/erd_module.js
@@ -7,7 +7,7 @@
//
//////////////////////////////////////////////////////////////
-import {getPanelTitle} from 'tools/datagrid/static/js/datagrid_panel_title';
+import {getPanelTitle} from 'tools/sqleditor/static/js/sqleditor_title';
import {getRandomInt, registerDetachEvent} from 'sources/utils';
import Notify from '../../../../static/js/helpers/Notifier';
diff --git a/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/BodyWidget.jsx b/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/BodyWidget.jsx
index 2b598d808..0eb34fc77 100644
--- a/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/BodyWidget.jsx
+++ b/web/pgadmin/tools/erd/static/js/erd_tool/ui_components/BodyWidget.jsx
@@ -22,7 +22,7 @@ import FloatingNote from './FloatingNote';
import {setPanelTitle} from '../../erd_module';
import gettext from 'sources/gettext';
import url_for from 'sources/url_for';
-import {showERDSqlTool} from 'tools/datagrid/static/js/show_query_tool';
+import {showERDSqlTool} from 'tools/sqleditor/static/js/show_query_tool';
import 'wcdocker';
import Theme from '../../../../../../static/js/Theme';
import TableSchema from '../../../../../../browser/server_groups/servers/databases/schemas/tables/static/js/table.ui';
@@ -579,7 +579,7 @@ export default class BodyWidget extends React.Component {
let sqlId = `erd${this.props.params.trans_id}`;
localStorage.setItem(sqlId, sqlScript);
- showERDSqlTool(parentData, sqlId, this.props.params.title, this.props.pgWindow.pgAdmin.DataGrid, this.props.alertify);
+ showERDSqlTool(parentData, sqlId, this.props.params.title, this.props.pgWindow.pgAdmin.Tools.SQLEditor, this.props.alertify);
})
.catch((error)=>{
this.handleAxiosCatch(error);
diff --git a/web/pgadmin/tools/psql/static/js/psql_module.js b/web/pgadmin/tools/psql/static/js/psql_module.js
index e3380152c..f70f1901a 100644
--- a/web/pgadmin/tools/psql/static/js/psql_module.js
+++ b/web/pgadmin/tools/psql/static/js/psql_module.js
@@ -18,7 +18,7 @@ import {retrieveAncestorOfTypeServer} from 'sources/tree/tree_utils';
import pgWindow from 'sources/window';
import Notify from '../../../../static/js/helpers/Notifier';
-import {generateTitle, refresh_db_node} from 'tools/datagrid/static/js/datagrid_panel_title';
+import {generateTitle, refresh_db_node} from 'tools/sqleditor/static/js/sqleditor_title';
export function setPanelTitle(psqlToolPanel, panelTitle) {
diff --git a/web/pgadmin/tools/schema_diff/static/js/schema_diff_ui.js b/web/pgadmin/tools/schema_diff/static/js/schema_diff_ui.js
index d47c266a4..a8b23d9eb 100644
--- a/web/pgadmin/tools/schema_diff/static/js/schema_diff_ui.js
+++ b/web/pgadmin/tools/schema_diff/static/js/schema_diff_ui.js
@@ -15,8 +15,7 @@ import Backbone from 'backbone';
import Slick from 'sources/../bundle/slickgrid';
import pgAdmin from 'sources/pgadmin';
import {setPGCSRFToken} from 'sources/csrf';
-import {generateScript} from 'tools/datagrid/static/js/show_query_tool';
-import 'pgadmin.sqleditor';
+import 'pgadmin.tools.sqleditor';
import pgWindow from 'sources/window';
import _ from 'underscore';
import Notify from '../../../../static/js/helpers/Notifier';
@@ -27,6 +26,7 @@ import { SchemaDiffSelect2Control, SchemaDiffHeaderView,
import { handleDependencies, selectDependenciesForGroup,
selectDependenciesForAll, selectDependencies } from './schema_diff_dependency';
+import { generateScript } from '../../../sqleditor/static/js/show_query_tool';
var wcDocker = window.wcDocker;
@@ -252,6 +252,7 @@ export default class SchemaDiffUI {
let data = res.data;
let server_data = {};
if (data) {
+ let sqlId = `schema${self.trans_id}`;
server_data['sgid'] = data.gid;
server_data['sid'] = data.sid;
server_data['stype'] = data.type;
@@ -259,13 +260,13 @@ export default class SchemaDiffUI {
server_data['user'] = data.user;
server_data['did'] = self.model.get('target_did');
server_data['database'] = data.database;
+ server_data['sql_id'] = sqlId;
if (_.isUndefined(generated_script)) {
generated_script = script_header + 'BEGIN;' + '\n' + self.model.get('diff_ddl') + '\n' + 'END;';
}
-
- pgWindow.pgAdmin.ddl_diff = generated_script;
- generateScript(server_data, pgWindow.pgAdmin.DataGrid, Alertify);
+ localStorage.setItem(sqlId, generated_script);
+ generateScript(server_data, pgWindow.pgAdmin.Tools.SQLEditor, Alertify);
}
$('#diff_fetching_data').find('.schema-diff-busy-text').text('');
diff --git a/web/pgadmin/tools/search_objects/static/js/search_objects_dialog.js b/web/pgadmin/tools/search_objects/static/js/search_objects_dialog.js
index af8d0cfb3..44d0e0c3c 100644
--- a/web/pgadmin/tools/search_objects/static/js/search_objects_dialog.js
+++ b/web/pgadmin/tools/search_objects/static/js/search_objects_dialog.js
@@ -9,7 +9,7 @@
import gettext from 'sources/gettext';
import {Dialog} from 'sources/alertify/dialog';
-import {getPanelTitle} from 'tools/datagrid/static/js/datagrid_panel_title';
+import {getPanelTitle} from 'tools/sqleditor/static/js/sqleditor_title';
import {retrieveAncestorOfTypeDatabase} from 'sources/tree/tree_utils';
export default class SearchObjectsDialog extends Dialog {
diff --git a/web/pgadmin/tools/sqleditor/__init__.py b/web/pgadmin/tools/sqleditor/__init__.py
index ac85b5eaf..7e81cdbdb 100644
--- a/web/pgadmin/tools/sqleditor/__init__.py
+++ b/web/pgadmin/tools/sqleditor/__init__.py
@@ -11,16 +11,21 @@
import os
import pickle
import re
+import random
from urllib.parse import unquote
+from threading import Lock
import simplejson as json
-from config import PG_DEFAULT_DRIVER, ON_DEMAND_RECORD_COUNT
+from config import PG_DEFAULT_DRIVER, ON_DEMAND_RECORD_COUNT,\
+ ALLOW_SAVE_PASSWORD
+from werkzeug.user_agent import UserAgent
from flask import Response, url_for, render_template, session, current_app
-from flask import request, jsonify
+from flask import request
from flask_babel import gettext
from flask_security import login_required, current_user
from pgadmin.misc.file_manager import Filemanager
-from pgadmin.tools.sqleditor.command import QueryToolCommand
+from pgadmin.tools.sqleditor.command import QueryToolCommand, ObjectRegistry, \
+ SQLFilter
from pgadmin.tools.sqleditor.utils.constant_definition import ASYNC_OK, \
ASYNC_EXECUTION_ABORTED, \
CONNECTION_STATUS_MESSAGE_MAPPING, TX_STATUS_INERROR
@@ -33,7 +38,8 @@ from pgadmin.utils.ajax import make_json_response, bad_request, \
success_return, internal_server_error
from pgadmin.utils.driver import get_driver
from pgadmin.utils.exception import ConnectionLost, SSHTunnelConnectionLost, \
- CryptKeyMissing
+ CryptKeyMissing, ObjectGone
+from pgadmin.browser.utils import underscore_unescape
from pgadmin.utils.menu import MenuItem
from pgadmin.utils.sqlautocomplete.autocomplete import SQLAutoComplete
from pgadmin.tools.sqleditor.utils.query_tool_preferences import \
@@ -48,10 +54,13 @@ from pgadmin.utils.constants import MIMETYPE_APP_JS, \
SERVER_CONNECTION_CLOSED, ERROR_MSG_TRANS_ID_NOT_FOUND, ERROR_FETCHING_DATA
from pgadmin.model import Server, ServerGroup
from pgadmin.tools.schema_diff.node_registry import SchemaDiffRegistry
+from pgadmin.settings import get_setting
+from pgadmin.utils.preferences import Preferences
MODULE_NAME = 'sqleditor'
TRANSACTION_STATUS_CHECK_FAILED = gettext("Transaction status check failed.")
_NODES_SQL = 'nodes.sql'
+sqleditor_close_session_lock = Lock()
class SqlEditorModule(PgAdminModule):
@@ -73,13 +82,6 @@ class SqlEditorModule(PgAdminModule):
url=url_for('help.static', filename='index.html'))
]}
- def get_own_javascripts(self):
- return [{
- 'name': 'pgadmin.sqleditor',
- 'path': url_for('sqleditor.index') + "sqleditor",
- 'when': None
- }]
-
def get_panels(self):
return []
@@ -89,6 +91,15 @@ class SqlEditorModule(PgAdminModule):
list: URL endpoints for sqleditor module
"""
return [
+ 'sqleditor.initialize_viewdata',
+ 'sqleditor.initialize_sqleditor',
+ 'sqleditor.initialize_sqleditor_with_did',
+ 'sqleditor.filter_validate',
+ 'sqleditor.filter',
+ 'sqleditor.panel',
+ 'sqleditor.close',
+ 'sqleditor.update_sqleditor_connection',
+
'sqleditor.view_data_start',
'sqleditor.query_tool_start',
'sqleditor.poll',
@@ -117,6 +128,7 @@ class SqlEditorModule(PgAdminModule):
'sqleditor.get_macros',
'sqleditor.set_macros',
'sqleditor.get_new_connection_data',
+ 'sqleditor.get_new_connection_servers',
'sqleditor.get_new_connection_database',
'sqleditor.get_new_connection_user',
'sqleditor._check_server_connection_status',
@@ -125,6 +137,20 @@ class SqlEditorModule(PgAdminModule):
'sqleditor.connect_server_with_user',
]
+ def on_logout(self, user):
+ """
+ This is a callback function when user logout from pgAdmin
+ :param user:
+ :return:
+ """
+ with sqleditor_close_session_lock:
+ if 'gridData' in session:
+ for trans_id in session['gridData']:
+ close_sqleditor_session(trans_id)
+
+ # Delete all grid data from session variable
+ del session['gridData']
+
def register_preferences(self):
register_query_tool_preferences(self)
@@ -140,6 +166,480 @@ def index():
)
+@blueprint.route("/filter", endpoint='filter')
+@login_required
+def show_filter():
+ return render_template(MODULE_NAME + '/filter.html')
+
+
+@blueprint.route(
+ '/initialize/viewdata////'
+ '///',
+ methods=["PUT", "POST"],
+ endpoint="initialize_viewdata"
+)
+@login_required
+def initialize_viewdata(trans_id, cmd_type, obj_type, sgid, sid, did, obj_id):
+ """
+ This method is responsible for creating an asynchronous connection.
+ After creating the connection it will instantiate and initialize
+ the object as per the object type. It will also create a unique
+ transaction id and store the information into session variable.
+
+ Args:
+ cmd_type: Contains value for which menu item is clicked.
+ obj_type: Contains type of selected object for which data grid to
+ be render
+ sgid: Server group Id
+ sid: Server Id
+ did: Database Id
+ obj_id: Id of currently selected object
+ """
+
+ if request.data:
+ filter_sql = json.loads(request.data, encoding='utf-8')
+ else:
+ filter_sql = request.args or request.form
+
+ # Create asynchronous connection using random connection id.
+ conn_id = str(random.randint(1, 9999999))
+ try:
+ manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
+ # default_conn is same connection which is created when user connect to
+ # database from tree
+ default_conn = manager.connection(did=did)
+ conn = manager.connection(did=did, conn_id=conn_id,
+ auto_reconnect=False,
+ use_binary_placeholder=True,
+ array_to_string=True)
+ except (ConnectionLost, SSHTunnelConnectionLost):
+ raise
+ except Exception as e:
+ current_app.logger.error(e)
+ return internal_server_error(errormsg=str(e))
+
+ status, msg = default_conn.connect()
+ if not status:
+ current_app.logger.error(msg)
+ return internal_server_error(errormsg=str(msg))
+
+ status, msg = conn.connect()
+ if not status:
+ current_app.logger.error(msg)
+ return internal_server_error(errormsg=str(msg))
+ try:
+ # if object type is partition then it is nothing but a table.
+ if obj_type == 'partition':
+ obj_type = 'table'
+
+ # Get the object as per the object type
+ command_obj = ObjectRegistry.get_object(
+ obj_type, conn_id=conn_id, sgid=sgid, sid=sid,
+ did=did, obj_id=obj_id, cmd_type=cmd_type,
+ sql_filter=filter_sql
+ )
+ except ObjectGone:
+ raise
+ except Exception as e:
+ current_app.logger.error(e)
+ return internal_server_error(errormsg=str(e))
+
+ if 'gridData' not in session:
+ sql_grid_data = dict()
+ else:
+ sql_grid_data = session['gridData']
+
+ # Use pickle to store the command object which will be used later by the
+ # sql grid module.
+ sql_grid_data[str(trans_id)] = {
+ # -1 specify the highest protocol version available
+ 'command_obj': pickle.dumps(command_obj, -1)
+ }
+
+ # Store the grid dictionary into the session variable
+ session['gridData'] = sql_grid_data
+
+ return make_json_response(
+ data={
+ 'conn_id': conn_id
+ }
+ )
+
+
+@blueprint.route(
+ '/panel/',
+ methods=["POST"],
+ endpoint='panel'
+)
+def panel(trans_id):
+ """
+ This method calls index.html to render the data grid.
+
+ Args:
+ trans_id: unique transaction id
+ """
+
+ params = None
+ if request.args:
+ params = {k: v for k, v in request.args.items()}
+
+ close_url = ''
+ if request.form:
+ params['title'] = underscore_unescape(request.form['title'])
+ close_url = request.form['close_url']
+ if 'sql_filter' in request.form:
+ params['sql_filter'] = request.form['sql_filter']
+ if 'query_url' in request.form:
+ params['query_url'] = request.form['query_url']
+
+ params['trans_id'] = trans_id
+
+ # We need client OS information to render correct Keyboard shortcuts
+ params['client_platform'] = UserAgent(request.headers.get('User-Agent'))\
+ .platform
+
+ params['is_linux'] = False
+ from sys import platform as _platform
+ if "linux" in _platform:
+ params['is_linux'] = True
+
+ # Fetch the server details
+ params['bgcolor'] = None
+ params['fgcolor'] = None
+
+ s = Server.query.filter_by(id=params['sid']).first()
+ if s and s.bgcolor:
+ # If background is set to white means we do not have to change
+ # the title background else change it as per user specified
+ # background
+ if s.bgcolor != '#ffffff':
+ params['bgcolor'] = s.bgcolor
+ params['fgcolor'] = s.fgcolor or 'black'
+
+ params['server_name'] = s.name
+ params['username'] = s.username
+ params['layout'] = get_setting('SQLEditor/Layout')
+ params['macros'] = get_user_macros()
+ params['is_desktop_mode'] = current_app.PGADMIN_RUNTIME
+
+ return render_template(
+ "sqleditor/index.html",
+ close_url=close_url,
+ params=json.dumps(params),
+ requirejs=True,
+ basejs=True,
+ )
+
+
+@blueprint.route(
+ '/initialize/sqleditor////',
+ methods=["POST"], endpoint='initialize_sqleditor_with_did'
+)
+@blueprint.route(
+ '/initialize/sqleditor///',
+ methods=["POST"], endpoint='initialize_sqleditor'
+)
+@login_required
+def initialize_sqleditor(trans_id, sgid, sid, did=None):
+ """
+ This method is responsible for instantiating and initializing
+ the query tool object. It will also create a unique
+ transaction id and store the information into session variable.
+
+ Args:
+ sgid: Server group Id
+ sid: Server Id
+ did: Database Id
+ """
+ connect = True
+ # Read the data if present. Skipping read may cause connection
+ # reset error if data is sent from the client
+ if request.data:
+ _ = request.data
+
+ req_args = request.args
+ if ('recreate' in req_args and
+ req_args['recreate'] == '1'):
+ connect = False
+
+ is_error, errmsg, conn_id, version = _init_sqleditor(
+ trans_id, connect, sgid, sid, did)
+ if is_error:
+ return errmsg
+
+ return make_json_response(
+ data={
+ 'connId': str(conn_id),
+ 'serverVersion': version,
+ }
+ )
+
+
+def _connect(conn, **kwargs):
+ """
+ Connect the database.
+ :param conn: Connection instance.
+ :param kwargs: user, role and password data from user.
+ :return:
+ """
+ user = None
+ role = None
+ password = None
+ is_ask_password = False
+ if 'user' in kwargs and 'role' in kwargs:
+ user = kwargs['user']
+ role = kwargs['role'] if kwargs['role'] else None
+ password = kwargs['password'] if kwargs['password'] else None
+ is_ask_password = True
+ if user:
+ status, msg = conn.connect(user=user, role=role,
+ password=password)
+ else:
+ status, msg = conn.connect()
+
+ return status, msg, is_ask_password, user, role, password
+
+
+def _init_sqleditor(trans_id, connect, sgid, sid, did, **kwargs):
+ # Create asynchronous connection using random connection id.
+ conn_id = str(random.randint(1, 9999999))
+
+ manager = get_driver(PG_DEFAULT_DRIVER).connection_manager(sid)
+
+ if did is None:
+ did = manager.did
+ try:
+ command_obj = ObjectRegistry.get_object(
+ 'query_tool', conn_id=conn_id, sgid=sgid, sid=sid, did=did
+ )
+ except Exception as e:
+ current_app.logger.error(e)
+ return True, internal_server_error(errormsg=str(e)), '', ''
+
+ try:
+ conn = manager.connection(did=did, conn_id=conn_id,
+ auto_reconnect=False,
+ use_binary_placeholder=True,
+ array_to_string=True)
+
+ if connect:
+ status, msg, is_ask_password, user, role, password = _connect(
+ conn, **kwargs)
+ if not status:
+ current_app.logger.error(msg)
+ if is_ask_password:
+ server = Server.query.filter_by(id=sid).first()
+ return True, make_json_response(
+ success=0,
+ status=428,
+ result=render_template(
+ 'servers/password.html',
+ server_label=server.name,
+ username=user,
+ errmsg=msg,
+ _=gettext,
+ allow_save_password=True if
+ ALLOW_SAVE_PASSWORD and
+ session['allow_save_password'] else False,
+ )
+ ), '', ''
+ else:
+ return True, internal_server_error(
+ errormsg=str(msg)), '', ''
+ except (ConnectionLost, SSHTunnelConnectionLost) as e:
+ current_app.logger.error(e)
+ raise
+ except Exception as e:
+ current_app.logger.error(e)
+ return True, internal_server_error(errormsg=str(e)), '', ''
+
+ if 'gridData' not in session:
+ sql_grid_data = dict()
+ else:
+ sql_grid_data = session['gridData']
+
+ # Set the value of auto commit and auto rollback specified in Preferences
+ pref = Preferences.module('sqleditor')
+ command_obj.set_auto_commit(pref.preference('auto_commit').get())
+ command_obj.set_auto_rollback(pref.preference('auto_rollback').get())
+
+ # Use pickle to store the command object which will be used
+ # later by the sql grid module.
+ sql_grid_data[str(trans_id)] = {
+ # -1 specify the highest protocol version available
+ 'command_obj': pickle.dumps(command_obj, -1)
+ }
+
+ # Store the grid dictionary into the session variable
+ session['gridData'] = sql_grid_data
+
+ return False, '', conn_id, manager.version
+
+
+@blueprint.route(
+ '/initialize/sqleditor/update_connection//'
+ '//',
+ methods=["POST"], endpoint='update_sqleditor_connection'
+)
+def update_sqleditor_connection(trans_id, sgid, sid, did):
+ # Remove transaction Id.
+ with sqleditor_close_session_lock:
+ data = json.loads(request.data, encoding='utf-8')
+
+ if 'gridData' not in session:
+ return make_json_response(data={'status': True})
+
+ grid_data = session['gridData']
+
+ # Return from the function if transaction id not found
+ if str(trans_id) not in grid_data:
+ return make_json_response(data={'status': True})
+
+ connect = True
+
+ req_args = request.args
+ if ('recreate' in req_args and
+ req_args['recreate'] == '1'):
+ connect = False
+
+ new_trans_id = str(random.randint(1, 9999999))
+ kwargs = {
+ 'user': data['user'],
+ 'role': data['role'] if 'role' in data else None,
+ 'password': data['password'] if 'password' in data else None
+ }
+
+ is_error, errmsg, conn_id, version = _init_sqleditor(
+ new_trans_id, connect, sgid, sid, did, **kwargs)
+
+ if is_error:
+ return errmsg
+ else:
+ try:
+ # Check the transaction and connection status
+ status, error_msg, conn, trans_obj, session_obj = \
+ check_transaction_status(trans_id)
+
+ status, error_msg, new_conn, new_trans_obj, new_session_obj = \
+ check_transaction_status(new_trans_id)
+
+ new_session_obj['primary_keys'] = session_obj[
+ 'primary_keys'] if 'primary_keys' in session_obj else None
+ new_session_obj['columns_info'] = session_obj[
+ 'columns_info'] if 'columns_info' in session_obj else None
+ new_session_obj['client_primary_key'] = session_obj[
+ 'client_primary_key'] if 'client_primary_key'\
+ in session_obj else None
+
+ close_sqleditor_session(trans_id)
+ # Remove the information of unique transaction id from the
+ # session variable.
+ grid_data.pop(str(trans_id), None)
+ session['gridData'] = grid_data
+ except Exception as e:
+ current_app.logger.error(e)
+
+ return make_json_response(
+ data={
+ 'connId': str(conn_id),
+ 'serverVersion': version,
+ 'trans_id': new_trans_id
+ }
+ )
+
+
+@blueprint.route('/close/', methods=["DELETE"], endpoint='close')
+def close(trans_id):
+ """
+ This method is used to close the asynchronous connection
+ and remove the information of unique transaction id from
+ the session variable.
+
+ Args:
+ trans_id: unique transaction id
+ """
+ with sqleditor_close_session_lock:
+ if 'gridData' not in session:
+ return make_json_response(data={'status': True})
+
+ grid_data = session['gridData']
+ # Return from the function if transaction id not found
+ if str(trans_id) not in grid_data:
+ return make_json_response(data={'status': True})
+
+ try:
+ close_sqleditor_session(trans_id)
+ # Remove the information of unique transaction id from the
+ # session variable.
+ grid_data.pop(str(trans_id), None)
+ session['gridData'] = grid_data
+ except Exception as e:
+ current_app.logger.error(e)
+ return internal_server_error(errormsg=str(e))
+
+ return make_json_response(data={'status': True})
+
+
+@blueprint.route(
+ '/filter/validate///',
+ methods=["PUT", "POST"], endpoint='filter_validate'
+)
+@login_required
+def validate_filter(sid, did, obj_id):
+ """
+ This method is used to validate the sql filter.
+
+ Args:
+ sid: Server Id
+ did: Database Id
+ obj_id: Id of currently selected object
+ """
+ if request.data:
+ filter_sql = json.loads(request.data, encoding='utf-8')
+ else:
+ filter_sql = request.args or request.form
+
+ try:
+ # Create object of SQLFilter class
+ sql_filter_obj = SQLFilter(sid=sid, did=did, obj_id=obj_id)
+
+ # Call validate_filter method to validate the SQL.
+ status, res = sql_filter_obj.validate_filter(filter_sql)
+ except ObjectGone:
+ raise
+ except Exception as e:
+ current_app.logger.error(e)
+ return internal_server_error(errormsg=str(e))
+
+ return make_json_response(data={'status': status, 'result': res})
+
+
+def close_sqleditor_session(trans_id):
+ """
+ This function is used to cancel the transaction and release the connection.
+
+ :param trans_id: Transaction id
+ :return:
+ """
+ if 'gridData' in session and str(trans_id) in session['gridData']:
+ cmd_obj_str = session['gridData'][str(trans_id)]['command_obj']
+ # Use pickle.loads function to get the command object
+ cmd_obj = pickle.loads(cmd_obj_str)
+
+ # if connection id is None then no need to release the connection
+ if cmd_obj.conn_id is not None:
+ manager = get_driver(
+ PG_DEFAULT_DRIVER).connection_manager(cmd_obj.sid)
+ if manager is not None:
+ conn = manager.connection(
+ did=cmd_obj.did, conn_id=cmd_obj.conn_id)
+
+ # Release the connection
+ if conn.connected():
+ conn.cancel_transaction(cmd_obj.conn_id, cmd_obj.did)
+ manager.release(did=cmd_obj.did, conn_id=cmd_obj.conn_id)
+
+
def check_transaction_status(trans_id):
"""
This function is used to check the transaction id
@@ -286,8 +786,6 @@ def start_view_data(trans_id):
'filter_applied': filter_applied,
'limit': limit, 'can_edit': can_edit,
'can_filter': can_filter, 'sql': sql,
- 'info_notifier_timeout':
- blueprint.info_notifier_timeout.get() * 1000
}
)
@@ -1345,7 +1843,7 @@ def start_query_download_tool(trans_id):
errormsg=TRANSACTION_STATUS_CHECK_FAILED
)
- data = request.values if request.values else None
+ data = request.values if request.values else request.json
if data is None:
return make_json_response(
status=410,
@@ -1534,8 +2032,12 @@ def _check_server_connection_status(sgid, sid=None):
'/new_connection_dialog//',
methods=["GET"], endpoint='get_new_connection_data'
)
+@blueprint.route(
+ '/new_connection_dialog',
+ methods=["GET"], endpoint='get_new_connection_servers'
+)
@login_required
-def get_new_connection_data(sgid, sid=None):
+def get_new_connection_data(sgid=None, sid=None):
"""
This method is used to get required data for get new connection.
:extract_sql_from_network_parameters,
@@ -1822,7 +2324,9 @@ def connect_server(sid, usr=None):
)
view = SchemaDiffRegistry.get_node_view('server')
- return view.connect(server.servergroup_id, sid, user_name=user)
+ return view.connect(
+ server.servergroup_id, sid, user_name=user, resp_json=True
+ )
@blueprint.route(
@@ -1886,7 +2390,8 @@ def clear_query_history(trans_id):
status, error_msg, conn, trans_obj, session_ob = \
check_transaction_status(trans_id)
- return QueryHistory.clear(current_user.id, trans_obj.sid, conn.db)
+ filter = request.json
+ return QueryHistory.clear(current_user.id, trans_obj.sid, conn.db, filter)
@blueprint.route(
diff --git a/web/pgadmin/tools/sqleditor/static/css/sqleditor.css b/web/pgadmin/tools/sqleditor/static/css/sqleditor.css
deleted file mode 100644
index 0c5688976..000000000
--- a/web/pgadmin/tools/sqleditor/static/css/sqleditor.css
+++ /dev/null
@@ -1,401 +0,0 @@
-#main-editor_panel {
- position: absolute;
- left: 0;
- right: 0;
- top : 0;
- bottom: 0;
-}
-
-.sql-editor {
- position: absolute;
- left: 0;
- right: 0;
- top : 0;
- bottom: 0;
-}
-
-.filter-container .CodeMirror-scroll {
- min-height: 120px;
-}
-
-.filter-container .sql-textarea{
- box-shadow: 0.1px 0.1px 3px #000;
- margin-bottom: 5px;
-}
-
-#filter .btn-group {
- margin-right: 2px;
- float: right;
-}
-
-#filter .btn-group > button {
- padding: 3px;
-}
-
-#filter .btn-group .btn-primary {
- margin: auto !important;
-}
-
-.has-select-all table thead tr th:nth-child(1),
-.has-select-all table tbody tr td:nth-child(1) {
- width: 35px !important;
- max-width: 35px !important;
- min-width: 35px !important;
-}
-.sql-status-cell {
- max-width: 30px;
-}
-
-.btn-circle {
- width: 16px;
- height: 16px;
- text-align: center;
- padding: 0;
- font-size: 10px;
- line-height: 1.428571429;
- border-radius: 10px;
- cursor: auto;
-}
-
-.visibility-hidden {
- visibility: hidden;
-}
-
-.sql-editor-mark {
- border-bottom: 2px dotted red;
-}
-
-.CodeMirror {
- min-height: 100%;
- height: 100%;
-}
-
-#output-panel {
- height: 100% !important;
-}
-
-.sql-editor-explain {
- height: 100%;
- width: 100%;
- overflow: auto;
-}
-
-
-.sqleditor-hint {
- padding-left: 20px;
-}
-
-.CodeMirror-hint .fa::before {
- padding-right: 7px;
-}
-
-h2 {
- font-size: 10pt;
- border-bottom: 1px dotted gray;
-}
-
-ul {
- margin-left: 0;
- padding: 0;
- cursor: default;
-}
-
-li {
- padding: 0 0 0 0px;
- list-style: none;
- margin: 0;
-}
-
-#datagrid {
- background: white;
- outline: 0;
- font-size: 9pt;
-}
-
-#datagrid .slick-header-column.ui-state-default {
- height: 32px !important;
-}
-
-#datagrid .grid-header label {
- display: inline-block;
- font-weight: bold;
- margin: auto auto auto 6px;
-}
-
-.grid-header .ui-icon {
- margin: 4px 4px auto 6px;
- background-color: transparent;
- border-color: transparent;
-}
-
-.slick-row .cell-actions {
- text-align: left;
-}
-
-/* Slick.Editors.Text, Slick.Editors.Date */
-#datagrid .slick-header > input.editor-text {
- width: 100%;
- height: 100%;
- border: 0;
- margin: 0;
- background: transparent;
- outline: 0;
- padding: 0;
-}
-
-/* Slick.Editors.Checkbox */
-#datagrid .slick-header > input.editor-checkbox {
- margin: 0;
- height: 100%;
- padding: 0;
- border: 0;
-}
-
-.slick-row.selected .cell-selection {
- background-color: transparent; /* show default selected row background */
-}
-
-#datagrid .slick-header .ui-state-default,
-#datagrid .slick-header .ui-widget-content.ui-state-default,
-#datagrid .slick-header .ui-widget-header .ui-state-default {
- background: none;
-}
-
-#datagrid .slick-header .slick-header-column .column-name {
- font-weight: bold;
- display: block;
-}
-
-.column-description {
- display: table-cell;
-}
-
-.long_text_editor {
- margin-left: 5px;
- font-size: 12px !important;
- padding: 1px 7px;
-}
-
-/* Slick.Editors.Text, Slick.Editors.Date */
-input.editor-text {
- width: 100%;
- height: 100%;
- border: 0;
- margin: 0;
- background: transparent;
- outline: 0;
- padding: 0;
-}
-
-/* Slick.Editors.Text, Slick.Editors.Date */
-textarea.editor-text {
- width: 100%;
- height: 100%;
- border: 0;
- margin: 0;
- background: transparent;
- outline: 0;
- padding: 0;
-}
-
-/* Slick.Editors.Checkbox */
-input.editor-checkbox {
- margin: 0;
- height: 100%;
- padding: 0;
- border: 0;
-}
-
-/* remove outlined border on focus */
-input.editor-checkbox:focus {
- outline: none;
-}
-
-.slick-cell span[data-cell-type="row-header-selector"] {
- display: block;
- text-align: center;
-}
-
-/*
- SlickGrid, To fix the issue of width misalignment between Column Header &
- actual Column in Mozilla Firefox browser
- Ref: https://github.com/mleibman/SlickGrid/issues/742
-*/
-.slickgrid, .slickgrid *, .slick-header-column {
- box-sizing: content-box;
- -moz-box-sizing: content-box;
- -webkit-box-sizing: content-box;
- -ms-box-sizing: content-box;
-}
-
-.select-all-icon {
- margin-left: 9px;
- margin-right: 4px;
- vertical-align: bottom;
- position: absolute;
- bottom: 4px;
- right: 0;
-}
-
-/* Style for text editor */
-.pg_buttons {
- text-align:right;
-}
-
-#datagrid .slick-row .slick-cell {
- white-space: pre;
-}
-
-.connection_status {
- font-size: 1rem;
- width: 40px;
-}
-
-.ajs-body .warn-header {
- font-size: 13px;
- font-weight: bold;
- line-height: 3em;
-}
-
-.ajs-body .warn-body {
- font-size: 13px;
-}
-
-.ajs-body .warn-footer {
- font-size: 13px;
- line-height: 3em;
-}
-
-/* For Filter status bar */
-.data_sorting_dialog .pg-prop-status-bar {
- position: absolute;
- left: 0;
- right: 0;
- bottom: 0;
- z-index: 5;
-}
-
-.data_sorting_dialog .CodeMirror-gutter-wrapper {
- left: -30px !important;
-}
-
-.data_sorting_dialog .CodeMirror-gutters {
- left: 0px !important;
-}
-
-.data_sorting_dialog .custom_height_css_class {
- height: 100px;
-}
-
-.data_sorting_dialog .data_sorting {
- padding: 10px 0px;
-}
-
-.connection-status-hide {
- display: none !important;
-}
-
-/* For geometry data viewer panel */
-.sql-editor-geometry-viewer{
- width: 100%;
- height: 100%;
-}
-
-.geometry-viewer-container {
- width: 100%;
- height: 100%;
- background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAANElEQVQoU2O8e/fuf2VlZUYGLAAkB5bApggmBteJrAiZjWI0SAJkIrKVxCvAawVeRxLyJgB+Ajc1cwux9wAAAABJRU5ErkJggg==);
- /* Let's keep the background as fff irrespective of theme
- * make geometry viewer look clean
- */
- background-color: #fff;
- }
-
-
-/* For geometry column button */
-.div-view-geometry-column, .editable-column-header-icon {
- float: right;
- height: 100%;
- display: flex;
- display: -webkit-flex;
- align-items: center;
- padding-right: 6px;
-}
-
-/* For leaflet popup */
-.leaflet-popup-content-wrapper {
- border-radius: 2px;
-}
-
-.leaflet-popup-content {
- margin: 5px;
- padding: 10px 10px 0;
- overflow-y: scroll;
- overflow-x: hidden;
-}
-
-/* For geometry viewer property table */
-.view-geometry-property-table {
- table-layout: fixed;
- white-space: nowrap;
- padding: 0;
-}
-
-.view-geometry-property-table th {
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-.view-geometry-property-table td {
- overflow: hidden;
- text-overflow: ellipsis;
-}
-
-/* For geometry viewer info control */
-.geometry-viewer-info-control {
- padding: 5px;
- background: white;
- border: 2px solid rgba(0, 0, 0, 0.2);
- background-clip: padding-box;
- border-radius: 2px;
-}
-
-.geometry-viewer-info-control i{
- margin: 0 0 0 4px;
-}
-
-.hide-vertical-scrollbar {
- overflow-y: hidden;
-}
-
-/* Macros */
-
-.macro-tab {
- top: 0px !important;
-}
-
-.macro-tab .tab-pane {
- padding: 0px !important;
-}
-
-.macro_dialog .CodeMirror {
- overflow-y: auto;
- resize: vertical;
-}
-.macro_dialog .sql-cell > div {
- overflow-y: auto;
- resize: vertical;
-}
-
-.macro_dialog .CodeMirror-cursor {
- width: 1px !important;
- height: 18px !important;
-}
-
-.macro_dialog .pg-prop-status-bar {
- z-index: 1;
-}
-
-.new-connection-dialog-style {
- width: 100% !important;
-}
diff --git a/web/pgadmin/tools/sqleditor/static/img/loading.gif b/web/pgadmin/tools/sqleditor/static/img/loading.gif
deleted file mode 100644
index 500fa0860e2eb9883f86c30da579008475f596c4..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1728
zcmaLUYfMvV8o=?_0=-b6t(-%J4!uyhmeRt3-fxHApp^o00J&3YK}w+uij3`5*3<`k|yaM3eyLSM9n>TOn-@iW?4B|NMcDrM-*pVYg?%ut7^ytz2{QTnL
z;_~uxygw9DW5*e$LCr_R{aNt08b~cB@
zdHneC%a<>=ZQB-)$6vjA1tC0s{P>$UZ{EIrd*Q-`D_5?(e*OB^ty{CRv(KMDzj5Qn
z!-o&=-Me?~+O_57<;BIt`}gnPzJ2?}ix+q9+}XZ;`>9i>=I7_@>gt-BnmRf9ks{mo8nJn3%vY?8%cSDwS&Q-o0&YZECezCX-E1PuJJiXJ%&Z-n}~<4p&uGUA}zz
z>eZ`{9z8m9=FHBWJNNC|clhw(*49>rVf=o7ZEdYmsXTV1KU!N-26ZMqmCDb}S81SLYt@k~_G&4uLy!X?iJv(Mtad9*P7}>x4m(UqN9KUp
z4cQs!oF2D9jv#9esWw9{TRdlTx*$)uMn;=eSsqf9EiaI0F`j{I`AGMv!swTK4QQ4VL3vl=%$GtQku4D@Q9@6zA&>b(I!>@?u1M#JLDn#_tU
z%4JE-a$p!MHD8!RdJGmb?UQFZpd%zF~G*z^!5CC
zPd5jmQ_FRQQ0vj3uU@wi>ag#bu1J*B|C=fh1iW;ziXcMeP4zx{>%>T>x@~NYg~64B
z{IqNP|MkaiK7u^*q;G0;_NS)?#&_+lKZltOmd1%_2#04qwm7uz`^D9Pv))0V)WK8Ni?>W@PR
zn$_~hZUe=w-!`^2LlD{S{4Sg=U}wl{darJfuhjOl-*B|v'+panelTitle+'');
+}
+
+export default class SQLEditor {
+ static instance;
+
+ static getInstance(...args) {
+ if(!SQLEditor.instance) {
+ SQLEditor.instance = new SQLEditor(...args);
+ }
+ return SQLEditor.instance;
+ }
+
+ SUPPORTED_NODES = [
+ 'table', 'view', 'mview',
+ 'foreign_table', 'catalog_object', 'partition',
+ ];
+
+ /* Enable/disable View data menu in tools based
+ * on node selected. if selected node is present
+ * in supportedNodes, menu will be enabled
+ * otherwise disabled.
+ */
+ viewMenuEnabled(obj) {
+ var isEnabled = (() => {
+ if (!_.isUndefined(obj) && !_.isNull(obj))
+ return (_.indexOf(this.SUPPORTED_NODES, obj._type) !== -1 ? true : false);
+ else
+ return false;
+ })();
+
+ toolBar.enable(gettext('View Data'), isEnabled);
+ toolBar.enable(gettext('Filtered Rows'), isEnabled);
+ return isEnabled;
+ }
+
+ /* Enable/disable Query tool menu in tools based
+ * on node selected. if selected node is present
+ * in unsupported_nodes, menu will be disabled
+ * otherwise enabled.
+ */
+ queryToolMenuEnabled(obj) {
+ var isEnabled = (() => {
+ if (!_.isUndefined(obj) && !_.isNull(obj)) {
+ if (_.indexOf(pgAdmin.unsupported_nodes, obj._type) == -1) {
+ if (obj._type == 'database' && obj.allowConn) {
+ return true;
+ } else if (obj._type != 'database') {
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ })();
+
+ toolBar.enable(gettext('Query Tool'), isEnabled);
+ return isEnabled;
+ }
+
+ init() {
+ if(this.initialized)
+ return;
+ this.initialized = true;
+
+ let self = this;
+ /* Cache may take time to load for the first time
+ * Keep trying till available
+ */
+ let cacheIntervalId = setInterval(function() {
+ if(pgBrowser.preference_version() > 0) {
+ self.preferences = pgBrowser.get_preferences_for_module('sqleditor');
+ clearInterval(cacheIntervalId);
+ }
+ },0);
+
+ pgBrowser.onPreferencesChange('sqleditor', function() {
+ self.preferences = pgBrowser.get_preferences_for_module('sqleditor');
+ });
+
+ // Define the nodes on which the menus to be appear
+ var menus = [{
+ name: 'query_tool',
+ module: this,
+ applies: ['tools'],
+ callback: 'showQueryTool',
+ enable: self.queryToolMenuEnabled,
+ priority: 1,
+ label: gettext('Query Tool'),
+ icon: 'pg-font-icon icon-query_tool',
+ data:{
+ applies: 'tools',
+ data_disabled: gettext('Please select a database from the browser tree to access Query Tool.'),
+ },
+ }];
+
+ // Create context menu
+ for (const supportedNode of self.SUPPORTED_NODES) {
+ menus.push({
+ name: 'view_all_rows_context_' + supportedNode,
+ node: supportedNode,
+ module: this,
+ data: {
+ mnuid: 3,
+ },
+ applies: ['context', 'object'],
+ callback: 'showViewData',
+ enable: self.viewMenuEnabled,
+ category: 'view_data',
+ priority: 101,
+ label: gettext('All Rows'),
+ }, {
+ name: 'view_first_100_rows_context_' + supportedNode,
+ node: supportedNode,
+ module: this,
+ data: {
+ mnuid: 1,
+ },
+ applies: ['context', 'object'],
+ callback: 'showViewData',
+ enable: self.viewMenuEnabled,
+ category: 'view_data',
+ priority: 102,
+ label: gettext('First 100 Rows'),
+ }, {
+ name: 'view_last_100_rows_context_' + supportedNode,
+ node: supportedNode,
+ module: this,
+ data: {
+ mnuid: 2,
+ },
+ applies: ['context', 'object'],
+ callback: 'showViewData',
+ enable: self.viewMenuEnabled,
+ category: 'view_data',
+ priority: 103,
+ label: gettext('Last 100 Rows'),
+ }, {
+ name: 'view_filtered_rows_context_' + supportedNode,
+ node: supportedNode,
+ module: this,
+ data: {
+ mnuid: 4,
+ },
+ applies: ['context', 'object'],
+ callback: 'showFilteredRow',
+ enable: self.viewMenuEnabled,
+ category: 'view_data',
+ priority: 104,
+ label: gettext('Filtered Rows...'),
+ });
+ }
+
+ pgBrowser.add_menu_category('view_data', gettext('View/Edit Data'), 100, '');
+ pgBrowser.add_menus(menus);
+
+ // Creating a new pgAdmin.Browser frame to show the data.
+ var frame = new pgAdmin.Browser.Frame({
+ name: 'frm_sqleditor',
+ showTitle: true,
+ isCloseable: true,
+ isRenamable: true,
+ isPrivate: true,
+ url: 'about:blank',
+ });
+
+ // Load the newly created frame
+ frame.load(pgBrowser.docker);
+ }
+
+ // This is a callback function to show data when user click on menu item.
+ showViewData(data, i) {
+ const transId = commonUtils.getRandomInt(1, 9999999);
+ showViewData.showViewData(this, pgBrowser, alertify, data, i, transId);
+ }
+
+ // This is a callback function to show filtered data when user click on menu item.
+ showFilteredRow(data, i) {
+ const transId = commonUtils.getRandomInt(1, 9999999);
+ showViewData.showViewData(this, pgBrowser, alertify, data, i, transId, true, this.preferences);
+ }
+
+ // This is a callback function to show query tool when user click on menu item.
+ showQueryTool(url, treeIdentifier) {
+ const transId = commonUtils.getRandomInt(1, 9999999);
+ var t = pgBrowser.tree,
+ i = treeIdentifier || t.selected(),
+ d = i ? t.itemData(i) : undefined;
+
+ //Open query tool with create script if copy_sql_to_query_tool is true else open blank query tool
+ var preference = pgBrowser.get_preference('sqleditor', 'copy_sql_to_query_tool');
+ if(preference.value && !d._type.includes('coll-') && (url === '' || url['applies'] === 'tools')){
+ var stype = d._type.toLowerCase();
+ var data = {
+ 'script': stype,
+ data_disabled: gettext('The selected tree node does not support this option.'),
+ };
+ pgBrowser.Node.callbacks.show_script(data);
+ } else {
+ if(d._type.includes('coll-')){
+ url = '';
+ }
+ showQueryTool.showQueryTool(this, pgBrowser, url, treeIdentifier, transId);
+ }
+ }
+
+ onPanelRename(queryToolPanel, panelData, is_query_tool) {
+ var temp_title = panelData.$titleText[0].textContent;
+ var is_dirty_editor = queryToolPanel.is_dirty_editor ? queryToolPanel.is_dirty_editor : false;
+ var title = queryToolPanel.is_dirty_editor ? panelData.$titleText[0].textContent.replace(/.$/, '') : temp_title;
+ alertify.prompt('', title,
+ // We will execute this function when user clicks on the OK button
+ function(evt, value) {
+ // Remove the leading and trailing white spaces.
+ value = value.trim();
+ if(value) {
+ var is_file = false;
+ if(panelData.$titleText[0].innerHTML.includes('File - ')) {
+ is_file = true;
+ }
+ var selected_item = pgBrowser.tree.selected();
+ var panel_titles = '';
+
+ if(is_query_tool) {
+ panel_titles = panelTitleFunc.getPanelTitle(pgBrowser, selected_item, value);
+ } else {
+ panel_titles = showViewData.generateDatagridTitle(pgBrowser, selected_item, value);
+ }
+ // Set title to the selected tab.
+ if (is_dirty_editor) {
+ panel_titles = panel_titles + ' *';
+ }
+ panelTitleFunc.setQueryToolDockerTitle(queryToolPanel, is_query_tool, _.unescape(panel_titles), is_file);
+ }
+ },
+ // We will execute this function when user clicks on the Cancel
+ // button. Do nothing just close it.
+ function(evt) { evt.cancel = false; }
+ ).set({'title': gettext('Rename Panel')});
+ }
+
+
+ openQueryToolPanel(trans_id, is_query_tool, panel_title, closeUrl, queryToolForm) {
+ let self = this;
+ var browser_preferences = pgBrowser.get_preferences_for_module('browser');
+ var propertiesPanel = pgBrowser.docker.findPanels('properties');
+ var queryToolPanel = pgBrowser.docker.addPanel('frm_sqleditor', wcDocker.DOCK.STACKED, propertiesPanel[0]);
+ queryToolPanel.trans_id = trans_id;
+ showQueryTool._set_dynamic_tab(pgBrowser, browser_preferences['dynamic_tabs']);
+
+ // Set panel title and icon
+ panelTitleFunc.setQueryToolDockerTitle(queryToolPanel, is_query_tool, _.unescape(panel_title));
+ queryToolPanel.focus();
+
+ // Listen on the panel closed event.
+ if (queryToolPanel.isVisible()) {
+ queryToolPanel.on(wcDocker.EVENT.CLOSED, function() {
+ $.ajax({
+ url: closeUrl,
+ method: 'DELETE',
+ });
+ });
+ }
+
+ queryToolPanel.on(wcDocker.EVENT.VISIBILITY_CHANGED, function() {
+ queryToolPanel.trigger(wcDocker.EVENT.RESIZED);
+ });
+
+ commonUtils.registerDetachEvent(queryToolPanel);
+
+ // Listen on the panelRename event.
+ queryToolPanel.on(wcDocker.EVENT.RENAME, function(panelData) {
+ self.onPanelRename(queryToolPanel, panelData, is_query_tool);
+ });
+
+ var openQueryToolURL = function(j) {
+ // add spinner element
+ let $spinner_el =
+ $(``).appendTo($(j).data('embeddedFrame').$container);
+
+ let init_poller_id = setInterval(function() {
+ var frameInitialized = $(j).data('frameInitialized');
+ if (frameInitialized) {
+ clearInterval(init_poller_id);
+ var frame = $(j).data('embeddedFrame');
+ if (frame) {
+ frame.onLoaded(()=>{
+ $spinner_el.remove();
+ });
+ frame.openHTML(queryToolForm);
+ }
+ }
+ }, 100);
+ };
+
+ openQueryToolURL(queryToolPanel);
+ }
+
+ launch(trans_id, panel_url, is_query_tool, panel_title, sURL=null, sql_filter=null) {
+ const self = this;
+ let closeUrl = url_for('sqleditor.close', {'trans_id': trans_id});
+ let queryToolForm = `
+
+
+
+ `;
+
+
+ if(sURL){
+ queryToolForm +=` `;
+ }
+ if(sql_filter) {
+ queryToolForm +=`${sql_filter} `;
+ }
+
+ /* Escape backslashes as it is stripped by back end */
+ queryToolForm +=`
+
+
+ `;
+
+ var browser_preferences = pgBrowser.get_preferences_for_module('browser');
+ var open_new_tab = browser_preferences.new_browser_tab_open;
+ if (open_new_tab && open_new_tab.includes('qt')) {
+ var newWin = window.open('', '_blank');
+ if(newWin) {
+ newWin.document.write(queryToolForm);
+ newWin.document.title = panel_title;
+ // Send the signal to runtime, so that proper zoom level will be set.
+ setTimeout(function() {
+ pgBrowser.send_signal_to_runtime('Runtime new window opened');
+ }, 500);
+ } else {
+ return false;
+ }
+ } else {
+ /* On successfully initialization find the dashboard panel,
+ * create new panel and add it to the dashboard panel.
+ */
+ self.openQueryToolPanel(trans_id, is_query_tool, panel_title, closeUrl, queryToolForm);
+ }
+ return true;
+ }
+
+ setupPreferencesWorker() {
+ if (window.location == window.parent?.location) {
+ /* Sync the local preferences with the main window if in new tab */
+ setInterval(()=>{
+ if(pgWindow?.pgAdmin) {
+ if(pgAdmin.Browser.preference_version() < pgWindow.pgAdmin.Browser.preference_version()){
+ pgAdmin.Browser.preferences_cache = pgWindow.pgAdmin.Browser.preferences_cache;
+ pgAdmin.Browser.preference_version(pgWindow.pgAdmin.Browser.preference_version());
+ pgAdmin.Browser.triggerPreferencesChange('browser');
+ pgAdmin.Browser.triggerPreferencesChange('sqleditor');
+ }
+ }
+ }, 1000);
+ }
+ }
+
+ loadComponent(container, params) {
+ let panel = null;
+ let selectedNodeInfo = pgWindow.pgAdmin.Browser.tree.getTreeNodeHierarchy(
+ pgWindow.pgAdmin.Browser.tree.selected()
+ );
+ _.each(pgWindow.pgAdmin.Browser.docker.findPanels('frm_sqleditor'), function(p) {
+ if (p.trans_id == params.trans_id) {
+ panel = p;
+ }
+ });
+ this.setupPreferencesWorker();
+ ReactDOM.render(
+
+
+ ,
+ container
+ );
+ }
+}
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/QueryToolComponent.jsx b/web/pgadmin/tools/sqleditor/static/js/components/QueryToolComponent.jsx
new file mode 100644
index 000000000..6d2af6045
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/static/js/components/QueryToolComponent.jsx
@@ -0,0 +1,646 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import React, {useCallback, useRef, useMemo, useState, useEffect} from 'react';
+import _ from 'lodash';
+import Layout, { LayoutHelper } from '../../../../../static/js/helpers/Layout';
+import EventBus from '../../../../../static/js/helpers/EventBus';
+import Query from './sections/Query';
+import { ConnectionBar } from './sections/ConnectionBar';
+import { ResultSet } from './sections/ResultSet';
+import { StatusBar } from './sections/StatusBar';
+import { MainToolBar } from './sections/MainToolBar';
+import { Messages } from './sections/Messages';
+import Theme from 'sources/Theme';
+import getApiInstance, {parseApiError} from '../../../../../static/js/api_instance';
+import url_for from 'sources/url_for';
+import { PANELS, QUERY_TOOL_EVENTS, CONNECTION_STATUS } from './QueryToolConstants';
+import { useInterval } from '../../../../../static/js/custom_hooks';
+import { Box } from '@material-ui/core';
+import { getDatabaseLabel, getTitle, setQueryToolDockerTitle } from '../sqleditor_title';
+import gettext from 'sources/gettext';
+import NewConnectionDialog from './dialogs/NewConnectionDialog';
+import { evalFunc } from '../../../../../static/js/utils';
+import { Notifications } from './sections/Notifications';
+import MacrosDialog from './dialogs/MacrosDialog';
+import Notifier from '../../../../../static/js/helpers/Notifier';
+import FilterDialog from './dialogs/FilterDialog';
+import { QueryHistory } from './sections/QueryHistory';
+import * as showQueryTool from '../show_query_tool';
+import * as commonUtils from 'sources/utils';
+import * as Kerberos from 'pgadmin.authenticate.kerberos';
+import PropTypes from 'prop-types';
+import { retrieveNodeName } from '../show_view_data';
+import 'wcdocker';
+import { useModal } from '../../../../../static/js/helpers/ModalProvider';
+
+export const QueryToolContext = React.createContext();
+export const QueryToolConnectionContext = React.createContext();
+export const QueryToolEventsContext = React.createContext();
+
+function fetchConnectionStatus(api, transId) {
+ return api.get(url_for('sqleditor.connection_status', {trans_id: transId}));
+}
+
+function initConnection(api, params, passdata) {
+ return api.post(url_for('NODE-server.connect_id', params), passdata);
+}
+
+function setPanelTitle(panel, title, qtState, dirty=false) {
+ if(title) {
+ title =title.split('\\').pop().split('/').pop();
+ } else if(qtState.current_file) {
+ title = qtState.current_file.split('\\').pop().split('/').pop();
+ } else {
+ title = qtState.params.title || 'Untitled';
+ }
+
+ title = title + (dirty ? '*': '');
+ if (qtState.is_new_tab) {
+ window.document.title = title;
+ } else {
+ setQueryToolDockerTitle(panel, true, title, qtState.current_file ? true : false);
+ }
+}
+export default function QueryToolComponent({params, pgWindow, pgAdmin, selectedNodeInfo, panel, eventBusObj}) {
+ const containerRef = React.useRef(null);
+ const forceClose = React.useRef(false);
+ const [qtState, _setQtState] = useState({
+ preferences: {
+ browser: {}, sqleditor: {},
+ },
+ is_new_tab: window.location == window.parent?.location,
+ current_file: null,
+ obtaining_conn: true,
+ connected: false,
+ connection_status: null,
+ connection_status_msg: '',
+ params: {
+ ...params,
+ is_query_tool: params.is_query_tool == 'true' ? true : false,
+ node_name: retrieveNodeName(selectedNodeInfo),
+ },
+ connection_list: [{
+ sgid: params.sgid,
+ sid: params.sid,
+ did: params.did,
+ user: params.username,
+ role: null,
+ title: _.unescape(params.title),
+ conn_title: getTitle(
+ pgAdmin, null, selectedNodeInfo, true, params.server_name, params.database_name || getDatabaseLabel(selectedNodeInfo),
+ params.username, params.is_query_tool == 'true' ? true : false),
+ server_name: params.server_name,
+ database_name: params.database_name || getDatabaseLabel(selectedNodeInfo),
+ is_selected: true,
+ }],
+ });
+
+ const setQtState = (state)=>{
+ _setQtState((prev)=>({...prev,...evalFunc(null, state, prev)}));
+ };
+ const eventBus = useRef(eventBusObj || (new EventBus()));
+ const docker = useRef(null);
+ const api = useMemo(()=>getApiInstance(), []);
+ const modal = useModal();
+
+ /* Connection status poller */
+ let pollTime = qtState.preferences.sqleditor.connection_status_fetch_time > 0 ?
+ qtState.preferences.sqleditor.connection_status_fetch_time*1000 : -1;
+ /* No need to poll when the query is executing. Query poller will the txn status */
+ if(qtState.connection_status === CONNECTION_STATUS.TRANSACTION_STATUS_ACTIVE && qtState.connected) {
+ pollTime = -1;
+ }
+ useInterval(async ()=>{
+ try {
+ let {data: respData} = await fetchConnectionStatus(api, qtState.params.trans_id);
+ if(respData.data) {
+ setQtState({
+ connected: true,
+ connection_status: respData.data.status,
+ });
+ } else {
+ setQtState({
+ connected: false,
+ connection_status: null,
+ connection_status_msg: gettext('An unexpected error occurred - ensure you are logged into the application.')
+ });
+ }
+ if(respData.data.notifies) {
+ eventBus.current.fireEvent(QUERY_TOOL_EVENTS.PUSH_NOTICE, respData.data.notifies);
+ }
+ } catch (error) {
+ console.error(error);
+ setQtState({
+ connected: false,
+ connection_status: null,
+ connection_status_msg: parseApiError(error),
+ });
+ }
+ }, pollTime);
+
+ let defaultLayout = {
+ dockbox: {
+ mode: 'vertical',
+ children: [
+ {
+ mode: 'horizontal',
+ children: [
+ {
+ tabs: [
+ LayoutHelper.getPanel({id: PANELS.QUERY, title: gettext('Query'), content: }),
+ LayoutHelper.getPanel({id: PANELS.HISTORY, title: 'Query History', content: ,
+ cached: undefined}),
+ ],
+ },
+ {
+ size: 75,
+ tabs: [
+ LayoutHelper.getPanel({
+ id: PANELS.SCRATCH, title: gettext('Scratch Pad'),
+ closable: true,
+ content:
+ }),
+ ]
+ }
+ ]
+ },
+ {
+ mode: 'horizontal',
+ children: [
+ {
+ tabs: [
+ LayoutHelper.getPanel({
+ id: PANELS.DATA_OUTPUT, title: 'Data output', content: ,
+ }),
+ LayoutHelper.getPanel({
+ id: PANELS.MESSAGES, title:'Messages', content: ,
+ }),
+ LayoutHelper.getPanel({
+ id: PANELS.NOTIFICATIONS, title:'Notifications', content: ,
+ }),
+ ],
+ }
+ ]
+ },
+ ]
+ },
+ };
+
+ const reflectPreferences = useCallback(()=>{
+ setQtState({preferences: {
+ browser: pgWindow.pgAdmin.Browser.get_preferences_for_module('browser'),
+ sqleditor: pgWindow.pgAdmin.Browser.get_preferences_for_module('sqleditor'),
+ }});
+ }, []);
+
+ const getSQLScript = ()=>{
+ // Fetch the SQL for Scripts (eg: CREATE/UPDATE/DELETE/SELECT)
+ // Call AJAX only if script type url is present
+ if(qtState.params.is_query_tool && qtState.params.query_url) {
+ api.get(qtState.params.query_url)
+ .then((res)=>{
+ eventBus.current.fireEvent(QUERY_TOOL_EVENTS.EDITOR_SET_SQL, res.data);
+ })
+ .catch((err)=>{
+ eventBus.current.fireEvent(QUERY_TOOL_EVENTS.HANDLE_API_ERROR, err);
+ });
+ } else if(qtState.params.sql_id) {
+ let sqlValue = localStorage.getItem(qtState.params.sql_id);
+ localStorage.removeItem(qtState.params.sql_id);
+ if(sqlValue) {
+ eventBus.current.fireEvent(QUERY_TOOL_EVENTS.EDITOR_SET_SQL, sqlValue);
+ }
+ }
+ };
+
+ const initializeQueryTool = ()=>{
+ let selectedConn = _.find(qtState.connection_list, (c)=>c.is_selected);
+ let baseUrl = '';
+ if(qtState.params.is_query_tool) {
+ let endpoint = 'sqleditor.initialize_sqleditor';
+
+ if(qtState.params.did) {
+ endpoint = 'sqleditor.initialize_sqleditor_with_did';
+ }
+ baseUrl = url_for(endpoint, {
+ ...selectedConn,
+ trans_id: qtState.params.trans_id,
+ });
+ } else {
+ baseUrl = url_for('sqleditor.initialize_viewdata', {
+ ...qtState.params,
+ });
+ }
+ api.post(baseUrl, qtState.params.is_query_tool ? null : JSON.stringify(qtState.params.sql_filter))
+ .then(()=>{
+ setQtState({
+ connected: true,
+ obtaining_conn: false,
+ });
+
+ if(!qtState.params.is_query_tool) {
+ eventBus.current.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_EXECUTION);
+ }
+ }).catch((err)=>{
+ if(err.response?.request?.responseText?.search('Ticket expired') !== -1) {
+ Kerberos.fetch_ticket()
+ .then(()=>{
+ initializeQueryTool();
+ })
+ .catch((kberr)=>{
+ setQtState({
+ connected: false,
+ obtaining_conn: false,
+ });
+ eventBus.current.fireEvent(QUERY_TOOL_EVENTS.HANDLE_API_ERROR, kberr);
+ });
+ }
+ setQtState({
+ connected: false,
+ obtaining_conn: false,
+ });
+ eventBus.current.fireEvent(QUERY_TOOL_EVENTS.HANDLE_API_ERROR, err);
+ });
+ };
+
+ useEffect(()=>{
+ getSQLScript();
+ initializeQueryTool();
+
+ eventBus.current.registerListener(QUERY_TOOL_EVENTS.FOCUS_PANEL, (panelId)=>{
+ LayoutHelper.focus(docker.current, panelId);
+ });
+
+ eventBus.current.registerListener(QUERY_TOOL_EVENTS.SET_CONNECTION_STATUS, (status)=>{
+ setQtState({connection_status: status});
+ });
+
+ eventBus.current.registerListener(QUERY_TOOL_EVENTS.FORCE_CLOSE_PANEL, ()=>{
+ panel.off(window.wcDocker.EVENT.CLOSING);
+ panel.close();
+ });
+
+ reflectPreferences();
+ pgWindow.pgAdmin.Browser.onPreferencesChange('sqleditor', function() {
+ reflectPreferences();
+ });
+
+ /* WC docker events */
+ panel?.on(window.wcDocker.EVENT.CLOSING, function() {
+ if(!forceClose.current) {
+ eventBus.current.fireEvent(QUERY_TOOL_EVENTS.WARN_SAVE_DATA_CLOSE);
+ } else {
+ panel.close();
+ }
+ });
+
+ pgAdmin.Browser.Events.on('pgadmin-storage:finish_btn:select_file', (fileName)=>{
+ eventBus.current.fireEvent(QUERY_TOOL_EVENTS.LOAD_FILE, fileName);
+ }, pgAdmin);
+
+ pgAdmin.Browser.Events.on('pgadmin-storage:finish_btn:create_file', (fileName)=>{
+ eventBus.current.fireEvent(QUERY_TOOL_EVENTS.SAVE_FILE, fileName);
+ }, pgAdmin);
+ }, []);
+
+ useEffect(()=>{
+ const pushHistory = (h)=>{
+ api.post(
+ url_for('sqleditor.add_query_history', {
+ 'trans_id': qtState.params.trans_id,
+ }),
+ JSON.stringify(h),
+ ).catch((error)=>{console.error(error);});
+ };
+ eventBus.current.registerListener(QUERY_TOOL_EVENTS.PUSH_HISTORY, pushHistory);
+ return ()=>{eventBus.current.deregisterListener(QUERY_TOOL_EVENTS.PUSH_HISTORY, pushHistory);};
+ }, [qtState.params.trans_id]);
+
+
+ const handleApiError = (error, handleParams)=>{
+ if(error.response && pgAdmin.Browser?.UserManagement?.isPgaLoginRequired(error.response)) {
+ return pgAdmin.Browser.UserManagement.pgaLogin();
+ }
+
+ if(error.response?.status == 503 && error.response.data?.info == 'CONNECTION_LOST') {
+ // We will display re-connect dialog, no need to display error message again
+ modal.confirm(
+ gettext('Connection Warning'),
+
+ {gettext('The application has lost the database connection:')}
+ {gettext('⁃ If the connection was idle it may have been forcibly disconnected.')}
+ {gettext('⁃ The application server or database server may have been restarted.')}
+ {gettext('⁃ The user session may have timed out.')}
+
+ {gettext('Do you want to continue and establish a new session')}
+
,
+ function() {
+ handleParams?.connectionLostCallback?.();
+ }, null,
+ gettext('Continue'),
+ gettext('Cancel')
+ );
+ } else if(handleParams?.checkTransaction && error.response?.data.info == 'DATAGRID_TRANSACTION_REQUIRED') {
+ let selectedConn = _.find(qtState.connection_list, (c)=>c.is_selected);
+ initConnection(api, {
+ 'gid': selectedConn.sgid,
+ 'sid': selectedConn.sid,
+ 'did': selectedConn.did,
+ 'role': selectedConn.role,
+ }).then(()=>{
+ initializeQueryTool();
+ }).catch((err)=>{
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.HANDLE_API_ERROR, err);
+ });
+ } else {
+ let msg = parseApiError(error);
+ eventBus.current.fireEvent(QUERY_TOOL_EVENTS.SET_MESSAGE, msg, true);
+ eventBus.current.fireEvent(QUERY_TOOL_EVENTS.FOCUS_PANEL, PANELS.MESSAGES);
+ Notifier.error(msg);
+ }
+ };
+
+ useEffect(()=>{
+ const fileDone = (fileName, success=true)=>{
+ if(success) {
+ setQtState({
+ current_file: fileName,
+ });
+ setPanelTitle(panel, fileName, {...qtState, current_file: fileName});
+ }
+ };
+ const events = [
+ [QUERY_TOOL_EVENTS.TRIGGER_LOAD_FILE, ()=>{
+ let fileParams = {
+ 'supported_types': ['*', 'sql'], // file types allowed
+ 'dialog_type': 'select_file', // open select file dialog
+ };
+ pgAdmin.FileManager.init();
+ pgAdmin.FileManager.show_dialog(fileParams);
+ }],
+ [QUERY_TOOL_EVENTS.TRIGGER_SAVE_FILE, (isSaveAs=false)=>{
+ if(!isSaveAs && qtState.current_file) {
+ eventBus.current.fireEvent(QUERY_TOOL_EVENTS.SAVE_FILE, qtState.current_file);
+ } else {
+ let fileParams = {
+ 'supported_types': ['*', 'sql'],
+ 'dialog_type': 'create_file',
+ 'dialog_title': 'Save File',
+ 'btn_primary': 'Save',
+ };
+ pgAdmin.FileManager.init();
+ pgAdmin.FileManager.show_dialog(fileParams);
+ }
+ }],
+ [QUERY_TOOL_EVENTS.LOAD_FILE_DONE, fileDone],
+ [QUERY_TOOL_EVENTS.SAVE_FILE_DONE, fileDone],
+ [QUERY_TOOL_EVENTS.QUERY_CHANGED, (isDirty)=>{
+ if(qtState.params.is_query_tool) {
+ setPanelTitle(panel, null, qtState, isDirty);
+ }
+ }],
+ [QUERY_TOOL_EVENTS.HANDLE_API_ERROR, handleApiError],
+ ];
+
+ events.forEach((e)=>{
+ eventBus.current.registerListener(e[0], e[1]);
+ });
+
+ return ()=>{
+ events.forEach((e)=>{
+ eventBus.current.deregisterListener(e[0], e[1]);
+ });
+ };
+ }, [qtState]);
+
+ useEffect(()=>{
+ /* Fire query change so that title changes to latest */
+ eventBus.current.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_QUERY_CHANGE);
+ }, [qtState.params.title]);
+
+ const updateQueryToolConnection = useCallback((connectionData, isNew=false)=>{
+ setQtState((prev)=>{
+ let newConnList = [...prev.connection_list];
+ if(isNew) {
+ newConnList.push(connectionData);
+ }
+ for (const connItem of newConnList) {
+ if(connectionData.sid == connItem.sid
+ && connectionData.did == connItem.did
+ && connectionData.user == connItem.user
+ && connectionData.role == connItem.role) {
+ connItem.is_selected = true;
+ } else {
+ connItem.is_selected = false;
+ }
+ }
+ return {
+ connection_list: newConnList,
+ };
+ });
+ setQtState((prev)=>{
+ return {
+ params: {
+ ...prev.params,
+ sid: connectionData.sid,
+ did: connectionData.did,
+ title: connectionData.title,
+ },
+ obtaining_conn: true,
+ connected: false,
+ };
+ });
+ return api.post(url_for('sqleditor.update_sqleditor_connection', {
+ trans_id: qtState.params.trans_id,
+ sgid: connectionData.sgid,
+ sid: connectionData.sid,
+ did: connectionData.did
+ }), connectionData)
+ .then(({data: respData})=>{
+ setQtState((prev)=>{
+ return {
+ params: {
+ ...prev.params,
+ trans_id: respData.data.trans_id,
+ },
+ connected: respData.data.trans_id ? true : false,
+ obtaining_conn: false,
+ };
+ });
+ let msg = `${connectionData['server_name']}/${connectionData['database_name']} - Database connected`;
+ Notifier.success(msg);
+ });
+ }, [qtState.params.trans_id]);
+
+ const onNewConnClick = useCallback(()=>{
+ const onClose = ()=>LayoutHelper.close(docker.current, 'new-conn');
+ LayoutHelper.openDialog(docker.current, {
+ id: 'new-conn',
+ title: gettext('Add new connection'),
+ content: {
+ let connectionData = {
+ sgid: 0,
+ sid: data.sid,
+ did: data.did,
+ user: data.user,
+ role: data.role && null,
+ title: getTitle(pgAdmin, qtState.preferences.browser, null, false, data.server_name, data.database_name, data.user, true),
+ conn_title: getTitle(pgAdmin, null, null, true, data.server_name, data.database_name, data.user, true),
+ server_name: data.server_name,
+ database_name: data.database_name,
+ is_selected: true,
+ };
+ updateQueryToolConnection(connectionData, true);
+ onClose();
+ return Promise.resolve();
+ }}
+ onClose={onClose}/>
+ });
+ }, [qtState.preferences.browser]);
+
+
+ const onNewQueryToolClick = ()=>{
+ const transId = commonUtils.getRandomInt(1, 9999999);
+ let selectedConn = _.find(qtState.connection_list, (c)=>c.is_selected);
+ let parentData = {
+ server_group: {
+ _id: selectedConn.sgid || 0,
+ },
+ server: {
+ _id: selectedConn.sid,
+ server_type: qtState.params.server_type,
+ },
+ database: {
+ _id: selectedConn.did,
+ label: selectedConn.database_name,
+ },
+ };
+
+ const gridUrl = showQueryTool.generateUrl(transId, parentData, null);
+ const title = getTitle(pgAdmin, qtState.preferences.browser, null, false, selectedConn.server_name, selectedConn.database_name, selectedConn.user);
+ showQueryTool.launchQueryTool(pgWindow.pgAdmin.Tools.SQLEditor, transId, gridUrl, title, '');
+ };
+
+ const onManageMacros = useCallback(()=>{
+ const onClose = ()=>LayoutHelper.close(docker.current, 'manage-macros');
+ LayoutHelper.openDialog(docker.current, {
+ id: 'manage-macros',
+ title: gettext('Manage Macros'),
+ content: {
+ setQtState((prev)=>{
+ return {
+ params: {
+ ...prev.params,
+ macros: newMacros,
+ },
+ };
+ });
+ }}
+ onClose={onClose}/>
+ }, 850, 500);
+ }, [qtState.preferences.browser]);
+
+ const onFilterClick = useCallback(()=>{
+ const onClose = ()=>LayoutHelper.close(docker.current, 'filter-dialog');
+ LayoutHelper.openDialog(docker.current, {
+ id: 'filter-dialog',
+ title: gettext('Sort/Filter options'),
+ content: {
+ onClose();
+ eventBus.current.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_EXECUTION);
+ }}
+ onClose={onClose}/>
+ }, 700, 400);
+ }, [qtState.preferences.browser]);
+
+ const onResetLayout = useCallback(()=>{
+ docker.current?.resetLayout();
+ eventBus.current.fireEvent(QUERY_TOOL_EVENTS.FOCUS_PANEL, PANELS.QUERY);
+ }, []);
+
+ const queryToolContextValue = React.useMemo(()=>({
+ docker: docker.current,
+ api: api,
+ modal: modal,
+ params: qtState.params,
+ preferences: qtState.preferences,
+ }), [qtState.params, qtState.preferences]);
+
+ const queryToolConnContextValue = React.useMemo(()=>({
+ connected: qtState.connected,
+ obtainingConn: qtState.obtaining_conn,
+ connectionStatus: qtState.connection_status,
+ }), [qtState]);
+
+ /* Push only those things in context which do not change frequently */
+ return (
+
+
+
+
+
+ updateQueryToolConnection(connectionData)}
+ onNewConnClick={onNewConnClick}
+ onNewQueryToolClick={onNewQueryToolClick}
+ onResetLayout={onResetLayout}
+ docker={docker.current}
+ />
+
+ docker.current=obj}
+ defaultLayout={defaultLayout}
+ layoutId="SQLEditor/Layout"
+ savedLayout={params.layout}
+ />
+
+
+
+
+
+
+ );
+}
+
+QueryToolComponent.propTypes = {
+ params:PropTypes.shape({
+ trans_id: PropTypes.number.isRequired,
+ sgid: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
+ sid: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
+ did: PropTypes.oneOfType([PropTypes.number, PropTypes.string]).isRequired,
+ server_type: PropTypes.string,
+ title: PropTypes.string.isRequired,
+ bgcolor: PropTypes.string,
+ fgcolor: PropTypes.string,
+ is_query_tool: PropTypes.oneOfType([PropTypes.bool, PropTypes.string]).isRequired,
+ username: PropTypes.string,
+ server_name: PropTypes.string,
+ database_name: PropTypes.string,
+ layout: PropTypes.string,
+ }),
+ pgWindow: PropTypes.object.isRequired,
+ pgAdmin: PropTypes.object.isRequired,
+ selectedNodeInfo: PropTypes.object,
+ panel: PropTypes.object,
+ eventBusObj: PropTypes.objectOf(EventBus),
+};
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/QueryToolConstants.js b/web/pgadmin/tools/sqleditor/static/js/components/QueryToolConstants.js
new file mode 100644
index 000000000..a6635dc2d
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/static/js/components/QueryToolConstants.js
@@ -0,0 +1,97 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import gettext from 'sources/gettext';
+
+export const QUERY_TOOL_EVENTS = {
+ TRIGGER_STOP_EXECUTION: 'TRIGGER_STOP_EXECUTION',
+ TRIGGER_EXECUTION: 'TRIGGER_EXECUTION',
+ TRIGGER_LOAD_FILE: 'TRIGGER_LOAD_FILE',
+ TRIGGER_SAVE_FILE: 'TRIGGER_SAVE_FILE',
+ TRIGGER_SAVE_DATA: 'TRIGGER_SAVE_DATA',
+ TRIGGER_DELETE_ROWS: 'TRIGGER_DELETE_ROWS',
+ TRIGGER_COPY_DATA: 'TRIGGER_COPY_DATA',
+ TRIGGER_ADD_ROWS: 'TRIGGER_ADD_ROWS',
+ TRIGGER_RENDER_GEOMETRIES: 'TRIGGER_RENDER_GEOMETRIES',
+ TRIGGER_SAVE_RESULTS: 'TRIGGER_SAVE_RESULTS',
+ TRIGGER_SAVE_RESULTS_END: 'TRIGGER_SAVE_RESULTS_END',
+ TRIGGER_PASTE_ROWS: 'TRIGGER_PASTE_ROWS',
+ TRIGGER_QUERY_CHANGE: 'TRIGGER_QUERY_CHANGE',
+ TRIGGER_INCLUDE_EXCLUDE_FILTER: 'TRIGGER_INCLUDE_EXCLUDE_FILTER',
+ TRIGGER_REMOVE_FILTER: 'TRIGGER_REMOVE_FILTER',
+ TRIGGER_SET_LIMIT: 'TRIGGER_SET_LIMIT',
+ TRIGGER_FORMAT_SQL: 'TRIGGER_FORMAT_SQL',
+
+ COPY_DATA: 'COPY_DATA',
+ SET_LIMIT_VALUE: 'SET_LIMIT_VALUE',
+ SET_CONNECTION_STATUS: 'SET_CONNECTION_STATUS',
+ EXECUTION_START: 'EXECUTION_START',
+ EXECUTION_END: 'EXECUTION_END',
+ STOP_QUERY: 'STOP_QUERY',
+ CURSOR_ACTIVITY: 'CURSOR_ACTIVITY',
+ SET_MESSAGE: 'SET_MESSAGE',
+ ROWS_FETCHED: 'ROWS_FETCHED',
+ SELECTED_ROWS_COLS_CHANGED: 'SELECTED_ROWS_COLS_CHANGED',
+ DATAGRID_CHANGED: 'DATAGRID_CHANGED',
+ HIGHLIGHT_ERROR: 'HIGHLIGHT_ERROR',
+ FOCUS_PANEL: 'FOCUS_PANEL',
+ LOAD_FILE: 'LOAD_FILE',
+ LOAD_FILE_DONE: 'LOAD_FILE_DONE',
+ SAVE_FILE: 'SAVE_FILE',
+ SAVE_FILE_DONE: 'SAVE_FILE_DONE',
+ QUERY_CHANGED: 'QUERY_CHANGED',
+ API_ERROR: 'API_ERROR',
+ SAVE_DATA_DONE: 'SAVE_DATA_DONE',
+ TASK_START: 'TASK_START',
+ TASK_END: 'TASK_END',
+ RENDER_GEOMETRIES: 'RENDER_GEOMETRIES',
+ PUSH_NOTICE: 'PUSH_NOTICE',
+ PUSH_HISTORY: 'PUSH_HISTORY',
+ HANDLE_API_ERROR: 'HANDLE_API_ERROR',
+ SET_FILTER_INFO: 'SET_FILTER_INFO',
+ FETCH_MORE_ROWS: 'FETCH_MORE_ROWS',
+
+ EDITOR_FIND_REPLACE: 'EDITOR_FIND_REPLACE',
+ EDITOR_EXEC_CMD: 'EDITOR_EXEC_CMD',
+ EDITOR_SET_SQL: 'EDITOR_SET_SQL',
+ COPY_TO_EDITOR: 'COPY_TO_EDITOR',
+
+ WARN_SAVE_DATA_CLOSE: 'WARN_SAVE_DATA_CLOSE',
+ WARN_SAVE_TEXT_CLOSE: 'WARN_SAVE_TEXT_CLOSE',
+ WARN_TXN_CLOSE: 'WARN_TXN_CLOSE',
+
+ RESET_LAYOUT: 'RESET_LAYOUT',
+ FORCE_CLOSE_PANEL: 'FORCE_CLOSE_PANEL',
+};
+
+export const CONNECTION_STATUS = {
+ TRANSACTION_STATUS_IDLE: 0,
+ TRANSACTION_STATUS_ACTIVE: 1,
+ TRANSACTION_STATUS_INTRANS: 2,
+ TRANSACTION_STATUS_INERROR: 3,
+ TRANSACTION_STATUS_UNKNOWN: 4,
+};
+
+export const CONNECTION_STATUS_MESSAGE = {
+ [CONNECTION_STATUS.TRANSACTION_STATUS_IDLE]: gettext('The session is idle and there is no current transaction.'),
+ [CONNECTION_STATUS.TRANSACTION_STATUS_ACTIVE]: gettext('A command is currently in progress.'),
+ [CONNECTION_STATUS.TRANSACTION_STATUS_INTRANS]: gettext('The session is idle in a valid transaction block.'),
+ [CONNECTION_STATUS.TRANSACTION_STATUS_INERROR]: gettext('The session is idle in a failed transaction block.'),
+ [CONNECTION_STATUS.TRANSACTION_STATUS_UNKNOWN]: gettext('The connection with the server is bad.')
+};
+
+export const PANELS = {
+ QUERY: 'id-query',
+ MESSAGES: 'id-messages',
+ SCRATCH: 'id-scratch',
+ DATA_OUTPUT: 'id-dataoutput',
+ EXPLAIN: 'id-explain',
+ GEOMETRY: 'id-geometry',
+ NOTIFICATIONS: 'id-notifications',
+ HISTORY: 'id-history',
+};
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/CopyData.js b/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/CopyData.js
new file mode 100644
index 000000000..b434c81e2
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/CopyData.js
@@ -0,0 +1,99 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import JSONBigNumber from 'json-bignumber';
+import _ from 'lodash';
+import * as clipboard from '../../../../../../static/js/clipboard';
+import { CSVToArray } from '../../../../../../static/js/utils';
+
+export default class CopyData {
+ constructor(options) {
+ this.CSVOptions = {
+ field_separator: '\t',
+ quote_char: '"',
+ quoting: 'strings',
+ ...options,
+ };
+ }
+
+ setCSVOptions(options) {
+ this.CSVOptions = {
+ ...this.CSVOptions,
+ ...options,
+ };
+ }
+
+ copyRowsToCsv(rows=[], columns=[], withHeaders=false) {
+ let csvRows = rows.reduce((prevCsvRows, currRow)=>{
+ let csvRow = columns.reduce((prevCsvCols, column)=>{
+ prevCsvCols.push(this.csvCell(currRow[column.key], column));
+ return prevCsvCols;
+ }, []).join(this.CSVOptions.field_separator);
+ prevCsvRows.push(csvRow);
+ return prevCsvRows;
+ }, []);
+
+ if(withHeaders) {
+ let csvRow = columns.reduce((prevCsvCols, column)=>{
+ prevCsvCols.push(this.csvCell(column.name, column, true));
+ return prevCsvCols;
+ }, []).join(this.CSVOptions.field_separator);
+ csvRows.unshift(csvRow);
+ }
+ clipboard.copyToClipboard(csvRows.join('\n'));
+ localStorage.setItem('copied-with-headers', withHeaders);
+ }
+
+ escape(iStr) {
+ return (this.CSVOptions.quote_char == '"') ?
+ iStr.replace(/\"/g, '""') : iStr.replace(/\'/g, '\'\'');
+ }
+
+ allQuoteCell(value) {
+ if (value && _.isObject(value)) {
+ value = this.CSVOptions.quote_char + JSONBigNumber.stringify(value) + this.CSVOptions.quote_char;
+ } else if (value) {
+ value = this.CSVOptions.quote_char + this.escape(value.toString()) + this.CSVOptions.quote_char;
+ } else if (_.isNull(value) || _.isUndefined(value)) {
+ value = '';
+ }
+ return value;
+ }
+
+ stringQuoteCell(value, column) {
+ if (value && _.isObject(value)) {
+ value = this.CSVOptions.quote_char + JSONBigNumber.stringify(value) + this.CSVOptions.quote_char;
+ } else if (value && column.cell != 'number' && column.cell != 'boolean') {
+ value = this.CSVOptions.quote_char + this.escape(value.toString()) + this.CSVOptions.quote_char;
+ } else if (column.cell == 'string' && _.isNull(value)){
+ value = null;
+ } else if (_.isNull(value) || _.isUndefined(value)) {
+ value = '';
+ }
+ return value;
+ }
+
+ csvCell(value, column, header=false) {
+ if (this.CSVOptions.quoting == 'all' || header) {
+ value = this.allQuoteCell(value);
+ } else if(this.CSVOptions.quoting == 'strings') {
+ value = this.stringQuoteCell(value, column);
+ }
+ return value;
+ }
+
+ getCopiedRows() {
+ let copiedText = clipboard.getFromClipboard();
+ let copiedRows = CSVToArray(copiedText, this.CSVOptions.field_separator, this.CSVOptions.quote_char);
+
+ if(localStorage.getItem('copied-with-headers') == 'true') {
+ copiedRows = copiedRows.slice(1);
+ }
+ return copiedRows;
+ }
+}
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/Editors.jsx b/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/Editors.jsx
new file mode 100644
index 000000000..b48152b11
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/Editors.jsx
@@ -0,0 +1,345 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import { makeStyles, Box, Portal } from '@material-ui/core';
+import React, {useContext} from 'react';
+import { DefaultButton, PrimaryButton } from '../../../../../../static/js/components/Buttons';
+import CheckRoundedIcon from '@material-ui/icons/CheckRounded';
+import CloseIcon from '@material-ui/icons/Close';
+import gettext from 'sources/gettext';
+import clsx from 'clsx';
+import JSONBigNumber from 'json-bignumber';
+import JsonEditor from '../../../../../../static/js/components/JsonEditor';
+import PropTypes from 'prop-types';
+import { RowInfoContext } from '.';
+import Notifier from '../../../../../../static/js/helpers/Notifier';
+
+const useStyles = makeStyles((theme)=>({
+ textEditor: {
+ position: 'absolute',
+
+ zIndex: 1050,
+ backgroundColor: theme.palette.background.default,
+ padding: '0.25rem',
+ fontSize: '12px',
+ ...theme.mixins.panelBorder.all,
+ left: 0,
+ // bottom: 0,
+ top: 0,
+ '& textarea': {
+ width: '250px',
+ height: '80px',
+ border: 0,
+ outline: 0,
+ resize: 'both',
+ }
+ },
+ jsonEditor: {
+ position: 'absolute',
+ zIndex: 1050,
+ backgroundColor: theme.palette.background.default,
+ ...theme.mixins.panelBorder,
+ padding: '0.25rem',
+ '& .jsoneditor-div': {
+ fontSize: '12px',
+ minWidth: '525px',
+ minHeight: '300px',
+ ...theme.mixins.panelBorder.all,
+ outline: 0,
+ resize: 'both',
+ overflow: 'auto',
+ },
+ '& .jsoneditor': {
+ height: 'abc',
+ border: 'none',
+ '& .ace-jsoneditor .ace_marker-layer .ace_active-line': {
+ background: theme.palette.primary.light
+ }
+ }
+ },
+ buttonMargin: {
+ marginLeft: '0.5rem',
+ },
+ textarea: {
+ resize: 'both'
+ },
+ input: {
+ appearance: 'none',
+ width: '100%',
+ height: '100%',
+ verticalAlign: 'top',
+ outline: 'none',
+ backgroundColor: theme.palette.background.default,
+ color: theme.palette.text.primary,
+ border: 0,
+ boxShadow: 'inset 0 0 0 1.5px '+theme.palette.primary.main,
+ padding: '0 2px',
+ '::selection': {
+ background: theme.palette.primary.light,
+ }
+ },
+ check: {
+ display: 'inline-block',
+ verticalAlign: 'top',
+ width: '16px',
+ height: '16px',
+ border: '1px solid '+theme.palette.grey[800],
+ margin: '3px',
+ textAlign: 'center',
+ lineHeight: '16px',
+
+ '&.checked, &.unchecked': {
+ background: theme.palette.background.default,
+ },
+ '&.checked:after': {
+ content: '\'\\2713\'',
+ fontWeight: 'bold',
+ },
+ '&.intermediate': {
+ background: theme.palette.grey[200],
+ '&:after': {
+ content: '\'\\003F\'',
+ fontWeight: 'bold',
+ },
+ },
+ }
+}));
+
+function autoFocusAndSelect(input) {
+ input?.focus();
+ input?.select();
+}
+
+function isValidArray(val) {
+ val = val?.trim();
+ return !(val != '' && (val.charAt(0) != '{' || val.charAt(val.length - 1) != '}'));
+}
+
+function setEditorPosition(cellEle, editorEle) {
+ if(!editorEle || !cellEle) {
+ return;
+ }
+ let gridEle = cellEle.closest('.rdg');
+ let cellRect = cellEle.getBoundingClientRect();
+ let position = {
+ left: cellRect.left,
+ top: cellRect.top - editorEle.offsetHeight + 12,
+ };
+
+ if ((position.left + editorEle.offsetWidth + 10) > gridEle.offsetWidth) {
+ position.left -= position.left + editorEle.offsetWidth - gridEle.offsetWidth + 10;
+ }
+ editorEle.style.left = position.left + 'px';
+ editorEle.style.top = position.top + 'px';
+}
+
+const EditorPropTypes = {
+ row: PropTypes.object,
+ column: PropTypes.object,
+ onRowChange: PropTypes.func,
+ onClose: PropTypes.func
+};
+
+function textColumnFinalVal(columnVal, column) {
+ if(columnVal === '') {
+ columnVal = null;
+ } else if (!column.is_array) {
+ if (columnVal === '\'\'' || columnVal === '""') {
+ columnVal = '';
+ } else if (columnVal === '\\\'\\\'') {
+ columnVal = '\'\'';
+ } else if (columnVal === '\\"\\"') {
+ columnVal = '""';
+ }
+ }
+ return columnVal;
+}
+export function TextEditor({row, column, onRowChange, onClose}) {
+ const classes = useStyles();
+ const value = row[column.key] ?? '';
+ const [localVal, setLocalVal] = React.useState(value);
+ const {getCellElement} = useContext(RowInfoContext);
+
+ const onChange = React.useCallback((e)=>{
+ setLocalVal(e.target.value);
+ }, []);
+
+ const onOK = ()=>{
+ if(column.is_array && !isValidArray(value)) {
+ console.error(gettext('Arrays must start with "{" and end with "}"'));
+ } else {
+ let columnVal = textColumnFinalVal(localVal, column);
+ onRowChange({ ...row, [column.key]: columnVal}, true);
+ onClose();
+ }
+ };
+
+ return(
+
+ {
+ setEditorPosition(getCellElement(column.idx), ele);
+ }} className={classes.textEditor}>
+
+
+ } onClick={()=>onClose(false)} size="small">
+ {gettext('Cancel')}
+
+ {column.can_edit &&
+ <>
+ } onClick={onOK} size="small" className={classes.buttonMargin}>
+ {gettext('OK')}
+
+ >}
+
+
+
+ );
+}
+TextEditor.propTypes = EditorPropTypes;
+
+export function NumberEditor({row, column, onRowChange, onClose}) {
+ const classes = useStyles();
+ const value = row[column.key] ?? '';
+ const onBlur = ()=>{
+ if(!column.is_array && isNaN(value)){
+ Notifier.error(gettext('Please enter a valid number'));
+ return;
+ } else if(column.is_array) {
+ if(!isValidArray(value)) {
+ Notifier.error(gettext('Arrays must start with "{" and end with "}"'));
+ return;
+ }
+ let checkVal = value.trim().slice(1, -1);
+ if(checkVal == '') {
+ checkVal = [];
+ } else {
+ checkVal = checkVal.split(',');
+ }
+ for (const val of checkVal) {
+ if(isNaN(val)) {
+ Notifier.error(gettext('Arrays must start with "{" and end with "}"'));
+ return;
+ }
+ }
+ }
+ onClose(column.can_edit ? true : false);
+ };
+ const onKeyDown = (e)=>{
+ if(e.code == 'Tab') {
+ e.preventDefault();
+ onBlur();
+ }
+ };
+ return (
+ {
+ if(column.can_edit) {
+ onRowChange({ ...row, [column.key]: e.target.value });
+ }
+ }}
+ // onBlur={onBlur}
+ onKeyDown={onKeyDown}
+ />
+ );
+}
+NumberEditor.propTypes = EditorPropTypes;
+
+export function CheckboxEditor({row, column, onRowChange, onClose}) {
+ const classes = useStyles();
+ const value = row[column.key] ?? null;
+ const changeValue = ()=>{
+ if(!column.can_edit) {
+ return;
+ }
+ let newVal = true;
+ if(value) {
+ newVal = false;
+ } else if(value != null && !value) {
+ newVal = null;
+ }
+ onRowChange({ ...row, [column.key]: newVal});
+ };
+ const onBlur = ()=>{onClose(true);};
+ let className = 'checked';
+ if(!value) {
+ className = 'unchecked';
+ } else if(value == null){
+ className = 'intermediate';
+ }
+ return (
+
+
+
+ );
+}
+CheckboxEditor.propTypes = EditorPropTypes;
+
+export function JsonTextEditor({row, column, onRowChange, onClose}) {
+ const classes = useStyles();
+ const {getCellElement} = useContext(RowInfoContext);
+ const value = React.useMemo(()=>{
+ let newVal = row[column.key] ?? null;
+ /* If jsonb or array */
+ if(column.column_type_internal === 'jsonb' && !Array.isArray(newVal) && newVal != null) {
+ newVal = JSONBigNumber.stringify(JSONBigNumber.parse(newVal), null, 2);
+ } else if (Array.isArray(newVal)) {
+ var temp = newVal.map((ele)=>{
+ if (typeof ele === 'object') {
+ return JSONBigNumber.stringify(ele, null, 2);
+ }
+ return ele;
+ });
+ newVal = '[' + temp.join() + ']';
+ }
+ /* set editor content to empty if value is null*/
+ if (_.isNull(newVal)){
+ newVal = '';
+ }
+ return newVal;
+ });
+ const [localVal, setLocalVal] = React.useState(value);
+
+ const onChange = React.useCallback((newVal)=>{
+ setLocalVal(newVal);
+ }, []);
+ const onOK = ()=>{
+ onRowChange({ ...row, [column.key]: localVal}, true);
+ onClose();
+ };
+ return (
+
+ {
+ setEditorPosition(getCellElement(column.idx), ele);
+ }} className={classes.jsonEditor}>
+ console.error('Invalid Json: ' + error.message.split(':')[0]),
+ }}
+ className={'jsoneditor-div'}
+ />
+
+ } onClick={()=>onClose(false)} size="small">
+ {gettext('Cancel')}
+
+ {column.can_edit &&
+ <>
+ } onClick={onOK} size="small" className={classes.buttonMargin}>
+ {gettext('OK')}
+
+ >}
+
+
+
+ );
+}
+JsonTextEditor.propTypes = EditorPropTypes;
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/Formatters.jsx b/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/Formatters.jsx
new file mode 100644
index 000000000..682a2e0f8
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/Formatters.jsx
@@ -0,0 +1,73 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import React from 'react';
+import _ from 'lodash';
+import { makeStyles } from '@material-ui/core';
+import PropTypes from 'prop-types';
+import CustomPropTypes from '../../../../../../static/js/custom_prop_types';
+
+const useStyles = makeStyles((theme)=>({
+ disabledCell: {
+ opacity: theme.palette.action.disabledOpacity,
+ }
+}));
+
+function NullAndDefaultFormatter({value, column, children}) {
+ const classes = useStyles();
+ if (_.isUndefined(value) && column.has_default_val) {
+ return [default] ;
+ } else if ((_.isUndefined(value) && column.not_null) ||
+ (_.isUndefined(value) || _.isNull(value))) {
+ return [null] ;
+ }
+ return children;
+}
+NullAndDefaultFormatter.propTypes = {
+ value: PropTypes.any,
+ column: PropTypes.object,
+ children: CustomPropTypes.children,
+};
+
+const FormatterPropTypes = {
+ row: PropTypes.object,
+ column: PropTypes.object,
+};
+export function TextFormatter({row, column}) {
+ let value = row[column.key];
+ if(!_.isNull(value) && !_.isUndefined(value)) {
+ value = value.toString();
+ }
+ return (
+
+ <>{value}>
+
+ );
+}
+TextFormatter.propTypes = FormatterPropTypes;
+
+export function NumberFormatter({row, column}) {
+ let value = row[column.key];
+ return (
+
+ {value}
+
+ );
+}
+NumberFormatter.propTypes = FormatterPropTypes;
+
+export function BinaryFormatter({row, column}) {
+ let value = row[column.key];
+ const classes = useStyles();
+ return (
+
+ [{value}]
+
+ );
+}
+BinaryFormatter.propTypes = FormatterPropTypes;
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/index.jsx b/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/index.jsx
new file mode 100644
index 000000000..17b4b7bf9
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/static/js/components/QueryToolDataGrid/index.jsx
@@ -0,0 +1,398 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import { Box, makeStyles } from '@material-ui/core';
+import _ from 'lodash';
+import React, {useState, useEffect, useCallback, useContext, useRef} from 'react';
+import ReactDataGrid, {Row, useRowSelection} from 'react-data-grid';
+import LockIcon from '@material-ui/icons/Lock';
+import EditIcon from '@material-ui/icons/Edit';
+import { QUERY_TOOL_EVENTS } from '../QueryToolConstants';
+import * as Editors from './Editors';
+import * as Formatters from './Formatters';
+import clsx from 'clsx';
+import { PgIconButton } from '../../../../../../static/js/components/Buttons';
+import MapIcon from '@material-ui/icons/Map';
+import { QueryToolEventsContext } from '../QueryToolComponent';
+import PropTypes, { number } from 'prop-types';
+import gettext from 'sources/gettext';
+
+export const ROWNUM_KEY = '$_pgadmin_rownum_key_$';
+export const GRID_ROW_SELECT_KEY = '$_pgadmin_gridrowselect_key_$';
+
+const useStyles = makeStyles((theme)=>({
+ root: {
+ height: '100%',
+ color: theme.palette.text.primary,
+ backgroundColor: theme.otherVars.qtDatagridBg,
+ fontSize: '12px',
+ border: 'none',
+ '--rdg-selection-color': theme.palette.primary.main,
+ '& .rdg-cell': {
+ ...theme.mixins.panelBorder.right,
+ ...theme.mixins.panelBorder.bottom,
+ fontWeight: 'abc',
+ '&[aria-colindex="1"]': {
+ padding: 0,
+ }
+ },
+ '& .rdg-header-row .rdg-cell': {
+ padding: 0,
+ },
+ '& .rdg-header-row': {
+ backgroundColor: theme.palette.background.default,
+ fontWeight: 'normal',
+ },
+ '& .rdg-row': {
+ backgroundColor: theme.palette.background.default,
+ '&[aria-selected=true]': {
+ backgroundColor: theme.palette.primary.light,
+ color: theme.otherVars.qtDatagridSelectFg,
+ '& .rdg-cell:nth-child(1)': {
+ backgroundColor: theme.palette.primary.main,
+ color: theme.palette.primary.contrastText,
+ }
+ },
+ }
+ },
+ columnHeader: {
+ padding: '3px 6px',
+ height: '100%',
+ display: 'flex',
+ lineHeight: '16px',
+ alignItems: 'center',
+ },
+ columnName: {
+ fontWeight: 'bold',
+ },
+ editedCell: {
+ fontWeight: 'bold',
+ },
+ deletedRow: {
+ '&:before': {
+ content: '" "',
+ position: 'absolute',
+ top: '50%',
+ left: 0,
+ borderTop: '1px solid ' + theme.palette.error.main,
+ width: '100%',
+ }
+ },
+ rowNumCell: {
+ padding: '0px 8px',
+ },
+ colHeaderSelected: {
+ outlineColor: theme.palette.primary.main,
+ backgroundColor: theme.palette.primary.main,
+ color: theme.palette.primary.contrastText,
+ },
+ colSelected: {
+ outlineColor: theme.palette.primary.main,
+ backgroundColor: theme.palette.primary.light,
+ color: theme.otherVars.qtDatagridSelectFg,
+ }
+}));
+
+export const RowInfoContext = React.createContext();
+
+function CustomRow(props) {
+ const rowRef = useRef();
+ const rowInfoValue = {
+ rowIdx: props.rowIdx,
+ getCellElement: (colIdx)=>{
+ return rowRef.current.querySelector(`.rdg-cell[aria-colindex="${colIdx+1}"]`);
+ }
+ };
+ return (
+
+
+
+ );
+}
+
+CustomRow.propTypes = {
+ rowIdx: number,
+};
+
+function SelectAllHeaderRenderer(props) {
+ const [checked, setChecked] = useState(false);
+ const eventBus = useContext(QueryToolEventsContext);
+ const onClick = ()=>{
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.FETCH_MORE_ROWS, true, ()=>{
+ setChecked(!checked);
+ props.onAllRowsSelectionChange(!checked);
+ });
+ };
+ return
;
+}
+SelectAllHeaderRenderer.propTypes = {
+ onAllRowsSelectionChange: PropTypes.func,
+};
+
+function SelectableHeaderRenderer({column, selectedColumns, onSelectedColumnsChange}) {
+ const classes = useStyles();
+ const eventBus = useContext(QueryToolEventsContext);
+
+ const onClick = ()=>{
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.FETCH_MORE_ROWS, true, ()=>{
+ const newSelectedCols = new Set(selectedColumns);
+ if (newSelectedCols.has(column.idx)) {
+ newSelectedCols.delete(column.idx);
+ } else {
+ newSelectedCols.add(column.idx);
+ }
+ onSelectedColumnsChange(newSelectedCols);
+ });
+ };
+
+ const isSelected = selectedColumns.has(column.idx);
+
+ return (
+
+ {(column.column_type_internal == 'geometry' || column.column_type_internal == 'geography') &&
+
+ } size="small" style={{marginRight: '0.25rem'}} onClick={(e)=>{
+ e.stopPropagation();
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_RENDER_GEOMETRIES, column);
+ }}/>
+ }
+
+ {column.display_name}
+ {column.display_type}
+
+ {column.can_edit ?
+ :
+
+ }
+
+ );
+}
+SelectableHeaderRenderer.propTypes = {
+ column: PropTypes.object,
+ selectedColumns: PropTypes.objectOf(Set),
+ onSelectedColumnsChange: PropTypes.func,
+};
+
+function setEditorFormatter(col) {
+ // If grid is editable then add editor else make it readonly
+ if (col.cell == 'oid' && col.name == 'oid') {
+ col.editor = null;
+ col.formatter = Formatters.TextFormatter;
+ } else if (col.cell == 'Json') {
+ col.editor = Editors.JsonTextEditor;
+ col.formatter = Formatters.TextFormatter;
+ } else if (['number', 'oid'].indexOf(col.cell) != -1 || ['xid', 'real'].indexOf(col.type) != -1) {
+ col.formatter = Formatters.NumberFormatter;
+ col.editor = Editors.NumberEditor;
+ } else if (col.cell == 'boolean') {
+ col.editor = Editors.CheckboxEditor;
+ col.formatter = Formatters.TextFormatter;
+ } else if (col.cell == 'binary') {
+ // We do not support editing binary data in SQL editor and data grid.
+ col.editor = null;
+ col.formatter = Formatters.BinaryFormatter;
+ } else {
+ col.editor = Editors.TextEditor;
+ col.formatter = Formatters.TextFormatter;
+ }
+}
+
+function cellClassGetter(col, classes, isSelected, dataChangeStore, rowKeyGetter){
+ return (row)=>{
+ let cellClasses = [];
+ if(dataChangeStore && rowKeyGetter) {
+ if(rowKeyGetter(row) in (dataChangeStore?.updated || {})
+ && !_.isUndefined(dataChangeStore?.updated[rowKeyGetter(row)]?.data[col.key])
+ || rowKeyGetter(row) in (dataChangeStore?.added || {})
+ ) {
+ cellClasses.push(classes.editedCell);
+ }
+ if(rowKeyGetter(row) in (dataChangeStore?.deleted || {})) {
+ cellClasses.push(classes.deletedRow);
+ }
+ }
+ if(isSelected) {
+ cellClasses.push(classes.colSelected);
+ }
+ return clsx(cellClasses);
+ };
+}
+
+function initialiseColumns(columns, rows, totalRowCount, columnWidthBy) {
+ let retColumns = [
+ ...columns,
+ ];
+ const canvas = document.createElement('canvas');
+ const canvasContext = canvas.getContext('2d');
+ canvasContext.font = '12px Roboto';
+
+ for(const col of retColumns) {
+ col.width = getTextWidth(col, rows, canvasContext, columnWidthBy);
+ col.resizable = true;
+ col.editorOptions = {
+ commitOnOutsideClick: false,
+ onCellKeyDown: (e)=>{
+ /* Do not open the editor */
+ e.preventDefault();
+ }
+ };
+ setEditorFormatter(col);
+ }
+
+ let rowNumCol = {
+ key: ROWNUM_KEY, name: '', frozen: true, resizable: false,
+ minWidth: 45, width: canvasContext.measureText((totalRowCount||'').toString()).width,
+ };
+ rowNumCol.cellClass = cellClassGetter(rowNumCol);
+ retColumns.unshift(rowNumCol);
+ canvas.remove();
+ return retColumns;
+}
+
+function formatColumns(columns, dataChangeStore, selectedColumns, onSelectedColumnsChange, rowKeyGetter, classes) {
+ let retColumns = [
+ ...columns,
+ ];
+
+ const HeaderRenderer = (props)=>{
+ return ;
+ };
+
+ for(const [idx, col] of retColumns.entries()) {
+ col.headerRenderer = HeaderRenderer;
+ col.cellClass = cellClassGetter(col, classes, selectedColumns.has(idx), dataChangeStore, rowKeyGetter);
+ }
+
+ let rowNumCol = retColumns[0];
+ rowNumCol.headerRenderer = SelectAllHeaderRenderer;
+ rowNumCol.formatter = ({row})=>{
+ const {rowIdx} = useContext(RowInfoContext);
+ const [isRowSelected, onRowSelectionChange] = useRowSelection();
+ let rowKey = rowKeyGetter(row);
+ let rownum = rowIdx+1;
+ if(rowKey in (dataChangeStore?.added || {})) {
+ rownum = rownum+'+';
+ } else if(rowKey in (dataChangeStore?.deleted || {})) {
+ rownum = rownum+'-';
+ }
+ return ({
+ onSelectedColumnsChange(new Set());
+ onRowSelectionChange({ row: row, checked: !isRowSelected, isShiftClick: false});
+ }}>
+ {rownum}
+
);
+ };
+
+ return retColumns;
+}
+
+function getTextWidth(column, rows, canvas, columnWidthBy) {
+ const dataWidthReducer = (longest, nextRow) => {
+ let value = nextRow[column.key];
+ if(_.isNull(value) || _.isUndefined(value)) {
+ value = '';
+ }
+ value = value.toString();
+ return longest.length > value.length ? longest : value;
+ };
+
+ let columnHeaderLen = column.display_name.length > column.display_type.length ?
+ canvas.measureText(column.display_name).width : canvas.measureText(column.display_type).width;
+ /* padding 12, icon-width 15 */
+ columnHeaderLen += 15 + 12;
+ if(column.column_type_internal == 'geometry' || column.column_type_internal == 'geography') {
+ columnHeaderLen += 40;
+ }
+ let width = columnHeaderLen;
+ if(typeof(columnWidthBy) == 'number') {
+ /* padding 16 */
+ width = 16 + Math.ceil(canvas.measureText(rows.reduce(dataWidthReducer, '')).width);
+ if(width > columnWidthBy && columnWidthBy > 0) {
+ width = columnWidthBy;
+ }
+ if(width < columnHeaderLen) {
+ width = columnHeaderLen;
+ }
+ }
+ /* Gracefull */
+ width += 2;
+ return width;
+}
+
+export default function QueryToolDataGrid({columns, rows, totalRowCount, dataChangeStore,
+ onSelectedCellChange, rowsResetKey, selectedColumns, onSelectedColumnsChange, columnWidthBy, ...props}) {
+ const classes = useStyles();
+ const [readyColumns, setColumns] = useState([]);
+ const eventBus = useContext(QueryToolEventsContext);
+ const onSelectedColumnsChangeWrapped = (arg)=>{
+ props.onSelectedRowsChange(new Set());
+ onSelectedColumnsChange(arg);
+ };
+
+ useEffect(()=>{
+ if(columns.length > 0 || rows.length > 0) {
+ let initCols = initialiseColumns(columns, rows, totalRowCount, columnWidthBy);
+ setColumns(formatColumns(initCols, dataChangeStore, selectedColumns, onSelectedColumnsChangeWrapped, props.rowKeyGetter, classes));
+ } else {
+ setColumns([], [], 0);
+ }
+ }, [columns, rowsResetKey]);
+
+ useEffect(()=>{
+ setColumns((prevCols)=>{
+ return formatColumns(prevCols, dataChangeStore, selectedColumns, onSelectedColumnsChangeWrapped, props.rowKeyGetter, classes);
+ });
+ }, [dataChangeStore, selectedColumns]);
+
+ const onRowClick = useCallback((row, column)=>{
+ if(column.key === ROWNUM_KEY) {
+ onSelectedCellChange && onSelectedCellChange(null);
+ } else {
+ onSelectedCellChange && onSelectedCellChange([row, column]);
+ }
+ }, []);
+
+ function handleCopy() {
+ if (window.isSecureContext) {
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_COPY_DATA);
+ }
+ }
+
+ return (
+
+ );
+}
+
+QueryToolDataGrid.propTypes = {
+ columns: PropTypes.array,
+ rows: PropTypes.array,
+ totalRowCount: PropTypes.number,
+ dataChangeStore: PropTypes.object,
+ onSelectedCellChange: PropTypes.func,
+ onSelectedRowsChange: PropTypes.func,
+ selectedColumns: PropTypes.objectOf(Set),
+ onSelectedColumnsChange: PropTypes.func,
+ rowKeyGetter: PropTypes.func,
+ rowsResetKey: PropTypes.any,
+ columnWidthBy: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
+};
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/dialogs/ConfirmSaveContent.jsx b/web/pgadmin/tools/sqleditor/static/js/components/dialogs/ConfirmSaveContent.jsx
new file mode 100644
index 000000000..ef48b8c30
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/static/js/components/dialogs/ConfirmSaveContent.jsx
@@ -0,0 +1,39 @@
+import React from 'react';
+import { useModalStyles } from '../../../../../../static/js/helpers/ModalProvider';
+import gettext from 'sources/gettext';
+import { Box } from '@material-ui/core';
+import { DefaultButton, PrimaryButton } from '../../../../../../static/js/components/Buttons';
+import CloseIcon from '@material-ui/icons/CloseRounded';
+import CheckRoundedIcon from '@material-ui/icons/CheckRounded';
+import DeleteRoundedIcon from '@material-ui/icons/DeleteRounded';
+import HTMLReactParser from 'html-react-parser';
+import PropTypes from 'prop-types';
+
+export default function ConfirmSaveContent({closeModal, text, onDontSave, onSave}) {
+ const classes = useModalStyles();
+ return (
+
+ {typeof(text) == 'string' ? HTMLReactParser(text) : text}
+
+ } onClick={()=>{
+ closeModal();
+ }} >{gettext('Cancel')}
+ } onClick={()=>{
+ onDontSave?.();
+ closeModal();
+ }} >{gettext('Don\'t save')}
+ } onClick={()=>{
+ onSave?.();
+ closeModal();
+ }} autoFocus={true} >{gettext('Save')}
+
+
+ );
+}
+
+ConfirmSaveContent.propTypes = {
+ closeModal: PropTypes.func,
+ text: PropTypes.string,
+ onDontSave: PropTypes.func,
+ onSave: PropTypes.func
+};
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/dialogs/ConfirmTransactionContent.jsx b/web/pgadmin/tools/sqleditor/static/js/components/dialogs/ConfirmTransactionContent.jsx
new file mode 100644
index 000000000..bfe88d97f
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/static/js/components/dialogs/ConfirmTransactionContent.jsx
@@ -0,0 +1,38 @@
+import React from 'react';
+import { useModalStyles } from '../../../../../../static/js/helpers/ModalProvider';
+import gettext from 'sources/gettext';
+import { Box } from '@material-ui/core';
+import { DefaultButton, PrimaryButton } from '../../../../../../static/js/components/Buttons';
+import CloseIcon from '@material-ui/icons/CloseRounded';
+import HTMLReactParser from 'html-react-parser';
+import { CommitIcon, RollbackIcon } from '../../../../../../static/js/components/ExternalIcon';
+import PropTypes from 'prop-types';
+
+export default function ConfirmTransactionContent({closeModal, text, onRollback, onCommit}) {
+ const classes = useModalStyles();
+ return (
+
+ {typeof(text) == 'string' ? HTMLReactParser(text) : text}
+
+ } onClick={()=>{
+ closeModal();
+ }} >{gettext('Cancel')}
+ } onClick={()=>{
+ onRollback?.();
+ closeModal();
+ }} >{gettext('Rollback')}
+ } onClick={()=>{
+ onCommit?.();
+ closeModal();
+ }} autoFocus={true} >{gettext('Commit')}
+
+
+ );
+}
+
+ConfirmTransactionContent.propTypes = {
+ closeModal: PropTypes.func,
+ text: PropTypes.string,
+ onRollback: PropTypes.func,
+ onCommit: PropTypes.func
+};
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/dialogs/FilterDialog.jsx b/web/pgadmin/tools/sqleditor/static/js/components/dialogs/FilterDialog.jsx
new file mode 100644
index 000000000..336b47d31
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/static/js/components/dialogs/FilterDialog.jsx
@@ -0,0 +1,155 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import { makeStyles } from '@material-ui/core';
+import React from 'react';
+import SchemaView from '../../../../../../static/js/SchemaView';
+import BaseUISchema from '../../../../../../static/js/SchemaView/base_schema.ui';
+import gettext from 'sources/gettext';
+import { QueryToolContext } from '../QueryToolComponent';
+import url_for from 'sources/url_for';
+import PropTypes from 'prop-types';
+
+class SortingCollection extends BaseUISchema {
+ constructor(columnOptions) {
+ super({
+ name: undefined,
+ order: 'asc',
+ });
+ this.columnOptions = columnOptions;
+ this.reloadColOptions = 0;
+ }
+
+ setColumnOptions(columnOptions) {
+ this.columnOptions = columnOptions;
+ this.reloadColOptions = this.reloadColOptions + 1;
+ }
+
+ get baseFields() {
+ return [
+ {
+ id: 'name', label: gettext('Column'), cell: 'select', controlProps: {
+ allowClear: false,
+ }, noEmpty: true, options: this.columnOptions, optionsReloadBasis: this.reloadColOptions
+ },
+ {
+ id: 'order', label: gettext('Order'), cell: 'select', controlProps: {
+ allowClear: false,
+ }, options: [
+ {label: gettext('ASC'), value: 'asc'},
+ {label: gettext('DESC'), value: 'desc'},
+ ]
+ },
+ ];
+ }
+}
+
+class FilterSchema extends BaseUISchema {
+ constructor(columnOptions) {
+ super({
+ sql: null,
+ data_sorting: [],
+ });
+ this.sortingCollObj = new SortingCollection(columnOptions);
+ }
+
+ setColumnOptions(columnOptions) {
+ this.sortingCollObj.setColumnOptions(columnOptions);
+ }
+
+ get baseFields() {
+ let obj = this;
+ return [
+ {
+ id: 'sql', label: gettext('SQL Filter'), type: 'sql', controlProps: {
+ options: {
+ lineWrapping: true,
+ },
+ }
+ },
+ {
+ id: 'data_sorting', label: gettext('Data Sorting'), type: 'collection', schema: obj.sortingCollObj,
+ group: 'temp', uniqueCol: ['name'], canAdd: true, canEdit: false, canDelete: true,
+ },
+ ];
+ }
+}
+
+const useStyles = makeStyles((theme)=>({
+ root: {
+ ...theme.mixins.tabPanel,
+ },
+}));
+
+export default function FilterDialog({onClose, onSave}) {
+ const classes = useStyles();
+ const queryToolCtx = React.useContext(QueryToolContext);
+ const filterSchemaObj = React.useMemo(()=>new FilterSchema([]));
+
+ const getInitData = ()=>{
+ return new Promise((resolve, reject)=>{
+ const getFilterData = async ()=>{
+ try {
+ let {data: respData} = await queryToolCtx.api.get(url_for('sqleditor.get_filter_data', {
+ 'trans_id': queryToolCtx.params.trans_id,
+ }));
+ let {column_list: columns, ...filterData} = respData.data.result;
+ filterSchemaObj.setColumnOptions((columns||[]).map((c)=>({label: c, value: c})));
+ resolve(filterData);
+ } catch (error) {
+ reject(error);
+ }
+ };
+ getFilterData();
+ });
+ };
+
+ const onSaveClick = (_isNew, changeData)=>{
+ return new Promise((resolve, reject)=>{
+ const setFilterData = async ()=>{
+ try {
+ let {data: respData} = await queryToolCtx.api.put(url_for('sqleditor.set_filter_data', {
+ 'trans_id': queryToolCtx.params.trans_id,
+ }), changeData);
+ if(respData.data.status) {
+ resolve();
+ onSave();
+ } else {
+ reject(respData.data.result);
+ }
+ } catch (error) {
+ reject(error);
+ }
+ };
+ setFilterData();
+ });
+ };
+
+ return (<>
+
+ >);
+}
+
+FilterDialog.propTypes = {
+ onClose: PropTypes.func,
+ onSave: PropTypes.func,
+};
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/dialogs/MacrosDialog.jsx b/web/pgadmin/tools/sqleditor/static/js/components/dialogs/MacrosDialog.jsx
new file mode 100644
index 000000000..f67e18899
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/static/js/components/dialogs/MacrosDialog.jsx
@@ -0,0 +1,189 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import { makeStyles } from '@material-ui/core';
+import React from 'react';
+import SchemaView from '../../../../../../static/js/SchemaView';
+import BaseUISchema from '../../../../../../static/js/SchemaView/base_schema.ui';
+import gettext from 'sources/gettext';
+import { QueryToolContext } from '../QueryToolComponent';
+import url_for from 'sources/url_for';
+import _ from 'lodash';
+import PropTypes from 'prop-types';
+
+class MacrosCollection extends BaseUISchema {
+ constructor(keyOptions) {
+ super();
+ this.keyOptions = keyOptions;
+ }
+
+ get idAttribute() {
+ return 'mid';
+ }
+
+ get baseFields() {
+ let obj = this;
+ return [
+ {
+ id: 'id', label: gettext('Key'), cell: 'select', noEmpty: true,
+ width: 100, options: obj.keyOptions, optionsReloadBasis: obj.keyOptions.length,
+ controlProps: {
+ allowClear: false,
+ }
+ },
+ {
+ id: 'name', label: gettext('Name'), cell: 'text', noEmpty: true,
+ width: 100,
+ },
+ {
+ id: 'sql', label: gettext('SQL'), cell: 'sql', noEmpty: true,
+ width: 300, controlProps: {
+ options: {
+ foldGutter: false,
+ lineNumbers: false,
+ gutters: [],
+ readOnly: true,
+ lineWrapping: true,
+ },
+ }
+ },
+ ];
+ }
+}
+
+class MacrosSchema extends BaseUISchema {
+ constructor(keyOptions) {
+ super();
+ this.macrosCollObj = new MacrosCollection(keyOptions);
+ }
+
+ get baseFields() {
+ let obj = this;
+ return [
+ {
+ id: 'macro', label: '', type: 'collection', schema: obj.macrosCollObj,
+ canAdd: true, canDelete: true, isFullTab: true, group: 'temp',
+ },
+ ];
+ }
+
+ validate(state, setError) {
+ let allKeys = state.macro.map((m)=>m.id.toString());
+ if(allKeys.length != new Set(allKeys).size) {
+ setError('macro', gettext('Key must be unique.'));
+ return true;
+ }
+ return false;
+ }
+}
+
+const useStyles = makeStyles((theme)=>({
+ root: {
+ ...theme.mixins.tabPanel,
+ padding: 0,
+ },
+}));
+
+function getChangedMacros(macrosData, changeData) {
+ /* For backend, added, removed is changed. Convert all added, removed to changed. */
+ let changed = [];
+ for (const m of (changeData.macro.changed || [])) {
+ let newM = {...m};
+ if('id' in m) {
+ /* if key changed, clear prev and add new */
+ changed.push({id: m.mid, name: null, sql: null});
+ let em = _.find(macrosData, (d)=>d.mid==m.mid);
+ newM = {name: em.name, sql: em.sql, ...m};
+ } else {
+ newM.id = m.mid;
+ }
+ delete newM.mid;
+ changed.push(newM);
+ }
+ for (const m of (changeData.macro.deleted || [])) {
+ changed.push({id: m.id, name: null, sql: null});
+ }
+ for (const m of (changeData.macro.added || [])) {
+ changed.push(m);
+ }
+ return changed;
+}
+
+export default function MacrosDialog({onClose, onSave}) {
+ const classes = useStyles();
+ const queryToolCtx = React.useContext(QueryToolContext);
+ const [macrosData, setMacrosData] = React.useState([]);
+ const [macrosErr, setMacrosErr] = React.useState(null);
+
+ React.useEffect(async ()=>{
+ try {
+ let {data: respData} = await queryToolCtx.api.get(url_for('sqleditor.get_macros', {
+ 'trans_id': queryToolCtx.params.trans_id,
+ }));
+ /* Copying id to mid to track key id changes */
+ setMacrosData(respData.macro.map((m)=>({...m, mid: m.id})));
+ } catch (error) {
+ setMacrosErr(error);
+ }
+ }, []);
+
+ const onSaveClick = (_isNew, changeData)=>{
+ return new Promise((resolve, reject)=>{
+ const setMacros = async ()=>{
+ try {
+ let changed = getChangedMacros(macrosData, changeData);
+ let {data: respData} = await queryToolCtx.api.put(url_for('sqleditor.set_macros', {
+ 'trans_id': queryToolCtx.params.trans_id,
+ }), {changed: changed});
+ resolve();
+ onSave(respData.macro?.filter((m)=>Boolean(m.name)));
+ onClose();
+ } catch (error) {
+ reject(error);
+ }
+ };
+ setMacros();
+ });
+ };
+
+ const keyOptions = macrosData.map((m)=>({
+ label: m.key_label,
+ value: m.id,
+ }));
+
+ if(keyOptions.length <= 0) {
+ return <>>;
+ }
+ return (<>
+ {
+ if(macrosErr) {
+ return Promise.reject(macrosErr);
+ }
+ return Promise.resolve({macro: macrosData.filter((m)=>Boolean(m.name))});
+ }}
+ schema={new MacrosSchema(keyOptions)}
+ viewHelperProps={{
+ mode: 'edit',
+ }}
+ onSave={onSaveClick}
+ onClose={onClose}
+ hasSQL={false}
+ disableSqlHelp={true}
+ disableDialogHelp={true}
+ isTabView={false}
+ formClassName={classes.root}
+ />
+ >);
+}
+
+MacrosDialog.propTypes = {
+ onClose: PropTypes.func,
+ onSave: PropTypes.func,
+};
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/dialogs/NewConnectionDialog.jsx b/web/pgadmin/tools/sqleditor/static/js/components/dialogs/NewConnectionDialog.jsx
new file mode 100644
index 000000000..fc35c0964
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/static/js/components/dialogs/NewConnectionDialog.jsx
@@ -0,0 +1,254 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import { makeStyles } from '@material-ui/core';
+import React, { useState } from 'react';
+import SchemaView from '../../../../../../static/js/SchemaView';
+import BaseUISchema from '../../../../../../static/js/SchemaView/base_schema.ui';
+import gettext from 'sources/gettext';
+import { QueryToolContext } from '../QueryToolComponent';
+import url_for from 'sources/url_for';
+import _ from 'lodash';
+import { flattenSelectOptions } from '../../../../../../static/js/components/FormComponents';
+import PropTypes from 'prop-types';
+import ConnectServerContent from '../../../../../../browser/static/js/ConnectServerContent';
+
+class NewConnectionSchema extends BaseUISchema {
+ constructor(api, params, connectServer) {
+ super({
+ sid: null,
+ did: null,
+ user: null,
+ role: null,
+ server_name: null,
+ database_name: null,
+ });
+ this.flatServers = [];
+ this.groupedServers = [];
+ this.dbs = [];
+ this.params = params;
+ this.api = api;
+ this.warningText = gettext('By changing the connection you will lose all your unsaved data for the current connection. Do you want to continue?');
+ this.connectServer = connectServer;
+ }
+
+ setServerConnected(sid, icon) {
+ for(const group of this.groupedServers) {
+ for(const opt of group.options) {
+ if(opt.value == sid) {
+ opt.connected = true;
+ opt.image = icon || 'icon-pg';
+ break;
+ }
+ }
+ }
+ }
+
+ isServerConnected(sid) {
+ return _.find(this.flatServers, (s)=>s.value==sid)?.connected;
+ }
+
+ getServerList() {
+ let obj = this;
+ if(this.groupedServers?.length != 0) {
+ return Promise.resolve(this.groupedServers);
+ }
+ return new Promise((resolve, reject)=>{
+ this.api.get(url_for('sqleditor.get_new_connection_servers'))
+ .then(({data: respData})=>{
+ let groupedOptions = [];
+ _.forIn(respData.data.result.server_list, (v, k)=>{
+ /* initial selection */
+ _.find(v, (o)=>o.value==obj.params.sid).selected = true;
+ groupedOptions.push({
+ label: k,
+ options: v,
+ });
+ });
+ /* Will be re-used for changing icon when connected */
+ this.groupedServers = groupedOptions.map((group)=>{
+ return {
+ label: group.label,
+ options: group.options.map((o)=>({...o, selected: false})),
+ };
+ });
+ resolve(groupedOptions);
+ })
+ .catch((error)=>{
+ reject(error);
+ });
+ });
+ }
+
+ getOtherOptions(sid, type) {
+ if(!sid) {
+ return [];
+ }
+
+ if(!this.isServerConnected(sid)) {
+ return [];
+ }
+ return new Promise((resolve, reject)=>{
+ this.api.get(url_for(`sqleditor.${type}`, {
+ 'sid': sid,
+ 'sgid': 0,
+ }))
+ .then(({data: respData})=>{
+ resolve(respData.data.result.data);
+ })
+ .catch((error)=>{
+ reject(error);
+ });
+ });
+ }
+
+ get baseFields() {
+ let self = this;
+ return [
+ {
+ id: 'sid', label: gettext('Server'), type: 'select', noEmpty: true,
+ controlProps: {
+ allowClear: false,
+ }, options: ()=>this.getServerList(),
+ optionsLoaded: (res)=>this.flatServers=flattenSelectOptions(res),
+ optionsReloadBasis: this.flatServers.map((s)=>s.connected).join(''),
+ depChange: (state)=>{
+ /* Once the option is selected get the name */
+ /* Force sid to null, and set only if connected */
+ return {
+ server_name: _.find(this.flatServers, (s)=>s.value==state.sid)?.label,
+ did: null,
+ user: null,
+ role: null,
+ sid: null,
+ };
+ },
+ deferredDepChange: (state, source, topState, actionObj)=>{
+ return new Promise((resolve)=>{
+ let sid = actionObj.value;
+ if(!_.find(this.flatServers, (s)=>s.value==sid)?.connected) {
+ this.connectServer(sid, state.user, null, (data)=>{
+ self.setServerConnected(sid, data.icon);
+ resolve(()=>({sid: sid}));
+ });
+ } else {
+ resolve(()=>({sid: sid}));
+ }
+ });
+ },
+ }, {
+ id: 'did', label: gettext('Database'), deps: ['sid'], noEmpty: true,
+ controlProps: {
+ allowClear: false,
+ },
+ type: (state)=>({
+ type: 'select',
+ options: ()=>this.getOtherOptions(state.sid, 'get_new_connection_database'),
+ optionsReloadBasis: `${state.sid} ${this.isServerConnected(state.sid)}`,
+ }),
+ optionsLoaded: (res)=>this.dbs=res,
+ depChange: (state)=>{
+ /* Once the option is selected get the name */
+ return {database_name: _.find(this.dbs, (s)=>s.value==state.did)?.label};
+ }
+ },{
+ id: 'user', label: gettext('User'), deps: ['sid'], noEmpty: true,
+ controlProps: {
+ allowClear: false,
+ },
+ type: (state)=>({
+ type: 'select',
+ options: ()=>this.getOtherOptions(state.sid, 'get_new_connection_user'),
+ optionsReloadBasis: `${state.sid} ${this.isServerConnected(state.sid)}`,
+ }),
+ },{
+ id: 'role', label: gettext('Role'), deps: ['sid'],
+ type: (state)=>({
+ type: 'select',
+ options: ()=>this.getOtherOptions(state.sid, 'get_new_connection_role'),
+ optionsReloadBasis: `${state.sid} ${this.isServerConnected(state.sid)}`,
+ }),
+ },{
+ id: 'server_name', label: '', type: 'text', visible: false,
+ },{
+ id: 'database_name', label: '', type: 'text', visible: false,
+ },
+ ];
+ }
+}
+
+
+const useStyles = makeStyles((theme)=>({
+ root: {
+ ...theme.mixins.tabPanel,
+ },
+}));
+
+export default function NewConnectionDialog({onClose, onSave}) {
+ const classes = useStyles();
+ const [connecting, setConnecting] = useState(false);
+ const queryToolCtx = React.useContext(QueryToolContext);
+
+ const connectServer = async (sid, user, formData, connectCallback) => {
+ setConnecting(true);
+ try {
+ let {data: respData} = await queryToolCtx.api({
+ method: 'POST',
+ url: url_for('sqleditor.connect_server', {
+ 'sid': sid,
+ ...(user ? {
+ 'usr': user,
+ }:{}),
+ }),
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
+ data: formData
+ });
+ setConnecting(false);
+ connectCallback?.(respData.data);
+ } catch (error) {
+ queryToolCtx.modal.showModal(gettext('Connect to server'), (closeModal)=>{
+ return (
+ {
+ setConnecting(false);
+ closeModal();
+ }}
+ data={error.response?.data?.result}
+ onOK={(formData)=>{
+ connectServer(sid, null, formData, connectCallback);
+ }}
+ />
+ );
+ });
+ }
+ };
+
+ return Promise.resolve({})}
+ schema={new NewConnectionSchema(queryToolCtx.api, {
+ sid: queryToolCtx.params.sid, sgid: 0,
+ }, connectServer)}
+ viewHelperProps={{
+ mode: 'create',
+ }}
+ loadingText={connecting ? 'Connecting...' : ''}
+ onSave={onSave}
+ onClose={onClose}
+ hasSQL={false}
+ disableSqlHelp={true}
+ disableDialogHelp={true}
+ isTabView={false}
+ formClassName={classes.root}
+ />;
+}
+
+NewConnectionDialog.propTypes = {
+ onClose: PropTypes.func,
+ onSave: PropTypes.func,
+};
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/sections/ConnectionBar.jsx b/web/pgadmin/tools/sqleditor/static/js/components/sections/ConnectionBar.jsx
new file mode 100644
index 000000000..da1493e69
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/ConnectionBar.jsx
@@ -0,0 +1,148 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import React from 'react';
+import { makeStyles } from '@material-ui/styles';
+import { Box, CircularProgress, Tooltip } from '@material-ui/core';
+import { DefaultButton, PgButtonGroup, PgIconButton } from '../../../../../../static/js/components/Buttons';
+import KeyboardArrowDownIcon from '@material-ui/icons/KeyboardArrowDown';
+import { ConnectedIcon, DisonnectedIcon, QueryToolIcon } from '../../../../../../static/js/components/ExternalIcon';
+import { QueryToolContext } from '../QueryToolComponent';
+import { CONNECTION_STATUS, CONNECTION_STATUS_MESSAGE } from '../QueryToolConstants';
+import HourglassEmptyRoundedIcon from '@material-ui/icons/HourglassEmptyRounded';
+import QueryBuilderRoundedIcon from '@material-ui/icons/QueryBuilderRounded';
+import ErrorOutlineRoundedIcon from '@material-ui/icons/ErrorOutlineRounded';
+import ReportProblemRoundedIcon from '@material-ui/icons/ReportProblemRounded';
+import { PgMenu, PgMenuItem } from '../../../../../../static/js/components/Menu';
+import gettext from 'sources/gettext';
+import RotateLeftRoundedIcon from '@material-ui/icons/RotateLeftRounded';
+import PropTypes from 'prop-types';
+
+const useStyles = makeStyles((theme)=>({
+ root: {
+ padding: '2px 4px',
+ display: 'flex',
+ alignItems: 'center',
+ gap: '4px',
+ backgroundColor: theme.otherVars.editorToolbarBg,
+ },
+ connectionButton: {
+ display: 'flex',
+ width: '450px',
+ backgroundColor: theme.palette.default.main,
+ color: theme.palette.default.contrastText,
+ border: '1px solid ' + theme.palette.default.borderColor,
+ justifyContent: 'flex-start',
+ },
+ viewDataConnTitle: {
+ marginTop: 'auto',
+ marginBottom: 'auto',
+ padding: '0px 4px',
+ },
+ menu: {
+ '& .szh-menu': {
+ minWidth: '450px',
+ }
+ }
+}));
+
+function ConnectionStatusIcon({connected, connecting, status}) {
+ if(connecting) {
+ return ;
+ } else if(connected) {
+ switch (status) {
+ case CONNECTION_STATUS.TRANSACTION_STATUS_ACTIVE:
+ return ;
+ case CONNECTION_STATUS.TRANSACTION_STATUS_INTRANS:
+ return ;
+ case CONNECTION_STATUS.TRANSACTION_STATUS_INERROR:
+ return ;
+ case CONNECTION_STATUS.TRANSACTION_STATUS_UNKNOWN:
+ return ;
+ default:
+ return ;
+ }
+ } else {
+ return ;
+ }
+}
+
+ConnectionStatusIcon.propTypes = {
+ connected: PropTypes.bool,
+ connecting: PropTypes.bool,
+ status: PropTypes.oneOf(Object.values(CONNECTION_STATUS)),
+};
+
+export function ConnectionBar({connected, connecting, connectionStatus, connectionStatusMsg,
+ connectionList, onConnectionChange, onNewConnClick, onNewQueryToolClick, onResetLayout}) {
+ const classes = useStyles();
+ const connMenuRef = React.useRef();
+ const [connDropdownOpen, setConnDropdownOpen] = React.useState(false);
+ const queryToolCtx = React.useContext(QueryToolContext);
+ const onConnItemClick = (e)=>{
+ if(!e.value.is_selected) {
+ onConnectionChange(e.value);
+ }
+ e.keepOpen = false;
+ };
+
+ const connTitle = React.useMemo(()=>_.find(connectionList, (c)=>c.is_selected)?.conn_title, [connectionList]);
+ return (
+ <>
+
+
+ {queryToolCtx.preferences?.sqleditor?.connection_status &&
+ }
+ />}
+ setConnDropdownOpen(true) : undefined}
+ style={{backgroundColor: queryToolCtx.params.bgcolor, color: queryToolCtx.params.fgcolor}}
+ >
+
+
+ {connecting && '(Obtaining connection)'}{connTitle}
+ {queryToolCtx.params.is_query_tool && }
+
+
+
+ } onClick={onNewQueryToolClick}/>
+
+
+ } onClick={onResetLayout}/>
+
+
+ {setConnDropdownOpen(false);}}
+ className={classes.menu}
+ >
+ {(connectionList||[]).map((conn)=>{
+ return (
+ {conn.conn_title}
+ );
+ })}
+ {`< ${gettext('New connection...')} >`}
+
+ >
+ );
+}
+
+ConnectionBar.propTypes = {
+ connected: PropTypes.bool,
+ connecting: PropTypes.bool,
+ connectionStatus: PropTypes.oneOf(Object.values(CONNECTION_STATUS)),
+ connectionStatusMsg: PropTypes.string,
+ connectionList: PropTypes.array,
+ onConnectionChange: PropTypes.func,
+ onNewConnClick: PropTypes.func,
+ onNewQueryToolClick: PropTypes.func,
+ onResetLayout: PropTypes.func,
+};
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/sections/GeometryViewer.jsx b/web/pgadmin/tools/sqleditor/static/js/components/sections/GeometryViewer.jsx
new file mode 100644
index 000000000..845148d6a
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/GeometryViewer.jsx
@@ -0,0 +1,386 @@
+
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import React, { useEffect, useRef } from 'react';
+import ReactDOMServer from 'react-dom/server';
+import { makeStyles } from '@material-ui/styles';
+import _ from 'lodash';
+import { MapContainer, TileLayer, LayersControl, GeoJSON, useMap } from 'react-leaflet';
+import Leaflet, { CRS } from 'leaflet';
+import {Geometry as WkxGeometry} from 'wkx';
+import {Buffer} from 'buffer';
+import gettext from 'sources/gettext';
+import Theme from 'sources/Theme';
+import clsx from 'clsx';
+import PropTypes from 'prop-types';
+
+const useStyles = makeStyles((theme)=>({
+ mapContainer: {
+ backgroundColor: theme.palette.background.default,
+ height: '100%',
+ width: '100%'
+ },
+ table: {
+ borderSpacing: 0,
+ width: '100%',
+ ...theme.mixins.panelBorder,
+ },
+ tableCell: {
+ margin: 0,
+ padding: theme.spacing(0.5),
+ ...theme.mixins.panelBorder.bottom,
+ ...theme.mixins.panelBorder.right,
+ overflow: 'hidden',
+ textOverflow: 'ellipsis',
+ whiteSpace: 'nowrap',
+ },
+ tableCellHead: {
+ fontWeight: 'bold',
+ }
+}));
+
+function parseEwkbData(rows, column) {
+ let key = column.key;
+ const maxRenderByteLength = 20 * 1024 * 1024; //render geometry data up to 20MB
+ const maxRenderGeometries = 100000; // render geometries up to 100000
+
+ let geometries3D = [],
+ supportedGeometries = [],
+ unsupportedRows = [],
+ geometryItemMap = new Map(),
+ geometryTotalByteLength = 0,
+ tooLargeDataSize = false,
+ tooManyGeometries = false,
+ infoList = [];
+
+ _.every(rows, function (item) {
+ try {
+ let value = item[key];
+ let buffer = Buffer.from(value, 'hex');
+ let geometry = WkxGeometry.parse(buffer);
+ if (geometry.hasZ) {
+ geometries3D.push(geometry);
+ return true;
+ }
+ geometryTotalByteLength += buffer.byteLength;
+ if (geometryTotalByteLength > maxRenderByteLength) {
+ tooLargeDataSize = true;
+ return false;
+ }
+ if (supportedGeometries.length >= maxRenderGeometries) {
+ tooManyGeometries = true;
+ return false;
+ }
+
+ if (!geometry.srid) {
+ geometry.srid = 0;
+ }
+ supportedGeometries.push(geometry);
+ geometryItemMap.set(geometry, item);
+ } catch (e) {
+ unsupportedRows.push(item);
+ }
+ return true;
+ });
+
+ // generate map info content
+ if (tooLargeDataSize || tooManyGeometries) {
+ infoList.push(supportedGeometries.length + ' of ' + rows.length + ' geometries rendered.');
+ }
+ if (geometries3D.length > 0) {
+ infoList.push(gettext('3D geometries not rendered.'));
+ }
+ if (unsupportedRows.length > 0) {
+ infoList.push(gettext('Unsupported geometries not rendered.'));
+ }
+
+ return [
+ supportedGeometries,
+ geometryItemMap,
+ infoList
+ ];
+}
+
+function parseData(rows, columns, column) {
+ if (rows.length === 0) {
+ return {
+ 'geoJSONs': [],
+ 'selectedSRID': 0,
+ 'getPopupContent': undefined,
+ 'infoList': ['Empty row.'],
+ };
+ }
+
+ let mixedSRID = false;
+ // parse ewkb data
+ let [
+ supportedGeometries,
+ geometryItemMap,
+ infoList
+ ] = parseEwkbData(rows, column);
+
+ if (supportedGeometries.length === 0) {
+ return {
+ 'geoJSONs': [],
+ 'selectedSRID': 0,
+ 'getPopupContent': undefined,
+ 'infoList': infoList,
+ };
+ }
+
+ // group geometries by SRID
+ let geometriesGroupBySRID = _.groupBy(supportedGeometries, 'srid');
+ let SRIDGeometriesPairs = _.toPairs(geometriesGroupBySRID);
+ if (SRIDGeometriesPairs.length > 1) {
+ mixedSRID = true;
+ }
+ // select the largest group
+ let selectedPair = _.max(SRIDGeometriesPairs, function (pair) {
+ return pair[1].length;
+ });
+ let selectedSRID = parseInt(selectedPair[0]);
+ let selectedGeometries = selectedPair[1];
+
+ let geoJSONs = _.map(selectedGeometries, function (geometry) {
+ return geometry.toGeoJSON();
+ });
+
+ let getPopupContent;
+ if (columns.length >= 3) {
+ // add popup when geometry has properties
+ getPopupContent = function (geojson) {
+ let geometry = selectedGeometries[geoJSONs.indexOf(geojson)];
+ let row = geometryItemMap.get(geometry);
+ let retVal = [];
+ for (const col of columns) {
+ if(col.key === column.key) {
+ continue;
+ }
+ retVal.push({
+ 'column': col.display_name,
+ 'value': row[col.key],
+ });
+ }
+ return retVal;
+ };
+ }
+
+ if (mixedSRID) {
+ infoList.push(gettext('Geometries with non-SRID %s not rendered.', selectedSRID));
+ }
+
+ return {
+ 'geoJSONs': geoJSONs,
+ 'selectedSRID': selectedSRID,
+ 'getPopupContent': getPopupContent,
+ 'infoList': infoList,
+ };
+}
+
+function PopupTable({data}) {
+ const classes = useStyles();
+ return (
+
+
+ {data.map((row)=>{
+ return (
+
+ {row.column}
+ {row.value}
+
+ );
+ })}
+
+
+ );
+}
+
+PopupTable.propTypes = {
+ data: PropTypes.arrayOf({
+ column: PropTypes.string,
+ value: PropTypes.string,
+ }),
+};
+
+function GeoJsonLayer({data}) {
+ const vectorLayerRef = useRef(null);
+ const mapObj = useMap();
+ useEffect(() => {
+ if(!vectorLayerRef.current) return;
+ if(data.geoJSONs.length <= 0) return;
+ let bounds = vectorLayerRef.current.getBounds().pad(0.1);
+ let maxLength = Math.max(bounds.getNorth() - bounds.getSouth(),
+ bounds.getEast() - bounds.getWest());
+ let minZoom = 0;
+ if(data.selectedSRID !== 4326) {
+ if (maxLength >= 180) {
+ // calculate the min zoom level to enable the map to fit the whole geometry.
+ minZoom = Math.floor(Math.log2(360 / maxLength)) - 2;
+ }
+ }
+ mapObj.setMinZoom(minZoom);
+ if (maxLength > 0) {
+ mapObj.fitBounds(bounds);
+ } else {
+ mapObj.setView(bounds.getCenter(), mapObj.getZoom());
+ }
+ });
+
+ return (
+ {
+ return Leaflet.circleMarker(latlng, {
+ radius: 4,
+ weight: 3,
+ });
+ }}
+ style={{weight: 2}}
+ onEachFeature={(feature, layer)=>{
+ if(_.isFunction(data.getPopupContent)) {
+ const popupContentNode = (
+
+
+
+ );
+ const popupContentHtml = ReactDOMServer.renderToString(popupContentNode);
+ layer.bindPopup(popupContentHtml, {
+ closeButton: false,
+ minWidth: 260,
+ maxWidth: 300,
+ maxHeight: 300,
+ });
+ }
+ }}
+ data={data.geoJSONs}
+ />
+ );
+}
+
+GeoJsonLayer.propTypes = {
+ data: PropTypes.shape({
+ geoJSONs: PropTypes.array,
+ selectedSRID: PropTypes.number,
+ getPopupContent: PropTypes.func,
+ infoList: PropTypes.array,
+ }),
+};
+
+function TheMap({data}) {
+ const mapObj = useMap();
+ const infoControl = useRef(null);
+ useEffect(()=>{
+ infoControl.current = Leaflet.control({position: 'topright'});
+ infoControl.current.onAdd = function () {
+ let ele = Leaflet.DomUtil.create('div', 'geometry-viewer-info-control');
+ ele.innerHTML = data.infoList.join(' ');
+ return ele;
+ };
+ if(data.infoList.length > 0) {
+ infoControl.current.addTo(mapObj);
+ }
+ return ()=>{infoControl.current && infoControl.current.remove();};
+ }, [data]);
+ return (
+ <>
+ {data.selectedSRID === 4326 &&
+
+
+
+
+
+
+
+
+ OpenStreetMap,'
+ + ' © SRTM ,'
+ + ' © OpenTopoMap '
+ }
+ />
+
+
+ OpenStreetMap,'
+ + ' © CartoDB '
+ }
+ subdomains='abcd'
+ />
+
+
+ OpenStreetMap,'
+ + ' © CartoDB '
+ }
+ subdomains='abcd'
+ />
+
+
+ OpenStreetMap,'
+ + ' © CartoDB '
+ }
+ subdomains='abcd'
+ />
+
+ }
+
+ >
+ );
+}
+TheMap.propTypes = {
+ data: PropTypes.shape({
+ geoJSONs: PropTypes.array,
+ selectedSRID: PropTypes.number,
+ getPopupContent: PropTypes.func,
+ infoList: PropTypes.array,
+ }),
+};
+
+
+export function GeometryViewer({rows, columns, column}) {
+ const classes = useStyles();
+ const data = parseData(rows, columns, column);
+ const crs = data.selectedSRID === 4326 ? CRS.EPSG3857 : CRS.Simple;
+ return (
+
+
+
+ );
+}
+
+GeometryViewer.propTypes = {
+ rows: PropTypes.array,
+ columns: PropTypes.array,
+ column: PropTypes.object,
+};
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/sections/MainToolBar.jsx b/web/pgadmin/tools/sqleditor/static/js/components/sections/MainToolBar.jsx
new file mode 100644
index 000000000..42d1222c5
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/MainToolBar.jsx
@@ -0,0 +1,607 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import React, {useContext, useCallback, useEffect, useState} from 'react';
+import { makeStyles } from '@material-ui/styles';
+import { Box } from '@material-ui/core';
+import { PgButtonGroup, PgIconButton } from '../../../../../../static/js/components/Buttons';
+import FolderRoundedIcon from '@material-ui/icons/FolderRounded';
+import KeyboardArrowDownIcon from '@material-ui/icons/KeyboardArrowDown';
+import SaveRoundedIcon from '@material-ui/icons/SaveRounded';
+import StopRoundedIcon from '@material-ui/icons/StopRounded';
+import PlayArrowRoundedIcon from '@material-ui/icons/PlayArrowRounded';
+import { FilterIcon, CommitIcon, RollbackIcon } from '../../../../../../static/js/components/ExternalIcon';
+import EditRoundedIcon from '@material-ui/icons/EditRounded';
+import AssessmentRoundedIcon from '@material-ui/icons/AssessmentRounded';
+import ExplicitRoundedIcon from '@material-ui/icons/ExplicitRounded';
+import FormatListNumberedRoundedIcon from '@material-ui/icons/FormatListNumberedRounded';
+import HelpIcon from '@material-ui/icons/HelpRounded';
+import {QUERY_TOOL_EVENTS, CONNECTION_STATUS} from '../QueryToolConstants';
+import { QueryToolConnectionContext, QueryToolContext, QueryToolEventsContext } from '../QueryToolComponent';
+import { PgMenu, PgMenuDivider, PgMenuItem } from '../../../../../../static/js/components/Menu';
+import gettext from 'sources/gettext';
+import { useKeyboardShortcuts } from '../../../../../../static/js/custom_hooks';
+import {shortcut_key} from 'sources/keyboard_shortcuts';
+import url_for from 'sources/url_for';
+import _ from 'lodash';
+import { InputSelectNonSearch } from '../../../../../../static/js/components/FormComponents';
+import PropTypes from 'prop-types';
+import CustomPropTypes from '../../../../../../static/js/custom_prop_types';
+import ConfirmTransactionContent from '../dialogs/ConfirmTransactionContent';
+import { isMac } from '../../../../../../static/js/keyboard_shortcuts';
+
+const useStyles = makeStyles((theme)=>({
+ root: {
+ padding: '2px 4px',
+ display: 'flex',
+ alignItems: 'center',
+ gap: '4px',
+ backgroundColor: theme.otherVars.editorToolbarBg,
+ ...theme.mixins.panelBorder.bottom,
+ },
+}));
+
+const FIXED_PREF = {
+ find: {
+ 'control': true,
+ ctrl_is_meta: true,
+ 'shift': false,
+ 'alt': false,
+ 'key': {
+ 'key_code': 70,
+ 'char': 'F',
+ },
+ },
+ replace: {
+ 'control': true,
+ ctrl_is_meta: true,
+ 'shift': isMac() ? false : true,
+ 'alt': isMac() ? true : false,
+ 'key': {
+ 'key_code': 70,
+ 'char': 'F',
+ },
+ },
+ jump: {
+ 'control': false,
+ 'shift': false,
+ 'alt': true,
+ 'key': {
+ 'key_code': 71,
+ 'char': 'G',
+ },
+ },
+ indent: {
+ 'control': false,
+ 'shift': false,
+ 'alt': false,
+ 'key': {
+ 'key_code': 9,
+ 'char': 'Tab',
+ },
+ },
+ unindent: {
+ 'control': false,
+ 'shift': true,
+ 'alt': false,
+ 'key': {
+ 'key_code': 9,
+ 'char': 'Tab',
+ },
+ },
+ comment: {
+ 'control': true,
+ ctrl_is_meta: true,
+ 'shift': false,
+ 'alt': false,
+ 'key': {
+ 'key_code': 191,
+ 'char': '/',
+ },
+ },
+ uncomment: {
+ 'control': true,
+ ctrl_is_meta: true,
+ 'shift': false,
+ 'alt': false,
+ 'key': {
+ 'key_code': 190,
+ 'char': '.',
+ },
+ },
+ format_sql: {
+ 'control': true,
+ 'shift': true,
+ 'alt': false,
+ 'key': {
+ 'key_code': 75,
+ 'char': 'k',
+ },
+ },
+};
+
+function autoCommitRollback(type, api, transId, value) {
+ let url = url_for(`sqleditor.${type}`, {
+ 'trans_id': transId,
+ });
+ return api.post(url, JSON.stringify(value));
+}
+
+export function MainToolBar({containerRef, onFilterClick, onManageMacros}) {
+ const classes = useStyles();
+ const eventBus = useContext(QueryToolEventsContext);
+ const queryToolCtx = useContext(QueryToolContext);
+ const queryToolConnCtx = useContext(QueryToolConnectionContext);
+
+ const [highlightFilter, setHighlightFilter] = useState(false);
+ const [limit, setLimit] = useState('-1');
+ const [buttonsDisabled, setButtonsDisabled] = useState({
+ 'save': true,
+ 'cancel': true,
+ 'save-data': true,
+ 'delete-rows': true,
+ 'commit': true,
+ 'rollback': true,
+ 'filter': true,
+ 'limit': false,
+ });
+ const [menuOpenId, setMenuOpenId] = React.useState(null);
+ const [checkedMenuItems, setCheckedMenuItems] = React.useState({});
+ /* Menu button refs */
+ const saveAsMenuRef = React.useRef(null);
+ const editMenuRef = React.useRef(null);
+ const autoCommitMenuRef = React.useRef(null);
+ const explainMenuRef = React.useRef(null);
+ const macrosMenuRef = React.useRef(null);
+ const filterMenuRef = React.useRef(null);
+
+ const queryToolPref = queryToolCtx.preferences.sqleditor;
+ const setDisableButton = useCallback((name, disable=true)=>{
+ setButtonsDisabled((prev)=>({...prev, [name]: disable}));
+ }, []);
+
+ const executeQuery = useCallback(()=>{
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_EXECUTION);
+ }, []);
+ const cancelQuery = useCallback(()=>{
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_STOP_EXECUTION);
+ }, []);
+
+ const explain = useCallback((analyze=false)=>{
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_EXECUTION, {
+ format: 'json',
+ analyze: analyze,
+ verbose: Boolean(checkedMenuItems['explain_verbose']),
+ costs: Boolean(checkedMenuItems['explain_costs']),
+ buffers: analyze ? Boolean(checkedMenuItems['explain_buffers']) : false,
+ timing: analyze ? Boolean(checkedMenuItems['explain_timing']) : false,
+ summary: Boolean(checkedMenuItems['explain_summary']),
+ settings: Boolean(checkedMenuItems['explain_settings']),
+ });
+ }, [checkedMenuItems]);
+
+ const explainAnalyse = useCallback(()=>{
+ explain(true);
+ }, [explain]);
+
+ const openMenu = useCallback((e)=>{
+ setMenuOpenId(e.currentTarget.name);
+ }, []);
+
+ const handleMenuClose = useCallback(()=>{
+ setMenuOpenId(null);
+ }, []);
+
+ const checkMenuClick = useCallback((e)=>{
+ setCheckedMenuItems((prev)=>{
+ let newVal = !prev[e.value];
+ if(e.value === 'auto_commit' || e.value === 'auto_rollback') {
+ autoCommitRollback(e.value, queryToolCtx.api, queryToolCtx.params.trans_id, newVal)
+ .catch ((error)=>{
+ newVal = prev[e.value];
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.HANDLE_API_ERROR, error, {
+ checkTransaction: true,
+ });
+ });
+ }
+ return {
+ ...prev,
+ [e.value]: newVal,
+ };
+ });
+ }, []);
+
+ const openFile = useCallback(()=>{
+ confirmDiscard(()=>{
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_LOAD_FILE);
+ });
+ }, []);
+
+ const saveFile = useCallback((saveAs=false)=>{
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_SAVE_FILE, saveAs);
+ }, []);
+
+ useEffect(()=>{
+ eventBus.registerListener(QUERY_TOOL_EVENTS.EXECUTION_START, ()=>{
+ setDisableButton('execute', true);
+ setDisableButton('cancel', false);
+ setDisableButton('explain', true);
+ setDisableButton('explain_analyse', true);
+ setDisableButton('limit', true);
+ });
+ eventBus.registerListener(QUERY_TOOL_EVENTS.EXECUTION_END, ()=>{
+ setDisableButton('execute', false);
+ setDisableButton('cancel', true);
+ setDisableButton('explain', false);
+ setDisableButton('explain_analyse', false);
+ setDisableButton('limit', false);
+ });
+ eventBus.registerListener(QUERY_TOOL_EVENTS.TRIGGER_SAVE_RESULTS, ()=>{
+ setDisableButton('execute', true);
+ setDisableButton('explain', true);
+ setDisableButton('explain_analyse', true);
+ setDisableButton('limit', true);
+ });
+ eventBus.registerListener(QUERY_TOOL_EVENTS.TRIGGER_SAVE_RESULTS_END, ()=>{
+ setDisableButton('execute', false);
+ setDisableButton('explain', false);
+ setDisableButton('explain_analyse', false);
+ setDisableButton('limit', false);
+ });
+ eventBus.registerListener(QUERY_TOOL_EVENTS.QUERY_CHANGED, (isDirty)=>{
+ setDisableButton('save', !isDirty);
+ });
+ eventBus.registerListener(QUERY_TOOL_EVENTS.DATAGRID_CHANGED, (isDirty)=>{
+ setDisableButton('save-data', !isDirty);
+ });
+ eventBus.registerListener(QUERY_TOOL_EVENTS.SELECTED_ROWS_COLS_CHANGED, (rows)=>{
+ setDisableButton('delete-rows', !rows);
+ });
+ eventBus.registerListener(QUERY_TOOL_EVENTS.SET_FILTER_INFO, (canFilter, filterApplied)=>{
+ setDisableButton('filter', !canFilter);
+ setHighlightFilter(filterApplied);
+ });
+ eventBus.registerListener(QUERY_TOOL_EVENTS.SET_LIMIT_VALUE, (l)=>{
+ setLimit(l);
+ });
+ }, []);
+
+ useEffect(()=>{
+ setDisableButton('execute', queryToolConnCtx.obtainingConn);
+ setDisableButton('explain', queryToolConnCtx.obtainingConn);
+ setDisableButton('explain_analyse', queryToolConnCtx.obtainingConn);
+ }, [queryToolConnCtx.obtainingConn]);
+
+ const isInTxn = ()=>(queryToolConnCtx.connectionStatus == CONNECTION_STATUS.TRANSACTION_STATUS_INTRANS
+ || queryToolConnCtx.connectionStatus == CONNECTION_STATUS.TRANSACTION_STATUS_INERROR);
+
+ const onExecutionDone = ()=>{
+ eventBus.registerListener(QUERY_TOOL_EVENTS.EXECUTION_END, (success)=>{
+ if(success) {
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.FORCE_CLOSE_PANEL);
+ }
+ }, true);
+ };
+ const warnTxnClose = ()=>{
+ if(!isInTxn() || !queryToolCtx.preferences?.sqleditor.prompt_commit_transaction) {
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.FORCE_CLOSE_PANEL);
+ return;
+ }
+ queryToolCtx.modal.showModal(gettext('Commit transaction?'), (closeModal)=>(
+ {
+ onExecutionDone();
+ onRollbackClick();
+ }}
+ onCommit={()=>{
+ onExecutionDone();
+ onCommitClick();
+ }}
+ />
+ ));
+ };
+ useEffect(()=>{
+ if(isInTxn()) {
+ setDisableButton('commit', false);
+ setDisableButton('rollback', false);
+ } else {
+ setDisableButton('commit', true);
+ setDisableButton('rollback', true);
+ }
+ eventBus.registerListener(QUERY_TOOL_EVENTS.WARN_TXN_CLOSE, warnTxnClose);
+ return ()=>{
+ eventBus.deregisterListener(QUERY_TOOL_EVENTS.WARN_TXN_CLOSE, warnTxnClose);
+ };
+ }, [queryToolConnCtx.connectionStatus]);
+
+ const onCommitClick=()=>{
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.EXECUTION_START, 'COMMIT;', null, true);
+ };
+ const onRollbackClick=()=>{
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.EXECUTION_START, 'ROLLBACK;', null, true);
+ };
+ const executeMacro = (m)=>{
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.EXECUTION_START, m.sql, null, true);
+ };
+ const onLimitChange=(e)=>{
+ setLimit(e.target.value);
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_SET_LIMIT,e.target.value);
+ };
+ const formatSQL=()=>{
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_FORMAT_SQL);
+ };
+ const clearQuery=()=>{
+ confirmDiscard(()=>{
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.EDITOR_SET_SQL, '');
+ });
+ };
+ const onHelpClick=()=>{
+ let url = url_for('help.static', {'filename': 'query_tool.html'});
+ window.open(url, 'pgadmin_help');
+ };
+ const confirmDiscard=(callback)=>{
+ queryToolCtx.modal.confirm(
+ gettext('Unsaved changes'),
+ gettext('Are you sure you wish to discard the current changes?'),
+ function() {
+ callback();
+ },
+ function() {
+ return true;
+ }
+ );
+ };
+
+ useEffect(()=>{
+ if(queryToolPref) {
+ /* Get the prefs first time */
+ if(_.isUndefined(checkedMenuItems.auto_commit)) {
+ setCheckedMenuItems({
+ auto_commit: queryToolPref.auto_commit,
+ auto_rollback: queryToolPref.auto_rollback,
+ explain_verbose: queryToolPref.explain_verbose,
+ explain_costs: queryToolPref.explain_costs,
+ explain_buffers: queryToolPref.explain_buffers,
+ explain_timing: queryToolPref.explain_timing,
+ explain_summary: queryToolPref.explain_summary,
+ explain_settings: queryToolPref.explain_settings,
+ });
+ }
+ }
+ }, [queryToolPref]);
+
+ /* Button shortcuts */
+ useKeyboardShortcuts([
+ {
+ shortcut: queryToolPref.execute_query,
+ options: {
+ callback: ()=>{executeQuery();}
+ }
+ },
+ {
+ shortcut: queryToolPref.explain_query,
+ options: {
+ callback: (e)=>{e.preventDefault();explain();}
+ }
+ },
+ {
+ shortcut: queryToolPref.explain_analyze_query,
+ options: {
+ callback: ()=>{explainAnalyse();}
+ }
+ },
+ {
+ shortcut: queryToolPref.commit_transaction,
+ options: {
+ callback: ()=>{onCommitClick();}
+ }
+ },
+ {
+ shortcut: queryToolPref.rollback_transaction,
+ options: {
+ callback: ()=>{onRollbackClick();}
+ }
+ },
+ {
+ shortcut: FIXED_PREF.format_sql,
+ options: {
+ callback: ()=>{formatSQL();}
+ }
+ },
+ {
+ shortcut: queryToolPref.clear_query,
+ options: {
+ callback: ()=>{clearQuery();}
+ }
+ },
+ ], containerRef);
+
+ /* Macro shortcuts */
+ useKeyboardShortcuts(
+ queryToolCtx.params?.macros?.map((m)=>{
+ return {
+ shortcut: {
+ ...m,
+ 'key': {
+ 'key_code': m.key_code,
+ 'char': m.key,
+ },
+ },
+ options: {
+ callback: ()=>{executeMacro(m);}
+ }
+ };
+ }) || [],
+ containerRef
+ );
+
+ return (
+ <>
+
+
+ } disabled={!queryToolCtx.params.is_query_tool}
+ accesskey={shortcut_key(queryToolPref.btn_open_file)} onClick={openFile} />
+ }
+ accesskey={shortcut_key(queryToolPref.btn_save_file)} disabled={buttonsDisabled['save'] || !queryToolCtx.params.is_query_tool}
+ onClick={()=>{saveFile(false);}} />
+ } splitButton disabled={!queryToolCtx.params.is_query_tool}
+ name="menu-saveas" ref={saveAsMenuRef} onClick={openMenu}
+ />
+
+
+ >}
+ disabled={!queryToolCtx.params.is_query_tool}
+ name="menu-edit" ref={editMenuRef} onClick={openMenu} />
+
+
+ }
+ onClick={onFilterClick} disabled={buttonsDisabled['filter']} accesskey={shortcut_key(queryToolPref.btn_filter_dialog)}/>
+ } splitButton
+ disabled={buttonsDisabled['filter']} name="menu-filter" ref={filterMenuRef} accesskey={shortcut_key(queryToolPref.btn_filter_options)}
+ onClick={openMenu} />
+
+
+
+ }
+ onClick={cancelQuery} disabled={buttonsDisabled['cancel']} accesskey={shortcut_key(queryToolPref.btn_cancel_query)} />
+ }
+ onClick={executeQuery} disabled={buttonsDisabled['execute']} shortcut={queryToolPref.execute_query}/>
+ } splitButton
+ name="menu-autocommit" ref={autoCommitMenuRef} accesskey={shortcut_key(queryToolPref.btn_delete_row)}
+ onClick={openMenu} />
+
+
+ }
+ onClick={()=>{explain();}} disabled={buttonsDisabled['explain'] || !queryToolCtx.params.is_query_tool} shortcut={queryToolPref.explain_query}/>
+ }
+ onClick={()=>{explainAnalyse();}} disabled={buttonsDisabled['explain_analyse'] || !queryToolCtx.params.is_query_tool} shortcut={queryToolPref.explain_analyze_query}/>
+ } splitButton
+ disabled={!queryToolCtx.params.is_query_tool}
+ name="menu-explain" ref={explainMenuRef} onClick={openMenu} />
+
+
+ }
+ onClick={onCommitClick} disabled={buttonsDisabled['commit']} shortcut={queryToolPref.commit_transaction}/>
+ }
+ onClick={onRollbackClick} disabled={buttonsDisabled['rollback']} shortcut={queryToolPref.rollback_transaction}/>
+
+
+ >}
+ disabled={!queryToolCtx.params.is_query_tool} name="menu-macros" ref={macrosMenuRef} onClick={openMenu} />
+
+
+ } onClick={onHelpClick} />
+
+
+
+ {saveFile(true);}}>{gettext('Save as')}
+
+
+ {eventBus.fireEvent(QUERY_TOOL_EVENTS.EDITOR_FIND_REPLACE, false);}}>{gettext('Find')}
+ {eventBus.fireEvent(QUERY_TOOL_EVENTS.EDITOR_FIND_REPLACE, true);}}>{gettext('Replace')}
+ {eventBus.fireEvent(QUERY_TOOL_EVENTS.EDITOR_EXEC_CMD, 'jumpToLine');}}>{gettext('Jump')}
+
+ {eventBus.fireEvent(QUERY_TOOL_EVENTS.EDITOR_EXEC_CMD, 'indentMore');}}>{gettext('Indent')}
+ {eventBus.fireEvent(QUERY_TOOL_EVENTS.EDITOR_EXEC_CMD, 'indentLess');}}>{gettext('Unindent')}
+ {eventBus.fireEvent(QUERY_TOOL_EVENTS.EDITOR_EXEC_CMD, 'toggleComment');}}>{gettext('Toggle comment')}
+ {gettext('Clear query')}
+
+ {gettext('Format SQL')}
+
+
+ {eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_INCLUDE_EXCLUDE_FILTER, true);}}>{gettext('Filter by Selection')}
+ {eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_INCLUDE_EXCLUDE_FILTER, false);}}>{gettext('Exclude by Selection')}
+ {eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_REMOVE_FILTER);}}>{gettext('Remove Sort/Filter')}
+
+
+ {gettext('Auto commit?')}
+ {gettext('Auto rollback on error?')}
+
+
+ {gettext('Verbose')}
+ {gettext('Costs')}
+ {gettext('Buffers')}
+ {gettext('Timing')}
+ {gettext('Summary')}
+ {gettext('Settings')}
+
+
+ {gettext('Manage macros')}
+
+ {queryToolCtx.params?.macros?.map((m, i)=>{
+ return (
+ executeMacro(m)} key={i}>
+ {m.name}
+
+ );
+ })}
+
+ >
+ );
+}
+
+MainToolBar.propTypes = {
+ containerRef: CustomPropTypes.ref,
+ onFilterClick: PropTypes.func,
+ onManageMacros: PropTypes.func,
+};
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/sections/Messages.jsx b/web/pgadmin/tools/sqleditor/static/js/components/sections/Messages.jsx
new file mode 100644
index 000000000..ea3d3b657
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/Messages.jsx
@@ -0,0 +1,46 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import { makeStyles } from '@material-ui/styles';
+import React from 'react';
+import { QueryToolEventsContext } from '../QueryToolComponent';
+import { QUERY_TOOL_EVENTS } from '../QueryToolConstants';
+
+const useStyles = makeStyles((theme)=>({
+ root: {
+ whiteSpace: 'pre-wrap',
+ fontFamily: '"Source Code Pro", SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
+ padding: '5px 10px',
+ overflow: 'auto',
+ height: '100%',
+ fontSize: '12px',
+ userSelect: 'text',
+ backgroundColor: theme.palette.background.default,
+ color: theme.palette.text.primary,
+ ...theme.mixins.fontSourceCode,
+ }
+}));
+
+export function Messages() {
+ const classes = useStyles();
+ const [messageText, setMessageText] = React.useState('');
+ const eventBus = React.useContext(QueryToolEventsContext);
+ React.useEffect(()=>{
+ eventBus.registerListener(QUERY_TOOL_EVENTS.SET_MESSAGE, (text, append=false)=>{
+ setMessageText((prev)=>{
+ if(append) {
+ return prev+text;
+ }
+ return text;
+ });
+ });
+ }, []);
+ return (
+ {messageText}
+ );
+}
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/sections/Notifications.jsx b/web/pgadmin/tools/sqleditor/static/js/components/sections/Notifications.jsx
new file mode 100644
index 000000000..ea6a1607d
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/Notifications.jsx
@@ -0,0 +1,58 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import React from 'react';
+import { commonTableStyles } from '../../../../../../static/js/Theme';
+import { QUERY_TOOL_EVENTS } from '../QueryToolConstants';
+import gettext from 'sources/gettext';
+import _ from 'lodash';
+import clsx from 'clsx';
+import { QueryToolEventsContext } from '../QueryToolComponent';
+
+export function Notifications() {
+ const [notices, setNotices] = React.useState([]);
+ const tableClasses = commonTableStyles();
+ const eventBus = React.useContext(QueryToolEventsContext);
+ React.useEffect(()=>{
+ eventBus.registerListener(QUERY_TOOL_EVENTS.PUSH_NOTICE, (notice)=>{
+ if(_.isArray(notice)) {
+ setNotices((prev)=>[
+ ...prev,
+ ...notice,
+ ]);
+ } else {
+ setNotices((prev)=>[
+ ...prev,
+ notice,
+ ]);
+ }
+ });
+ }, []);
+
+
+ return
+
+
+ {gettext('Recorded time')}
+ {gettext('Event')}
+ {gettext('Process ID')}
+ {gettext('Payload')}
+
+
+
+ {notices.map((notice, i)=>{
+ return
+ {notice.recorded_time}
+ {notice.channel}
+ {notice.pid}
+ {notice.payload}
+ ;
+ })}
+
+
;
+}
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/sections/Query.jsx b/web/pgadmin/tools/sqleditor/static/js/components/sections/Query.jsx
new file mode 100644
index 000000000..e37f91a8a
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/Query.jsx
@@ -0,0 +1,401 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import { makeStyles } from '@material-ui/styles';
+import React, {useContext, useCallback, useEffect } from 'react';
+import { QueryToolContext, QueryToolEventsContext } from '../QueryToolComponent';
+import CodeMirror from '../../../../../../static/js/components/CodeMirror';
+import {PANELS, QUERY_TOOL_EVENTS} from '../QueryToolConstants';
+import url_for from 'sources/url_for';
+import { LayoutEventsContext, LAYOUT_EVENTS } from '../../../../../../static/js/helpers/Layout';
+import ConfirmSaveContent from '../dialogs/ConfirmSaveContent';
+import gettext from 'sources/gettext';
+import OrigCodeMirror from 'bundled_codemirror';
+import Notifier from '../../../../../../static/js/helpers/Notifier';
+import { isMac } from '../../../../../../static/js/keyboard_shortcuts';
+
+const useStyles = makeStyles(()=>({
+ sql: {
+ height: '100%',
+ }
+}));
+
+function registerAutocomplete(api, transId, onFailure) {
+ OrigCodeMirror.registerHelper('hint', 'sql', function (editor) {
+ var data = [],
+ doc = editor.getDoc(),
+ cur = doc.getCursor(),
+ // Get the current cursor position
+ current_cur = cur.ch,
+ // function context
+ ctx = {
+ editor: editor,
+ // URL for auto-complete
+ url: url_for('sqleditor.autocomplete', {
+ 'trans_id': transId,
+ }),
+ data: data,
+ // Get the line number in the cursor position
+ current_line: cur.line,
+ /*
+ * Render function for hint to add our own class
+ * and icon as per the object type.
+ */
+ hint_render: function (elt, data_arg, cur_arg) {
+ var el = document.createElement('span');
+
+ switch (cur_arg.type) {
+ case 'database':
+ el.className = 'sqleditor-hint pg-icon-' + cur_arg.type;
+ break;
+ case 'datatype':
+ el.className = 'sqleditor-hint icon-type';
+ break;
+ case 'keyword':
+ el.className = 'fa fa-key';
+ break;
+ case 'table alias':
+ el.className = 'fa fa-at';
+ break;
+ default:
+ el.className = 'sqleditor-hint icon-' + cur_arg.type;
+ }
+
+ el.appendChild(document.createTextNode(cur_arg.text));
+ elt.appendChild(el);
+ },
+ };
+
+ data.push(doc.getValue());
+ // Get the text from start to the current cursor position.
+ data.push(
+ doc.getRange({
+ line: 0,
+ ch: 0,
+ }, {
+ line: ctx.current_line,
+ ch: current_cur,
+ })
+ );
+
+ return {
+ then: function (cb) {
+ var self_local = this;
+ // Make ajax call to find the autocomplete data
+ api.post(self_local.url, JSON.stringify(self_local.data))
+ .then((res) => {
+ var result = [];
+
+ _.each(res.data.data.result, function (obj, key) {
+ result.push({
+ text: key,
+ type: obj.object_type,
+ render: self_local.hint_render,
+ });
+ });
+
+ // Sort function to sort the suggestion's alphabetically.
+ result.sort(function (a, b) {
+ var textA = a.text.toLowerCase(),
+ textB = b.text.toLowerCase();
+ if (textA < textB) //sort string ascending
+ return -1;
+ if (textA > textB)
+ return 1;
+ return 0; //default return value (no sorting)
+ });
+
+ /*
+ * Below logic find the start and end point
+ * to replace the selected auto complete suggestion.
+ */
+ var token = self_local.editor.getTokenAt(cur),
+ start, end, search;
+ if (token.end > cur.ch) {
+ token.end = cur.ch;
+ token.string = token.string.slice(0, cur.ch - token.start);
+ }
+
+ if (token.string.match(/^[.`\w@]\w*$/)) {
+ search = token.string;
+ start = token.start;
+ end = token.end;
+ } else {
+ start = end = cur.ch;
+ search = '';
+ }
+
+ /*
+ * Added 1 in the start position if search string
+ * started with "." or "`" else auto complete of code mirror
+ * will remove the "." when user select any suggestion.
+ */
+ if (search.charAt(0) == '.' || search.charAt(0) == '``')
+ start += 1;
+
+ cb({
+ list: result,
+ from: {
+ line: self_local.current_line,
+ ch: start,
+ },
+ to: {
+ line: self_local.current_line,
+ ch: end,
+ },
+ });
+ })
+ .catch((err) => {
+ onFailure?.(err);
+ });
+ }.bind(ctx),
+ };
+ });
+}
+
+export default function Query() {
+ const classes = useStyles();
+ const editor = React.useRef();
+ const eventBus = useContext(QueryToolEventsContext);
+ const queryToolCtx = useContext(QueryToolContext);
+ const layoutEvenBus = useContext(LayoutEventsContext);
+ const lastSavedText = React.useRef('');
+ const markedLine = React.useRef(0);
+
+ const removeHighlightError = (cmObj)=>{
+ // Remove already existing marker
+ cmObj.removeLineClass(markedLine.current, 'wrap', 'CodeMirror-activeline-background');
+ markedLine.current = 0;
+ };
+ const highlightError = (cmObj, result)=>{
+ let errorLineNo = 0,
+ startMarker = 0,
+ endMarker = 0,
+ selectedLineNo = 0;
+
+ removeHighlightError(cmObj);
+
+ // In case of selection we need to find the actual line no
+ if (cmObj.getSelection().length > 0)
+ selectedLineNo = cmObj.getCursor(true).line;
+
+ // Fetch the LINE string using regex from the result
+ var line = /LINE (\d+)/.exec(result),
+ // Fetch the Character string using regex from the result
+ char = /Character: (\d+)/.exec(result);
+
+ // If line and character is null then no need to mark
+ if (line != null && char != null) {
+ errorLineNo = (parseInt(line[1]) - 1) + selectedLineNo;
+ var errorCharNo = (parseInt(char[1]) - 1);
+
+ /* We need to loop through each line till the error line and
+ * count the total no of character to figure out the actual
+ * starting/ending marker point for the individual line. We
+ * have also added 1 per line for the "\n" character.
+ */
+ var prevLineChars = 0;
+ for (let i = selectedLineNo > 0 ? selectedLineNo : 0; i < errorLineNo; i++)
+ prevLineChars += cmObj.getLine(i).length + 1;
+
+ /* Marker starting point for the individual line is
+ * equal to error character index minus total no of
+ * character till the error line starts.
+ */
+ startMarker = errorCharNo - prevLineChars;
+
+ // Find the next space from the character or end of line
+ var errorLine = cmObj.getLine(errorLineNo);
+
+ if (_.isUndefined(errorLine)) return;
+ endMarker = errorLine.indexOf(' ', startMarker);
+ if (endMarker < 0)
+ endMarker = errorLine.length;
+
+ // Mark the error text
+ cmObj.markText({
+ line: errorLineNo,
+ ch: startMarker,
+ }, {
+ line: errorLineNo,
+ ch: endMarker,
+ }, {
+ className: 'sql-editor-mark',
+ });
+
+ markedLine.current = errorLineNo;
+ cmObj.addLineClass(errorLineNo, 'wrap', 'CodeMirror-activeline-background');
+ cmObj.focus();
+ cmObj.setCursor(errorLineNo, 0);
+ }
+ };
+
+ const triggerExecution = (explainObject)=>{
+ if(queryToolCtx.params.is_query_tool) {
+ let query = editor.current?.getSelection() || editor.current?.getValue() || '';
+ if(query) {
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.EXECUTION_START, query, explainObject);
+ }
+ } else {
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.EXECUTION_START, null, null);
+ }
+ };
+
+ useEffect(()=>{
+ layoutEvenBus.registerListener(LAYOUT_EVENTS.ACTIVE, (currentTabId)=>{
+ currentTabId == PANELS.QUERY && editor.current.focus();
+ });
+
+ eventBus.registerListener(QUERY_TOOL_EVENTS.TRIGGER_EXECUTION, triggerExecution);
+
+ eventBus.registerListener(QUERY_TOOL_EVENTS.HIGHLIGHT_ERROR, (result)=>{
+ if(result) {
+ highlightError(editor.current, result);
+ } else {
+ removeHighlightError(editor.current);
+ }
+ });
+
+ eventBus.registerListener(QUERY_TOOL_EVENTS.LOAD_FILE, (fileName)=>{
+ queryToolCtx.api.post(url_for('sqleditor.load_file'), {
+ 'file_name': decodeURI(fileName),
+ }).then((res)=>{
+ editor.current.setValue(res.data);
+ lastSavedText.current = res.data;
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.LOAD_FILE_DONE, fileName, true);
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.QUERY_CHANGED, isDirty());
+ }).catch((err)=>{
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.LOAD_FILE_DONE, null, false);
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.HANDLE_API_ERROR, err);
+ });
+ });
+
+ eventBus.registerListener(QUERY_TOOL_EVENTS.SAVE_FILE, (fileName)=>{
+ let editorValue = editor.current.getValue();
+ queryToolCtx.api.post(url_for('sqleditor.save_file'), {
+ 'file_name': decodeURI(fileName),
+ 'file_content': editor.current.getValue(),
+ }).then(()=>{
+ lastSavedText.current = editorValue;
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.SAVE_FILE_DONE, fileName, true);
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.QUERY_CHANGED, isDirty());
+ Notifier.success(gettext('File saved successfully.'));
+ }).catch((err)=>{
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.SAVE_FILE_DONE, null, false);
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.HANDLE_API_ERROR, err);
+ });
+ });
+
+ eventBus.registerListener(QUERY_TOOL_EVENTS.EDITOR_EXEC_CMD, (cmd='')=>{
+ editor.current?.execCommand(cmd);
+ });
+ eventBus.registerListener(QUERY_TOOL_EVENTS.COPY_TO_EDITOR, (text)=>{
+ editor.current?.setValue(text);
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.FOCUS_PANEL, PANELS.QUERY);
+ setTimeout(()=>{
+ editor.current?.focus();
+ editor.current?.setCursor(editor.current.lineCount(), 0);
+ }, 250);
+ });
+ eventBus.registerListener(QUERY_TOOL_EVENTS.EDITOR_FIND_REPLACE, (replace=false)=>{
+ editor.current?.focus();
+ let key = {
+ keyCode: 70, metaKey: false, ctrlKey: true, shiftKey: replace, altKey: false,
+ };
+ if(isMac()) {
+ key.metaKey = true;
+ key.ctrlKey = false;
+ key.shiftKey = false;
+ key.altKey = true;
+ }
+ editor.current?.triggerOnKeyDown(
+ new KeyboardEvent('keydown', key)
+ );
+ });
+ eventBus.registerListener(QUERY_TOOL_EVENTS.EDITOR_SET_SQL, (value, focus=true)=>{
+ focus && editor.current?.focus();
+ editor.current?.setValue(value);
+ });
+ eventBus.registerListener(QUERY_TOOL_EVENTS.TRIGGER_QUERY_CHANGE, ()=>{
+ change();
+ });
+ eventBus.registerListener(QUERY_TOOL_EVENTS.WARN_SAVE_TEXT_CLOSE, ()=>{
+ if(!isDirty() || !queryToolCtx.preferences?.sqleditor.prompt_save_query_changes) {
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.WARN_TXN_CLOSE);
+ return;
+ }
+ queryToolCtx.modal.showModal(gettext('Save query changes?'), (closeModal)=>(
+ {
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.WARN_TXN_CLOSE);
+ }}
+ onSave={()=>{
+ eventBus.registerListener(QUERY_TOOL_EVENTS.SAVE_FILE_DONE, (_f, success)=>{
+ if(success) {
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.WARN_TXN_CLOSE);
+ }
+ }, true);
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_SAVE_FILE);
+ }}
+ />
+ ));
+ });
+ eventBus.registerListener(QUERY_TOOL_EVENTS.TRIGGER_FORMAT_SQL, ()=>{
+ let selection = true, sql = editor.current?.getSelection();
+ if(sql == '') {
+ sql = editor.current.getValue();
+ selection = false;
+ }
+ queryToolCtx.api.post(url_for('sql.format'), {
+ 'sql': sql,
+ }).then((res)=>{
+ if(selection) {
+ editor.current.replaceSelection(res.data.data.sql, 'around');
+ } else {
+ editor.current.setValue(res.data.data.sql);
+ }
+ }).catch(()=>{/* failure should be ignored */});
+ });
+
+ editor.current.focus();
+ }, []);
+
+ useEffect(()=>{
+ registerAutocomplete(queryToolCtx.api, queryToolCtx.params.trans_id, (err)=>{
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.HANDLE_API_ERROR, err);
+ });
+ }, [queryToolCtx.params.trans_id]);
+
+ const isDirty = ()=>lastSavedText.current !== editor.current.getValue();
+
+ const cursorActivity = useCallback((cmObj)=>{
+ const c = cmObj.getCursor();
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.CURSOR_ACTIVITY, [c.line+1, c.ch+1]);
+ }, []);
+
+ const change = useCallback(()=>{
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.QUERY_CHANGED, isDirty());
+ }, []);
+
+ return {
+ editor.current=obj;
+ }}
+ value={''}
+ className={classes.sql}
+ events={{
+ 'focus': cursorActivity,
+ 'cursorActivity': cursorActivity,
+ 'change': change,
+ }}
+ disabled={!queryToolCtx.params.is_query_tool}
+ autocomplete={true}
+ />;
+}
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/sections/QueryHistory.jsx b/web/pgadmin/tools/sqleditor/static/js/components/sections/QueryHistory.jsx
new file mode 100644
index 000000000..cbbca3486
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/QueryHistory.jsx
@@ -0,0 +1,500 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import { makeStyles } from '@material-ui/styles';
+import React from 'react';
+import { PANELS, QUERY_TOOL_EVENTS } from '../QueryToolConstants';
+import gettext from 'sources/gettext';
+import _ from 'lodash';
+import clsx from 'clsx';
+import { Box, Grid, List, ListItem, ListSubheader } from '@material-ui/core';
+import url_for from 'sources/url_for';
+import { QueryToolContext, QueryToolEventsContext } from '../QueryToolComponent';
+import moment from 'moment';
+import PlayArrowRoundedIcon from '@material-ui/icons/PlayArrowRounded';
+import AssessmentRoundedIcon from '@material-ui/icons/AssessmentRounded';
+import ExplicitRoundedIcon from '@material-ui/icons/ExplicitRounded';
+import { SaveDataIcon, CommitIcon, RollbackIcon } from '../../../../../../static/js/components/ExternalIcon';
+import { InputSwitch } from '../../../../../../static/js/components/FormComponents';
+import CodeMirror from '../../../../../../static/js/components/CodeMirror';
+import { DefaultButton } from '../../../../../../static/js/components/Buttons';
+import { useDelayedCaller } from '../../../../../../static/js/custom_hooks';
+import Notifier from '../../../../../../static/js/helpers/Notifier';
+import Loader from 'sources/components/Loader';
+import { LayoutEventsContext, LAYOUT_EVENTS } from '../../../../../../static/js/helpers/Layout';
+import PropTypes from 'prop-types';
+import { parseApiError } from '../../../../../../static/js/api_instance';
+import * as clipboard from '../../../../../../static/js/clipboard';
+
+const useStyles = makeStyles((theme)=>({
+ leftRoot: {
+ display: 'flex',
+ flexDirection: 'column',
+ backgroundColor: theme.otherVars.editorToolbarBg,
+ ...theme.mixins.panelBorder.right,
+ },
+ listRoot: {
+ ...theme.mixins.panelBorder.top,
+ },
+ listSubheader: {
+ padding: '0.25rem',
+ lineHeight: 'unset',
+ color: theme.palette.text.muted,
+ backgroundColor: theme.palette.background.default,
+ ...theme.mixins.panelBorder.bottom,
+ ...theme.mixins.fontSourceCode,
+ },
+ removePadding: {
+ padding: 0,
+ },
+ fontSourceCode:{
+ ...theme.mixins.fontSourceCode,
+ userSelect: 'text',
+ },
+ itemError: {
+ backgroundColor: theme.palette.error.light,
+ '&.Mui-selected': {
+ backgroundColor: theme.palette.error.light,
+ '&:hover': {
+ backgroundColor: theme.palette.error.light,
+ }
+ }
+ },
+ detailsQuery: {
+ marginTop: '0.5rem',
+ ...theme.mixins.panelBorder.all,
+ },
+ copyBtn: {
+ borderRadius: 0,
+ paddingLeft: '8px',
+ paddingRight: '8px',
+ borderTop: 'none',
+ borderLeft: 'none',
+ borderColor: theme.otherVars.borderColor,
+ fontSize: '13px',
+ },
+ infoHeader: {
+ fontSize: '13px',
+ padding: '0.5rem',
+ backgroundColor: theme.otherVars.editorToolbarBg,
+ },
+ removeBtnMargin: {
+ marginLeft: '0.25rem',
+ }
+}));
+
+export const QuerySources = {
+ EXECUTE: {
+ ICON_CSS_CLASS: 'fa fa-play',
+ },
+ EXPLAIN: {
+ ICON_CSS_CLASS: 'fa fa-hand-pointer',
+ },
+ EXPLAIN_ANALYZE: {
+ ICON_CSS_CLASS: 'fa fa-list-alt',
+ },
+ COMMIT: {
+ ICON_CSS_CLASS: 'pg-font-icon icon-commit',
+ },
+ ROLLBACK: {
+ ICON_CSS_CLASS: 'pg-font-icon icon-rollback',
+ },
+ SAVE_DATA: {
+ ICON_CSS_CLASS: 'pg-font-icon icon-save_data_changes',
+ },
+ VIEW_DATA: {
+ ICON_CSS_CLASS: 'pg-font-icon icon-view_data',
+ },
+};
+
+
+class QueryHistoryUtils {
+ constructor() {
+ this._entries = [];
+ this.showInternal = true;
+ }
+
+ dateAsGroupKey(date) {
+ return moment(date).format('YYYY MM DD');
+ }
+
+ getItemKey(entry) {
+ return this.dateAsGroupKey(entry.start_time) + this.formatEntryDate(entry.start_time) + (entry.subKey ?? '');
+ }
+
+ getDateFormatted(date) {
+ return date.toLocaleDateString();
+ }
+
+ formatEntryDate(date) {
+ return moment(date).format('HH:mm:ss');
+ }
+
+ isDaysBefore(date, before) {
+ return (
+ this.getDateFormatted(date) ===
+ this.getDateFormatted(moment().subtract(before, 'days').toDate())
+ );
+ }
+
+ getDatePrefix(date) {
+ let prefix = '';
+ if (this.isDaysBefore(date, 0)) {
+ prefix = 'Today - ';
+ } else if (this.isDaysBefore(date, 1)) {
+ prefix = 'Yesterday - ';
+ }
+ return prefix;
+ }
+
+ addEntry(entry) {
+ entry.groupKey = this.dateAsGroupKey(entry.start_time);
+ entry.itemKey = this.getItemKey(entry);
+ let existEntry = _.find(this._entries, (e)=>e.itemKey==entry.itemKey);
+ if(existEntry) {
+ entry.itemKey = this.getItemKey(entry) + _.uniqueId();
+ }
+ let insertIndex = _.sortedIndexBy(this._entries, entry, (e)=>e.itemKey);
+ this._entries = [
+ ...this._entries.slice(0, insertIndex),
+ entry,
+ ...this._entries.slice(insertIndex),
+ ];
+ }
+
+ getEntries() {
+ if(!this.showInternal) {
+ return this._entries.filter((e)=>!e.is_pgadmin_query);
+ }
+ return this._entries;
+ }
+
+ getEntry(itemKey) {
+ return _.find(this.getEntries(), (e)=>e.itemKey==itemKey);
+ }
+
+ getGroupHeader(entry) {
+ return this.getDatePrefix(entry.start_time)+this.getDateFormatted(entry.start_time);
+ }
+
+ getGroups() {
+ return _.sortedUniqBy(this.getEntries().map((e)=>[e.groupKey, this.getGroupHeader(e)]), (g)=>g[0]).reverse();
+ }
+
+ getGroupEntries(groupKey) {
+ return this.getEntries().filter((e)=>e.groupKey==groupKey).reverse();
+ }
+
+ getNextItemKey(currKey) {
+ let nextIndex = this.getEntries().length-1;
+ if(currKey) {
+ let currIndex = _.findIndex(this.getEntries(), (e)=>e.itemKey==currKey);
+ if(currIndex == 0) {
+ nextIndex = currIndex;
+ } else {
+ nextIndex = currIndex - 1;
+ }
+ }
+ return this.getEntries()[nextIndex]?.itemKey;
+ }
+
+ getPrevItemKey(currKey) {
+ let nextIndex = this.getEntries().length-1;
+ if(currKey) {
+ let currIndex = _.findIndex(this.getEntries(), (e)=>e.itemKey==currKey);
+ if(currIndex == this.getEntries().length-1) {
+ nextIndex = currIndex;
+ } else {
+ nextIndex = currIndex + 1;
+ }
+ }
+ return this.getEntries()[nextIndex]?.itemKey;
+ }
+
+ clear(itemKey) {
+ if(itemKey) {
+ let nextKey = this.getNextItemKey(itemKey);
+ let removeIdx = _.findIndex(this._entries, (e)=>e.itemKey==itemKey);
+ this._entries.splice(removeIdx, 1);
+ return nextKey;
+ } else {
+ this._entries = [];
+ }
+ }
+
+ size() {
+ return this._entries.length;
+ }
+}
+
+function QuerySourceIcon({source}) {
+ switch(JSON.stringify(source)) {
+ case JSON.stringify(QuerySources.EXECUTE):
+ return ;
+ case JSON.stringify(QuerySources.EXPLAIN):
+ return ;
+ case JSON.stringify(QuerySources.EXPLAIN_ANALYZE):
+ return ;
+ case JSON.stringify(QuerySources.COMMIT):
+ return ;
+ case JSON.stringify(QuerySources.ROLLBACK):
+ return ;
+ case JSON.stringify(QuerySources.SAVE_DATA):
+ return ;
+ case JSON.stringify(QuerySources.VIEW_DATA):
+ return ;
+ default:
+ return <>>;
+ }
+}
+QuerySourceIcon.propTypes = {
+ source: PropTypes.object,
+};
+
+function HistoryEntry({entry, formatEntryDate, itemKey, selectedItemKey, onClick}) {
+ const classes = useStyles();
+ return {
+ selectedItemKey==itemKey && ele && ele.scrollIntoView({
+ block: 'center',
+ behavior: 'smooth',
+ });
+ }} className={clsx(classes.fontSourceCode, entry.status ? '' : classes.itemError)} selected={selectedItemKey==itemKey} onClick={onClick}>
+
+
+ {entry.query}
+
+
+ {formatEntryDate(entry.start_time)}
+
+ ;
+}
+
+const EntryPropType = PropTypes.shape({
+ info: PropTypes.string,
+ status: PropTypes.bool,
+ start_time: PropTypes.objectOf(Date),
+ query: PropTypes.string,
+ row_affected: PropTypes.number,
+ total_time: PropTypes.string,
+ message: PropTypes.string,
+ query_source: PropTypes.object,
+ is_pgadmin_query: PropTypes.bool,
+});
+HistoryEntry.propTypes = {
+ entry: EntryPropType,
+ formatEntryDate: PropTypes.func,
+ itemKey: PropTypes.string,
+ selectedItemKey: PropTypes.string,
+ onClick: PropTypes.func,
+};
+
+function QueryHistoryDetails({entry}) {
+ const classes = useStyles();
+ const [copyText, setCopyText] = React.useState(gettext('Copy'));
+ const eventBus = React.useContext(QueryToolEventsContext);
+ const revertCopiedText = useDelayedCaller(()=>{
+ setCopyText(gettext('Copy'));
+ });
+
+ const onCopyClick = React.useCallback(()=>{
+ clipboard.copyToClipboard(entry.query);
+ setCopyText(gettext('Copied!'));
+ revertCopiedText(1500);
+ }, [entry]);
+
+ const onCopyToEditor = React.useCallback(()=>{
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.COPY_TO_EDITOR, entry.query);
+ }, [entry]);
+
+ if(!entry) {
+ return <>>;
+ }
+
+ return (
+ <>
+ {entry.info && {entry.info} }
+
+
+ {entry.start_time.toLocaleDateString() + ' ' + entry.start_time.toLocaleTimeString()}
+ {entry?.row_affected > 0 && entry.row_affected}
+ {entry.total_time}
+
+
+ {gettext('Date')}
+ {gettext('Rows affected')}
+ {gettext('Duration')}
+
+
+ {copyText}
+ {gettext('Copy to Query Editor')}
+
+
+
+ {gettext('Messages')}
+ {entry.message}
+
+
+ >
+ );
+}
+
+QueryHistoryDetails.propTypes = {
+ entry: EntryPropType,
+};
+
+export function QueryHistory() {
+ const qhu = React.useRef(new QueryHistoryUtils());
+ const queryToolCtx = React.useContext(QueryToolContext);
+ const classes = useStyles();
+ const eventBus = React.useContext(QueryToolEventsContext);
+ const [selectedItemKey, setSelectedItemKey] = React.useState(1);
+ const [showInternal, setShowInternal] = React.useState(true);
+ const [loaderText, setLoaderText] = React.useState('');
+ const [,refresh] = React.useState({});
+ const selectedEntry = qhu.current.getEntry(selectedItemKey);
+ const layoutEvenBus = React.useContext(LayoutEventsContext);
+ const listRef = React.useRef();
+
+ React.useEffect(async ()=>{
+ layoutEvenBus.registerListener(LAYOUT_EVENTS.ACTIVE, (currentTabId)=>{
+ currentTabId == PANELS.HISTORY && listRef.current.focus();
+ });
+
+ setLoaderText(gettext('Fetching history...'));
+ try {
+ let {data: respData} = await queryToolCtx.api.get(url_for('sqleditor.get_query_history', {
+ 'trans_id': queryToolCtx.params.trans_id,
+ }));
+ respData.data.result.forEach((h)=>{
+ h = JSON.parse(h);
+ h.start_time_orig = h.start_time;
+ h.start_time = new Date(h.start_time);
+ qhu.current.addEntry(h);
+ });
+ setSelectedItemKey(qhu.current.getNextItemKey());
+ } catch (error) {
+ console.error(error);
+ Notifier.error(gettext('Failed to fetch query history.') + parseApiError(error));
+ }
+ setLoaderText('');
+
+ const pushHistory = (h)=>{
+ qhu.current.addEntry(h);
+ refresh({});
+ };
+
+ listRef.current.focus();
+ eventBus.registerListener(QUERY_TOOL_EVENTS.PUSH_HISTORY, pushHistory);
+ return ()=>eventBus.deregisterListener(QUERY_TOOL_EVENTS.PUSH_HISTORY, pushHistory);
+ }, []);
+
+ const onRemove = async ()=>{
+ setLoaderText(gettext('Removing history entry...'));
+ try {
+ await queryToolCtx.api.delete(url_for('sqleditor.clear_query_history', {
+ 'trans_id': queryToolCtx.params.trans_id,
+ }), {
+ data: {
+ query: selectedEntry.query,
+ start_time: selectedEntry.start_time,
+ }
+ });
+ setSelectedItemKey(qhu.current.clear(selectedItemKey));
+ } catch (error) {
+ console.error(error);
+ Notifier.error(gettext('Failed to remove query history.') + parseApiError(error));
+ }
+ setLoaderText('');
+ };
+
+ const onRemoveAll = React.useCallback(()=>{
+ queryToolCtx.modal.confirm(gettext('Clear history'),
+ gettext('Are you sure you wish to clear the history?') + '' +
+ gettext('This will remove all of your query history from this and other sessions for this database.'),
+ async function() {
+ setLoaderText(gettext('Removing history...'));
+ try {
+ await queryToolCtx.api.delete(url_for('sqleditor.clear_query_history', {
+ 'trans_id': queryToolCtx.params.trans_id,
+ }));
+ qhu.current.clear();
+ setSelectedItemKey(null);
+ } catch (error) {
+ console.error(error);
+ Notifier.error(gettext('Failed to remove query history.') + parseApiError(error));
+ }
+ setLoaderText('');
+ },
+ function() {
+ return true;
+ }
+ );
+
+ }, []);
+
+ const onKeyPressed = (e) => {
+ if (e.keyCode == '38') {
+ e.preventDefault();
+ setSelectedItemKey(qhu.current.getPrevItemKey(selectedItemKey));
+ } else if (e.keyCode == '40') {
+ e.preventDefault();
+ setSelectedItemKey(qhu.current.getNextItemKey(selectedItemKey));
+ }
+ };
+
+ return (
+ <>
+
+ {React.useMemo(()=>(
+
+
+
+ {gettext('Show queries generated internally by pgAdmin?')}
+ {
+ setShowInternal(e.target.checked);
+ qhu.current.showInternal = e.target.checked;
+ setSelectedItemKey(qhu.current.getNextItemKey());
+ }} />
+
+ Remove
+ Remove All
+
+
+
+
} tabIndex="0" onKeyDown={onKeyPressed}>
+ {qhu.current.getGroups().map(([groupKey, groupHeader]) => (
+
+
+ {groupHeader}
+ {qhu.current.getGroupEntries(groupKey).map((entry) => (
+ {setSelectedItemKey(entry.itemKey);}}/>
+ ))}
+
+
+ ))}
+
+
+
+
+
+
+
+ ), [selectedItemKey, showInternal, qhu.current.size()])}
+ >
+ );
+}
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSet.jsx b/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSet.jsx
new file mode 100644
index 000000000..ee5b2245a
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSet.jsx
@@ -0,0 +1,1225 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import _ from 'lodash';
+import React, { useContext, useEffect, useRef, useState } from 'react';
+import QueryToolDataGrid, { GRID_ROW_SELECT_KEY } from '../QueryToolDataGrid';
+import {CONNECTION_STATUS, PANELS, QUERY_TOOL_EVENTS} from '../QueryToolConstants';
+import url_for from 'sources/url_for';
+import getApiInstance, { parseApiError } from '../../../../../../static/js/api_instance';
+import { QueryToolContext, QueryToolEventsContext } from '../QueryToolComponent';
+import gettext from 'sources/gettext';
+import Loader from 'sources/components/Loader';
+import { Box } from '@material-ui/core';
+import { ResultSetToolbar } from './ResultSetToolbar';
+import { LayoutHelper } from '../../../../../../static/js/helpers/Layout';
+import { GeometryViewer } from './GeometryViewer';
+import Explain from '../../../../../../static/js/Explain';
+import Notifier from '../../../../../../static/js/helpers/Notifier';
+import { QuerySources } from './QueryHistory';
+import { getBrowser } from '../../../../../../static/js/utils';
+import CopyData from '../QueryToolDataGrid/CopyData';
+import moment from 'moment';
+import ConfirmSaveContent from '../dialogs/ConfirmSaveContent';
+import { makeStyles } from '@material-ui/styles';
+import EmptyPanelMessage from '../../../../../../static/js/components/EmptyPanelMessage';
+
+export class ResultSetUtils {
+ constructor(api, transId, isQueryTool=true) {
+ this.api = api;
+ this.transId = transId;
+ this.startTime = new Date();
+ this.clientPK = null;
+ this.isQueryTool = isQueryTool;
+ this.clientPKLastIndex = 0;
+ this.historyQuerySource = null;
+ }
+
+ static generateURLReconnectionFlag(baseUrl, transId, shouldReconnect) {
+ let url = url_for(baseUrl, {
+ 'trans_id': transId,
+ });
+
+ if (shouldReconnect) {
+ url += '?connect=1';
+ }
+ return url;
+ }
+
+ static prepareAnalyzeSql(sqlStatement, analyzeSql) {
+ return {
+ sql: sqlStatement,
+ explain_plan: analyzeSql,
+ };
+ }
+
+ static wasConnectionLostToPythonServer(httpResponse) {
+ return _.isUndefined(httpResponse) || _.isUndefined(httpResponse.data);
+ }
+
+ static wasDatabaseConnectionLost(httpMessage) {
+ return httpMessage.response.status === 503 &&
+ httpMessage.response.data.info !== undefined &&
+ httpMessage.response.data.info === 'CONNECTION_LOST';
+ }
+
+ static isCryptKeyMissing(httpMessage) {
+ return httpMessage.response.status === 503 &&
+ httpMessage.response.data.info !== undefined &&
+ httpMessage.response.data.info === 'CRYPTKEY_MISSING';
+ }
+
+ static isSqlCorrect(httpMessageData) {
+ return httpMessageData.data.status;
+ }
+
+ static extractErrorMessage(httpMessage) {
+ let msg = httpMessage.errormsg;
+ if (httpMessage.responseJSON !== undefined &&
+ httpMessage.responseJSON.errormsg !== undefined)
+ msg = httpMessage.responseJSON.errormsg;
+
+ return msg;
+ }
+
+ static isQueryFinished(httpMessage) {
+ return httpMessage.data.data.status === 'Success';
+ }
+
+ static isQueryStillRunning(httpMessage) {
+ return httpMessage.data.data.status === 'Busy';
+ }
+
+ static isQueryCancelled(httpMessage) {
+ return httpMessage.data.data.status === 'Cancel';
+ }
+
+ static isConnectionToServerLostWhilePolling(httpMessage) {
+ return httpMessage.data.data.status === 'NotConnected';
+ }
+
+ setStartTime(start) {
+ this.startTime = start;
+ }
+
+ setEndTime(end) {
+ this.endTime = end;
+ }
+
+ queryRunTime() {
+ let total_ms = moment(this.endTime).diff(this.startTime);
+ let result = '';
+ let secs, mins, hrs;
+
+ /* Extract seconds from millisecs */
+ secs = parseInt(total_ms/1000);
+ total_ms = total_ms%1000;
+
+ /* Extract mins from seconds */
+ mins = parseInt(secs/60);
+ secs = secs%60;
+
+ /* Extract hrs from mins */
+ hrs = parseInt(mins/60);
+ mins = mins%60;
+
+ result = (hrs>0 ? hrs + ' ' + gettext('hr') + ' ': '')
+ + (mins>0 ? mins + ' ' + gettext('min') + ' ': '')
+ + (hrs<=0 && secs>0 ? secs + ' ' + gettext('secs') + ' ': '')
+ + (hrs<=0 && mins<=0 ? total_ms + ' ' + gettext('msec') + ' ':'');
+ return result.trim();
+ }
+
+ setEventBus(eventBus) {
+ this.eventBus = eventBus;
+ }
+
+ setStartData(data) {
+ this.startData = data;
+ }
+
+ resetClientPKIndex() {
+ this.clientPKLastIndex = 0;
+ }
+
+ setClientPK(clientPK) {
+ this.clientPK = clientPK || GRID_ROW_SELECT_KEY;
+ }
+
+ hasResultsToDisplay(res) {
+ return res.colinfo != null;
+ }
+
+ isAtBottom({ currentTarget }) {
+ return currentTarget.scrollTop + 10 >= currentTarget.scrollHeight - currentTarget.clientHeight;
+ }
+
+ postExecutionApi(query, explainObject, isQueryTool=true, reconnect=false) {
+ if(isQueryTool) {
+ return this.api.post(
+ ResultSetUtils.generateURLReconnectionFlag('sqleditor.query_tool_start', this.transId, reconnect),
+ JSON.stringify({
+ sql: query,
+ explain_plan: explainObject,
+ })
+ );
+ } else {
+ return this.api.get(
+ ResultSetUtils.generateURLReconnectionFlag('sqleditor.view_data_start', this.transId, reconnect)
+ );
+ }
+ }
+
+ async startExecution(query, explainObject, onIncorrectSQL, flags={
+ isQueryTool: true, external: false, reconnect: false,
+ }) {
+ let startTime = new Date();
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.SET_MESSAGE, '');
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.TASK_START, gettext('Waiting for the query to complete...'), startTime);
+ this.setStartTime(startTime);
+ this.query = query;
+ this.historyQuerySource = flags.isQueryTool ? QuerySources.EXECUTE : QuerySources.VIEW_DATA;
+ if(explainObject) {
+ if(explainObject.analyze) {
+ this.historyQuerySource = QuerySources.EXPLAIN_ANALYZE;
+ } else {
+ this.historyQuerySource = QuerySources.EXPLAIN;
+ }
+ } else if(query == 'COMMIT;') {
+ this.historyQuerySource = QuerySources.COMMIT;
+ } else if(query == 'ROLLBACK;') {
+ this.historyQuerySource = QuerySources.ROLLBACK;
+ }
+ try {
+ let {data: httpMessageData} = await this.postExecutionApi(query, explainObject, flags.isQueryTool, flags.reconnect);
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.SET_CONNECTION_STATUS, httpMessageData.data.transaction_status);
+
+ if (ResultSetUtils.isSqlCorrect(httpMessageData)) {
+ this.setStartData(httpMessageData.data);
+ if(!flags.isQueryTool) {
+ this.query = httpMessageData.data.sql;
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.SET_FILTER_INFO, httpMessageData.data.can_filter, httpMessageData.data.filter_applied);
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.SET_LIMIT_VALUE, httpMessageData.data.limit);
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.EDITOR_SET_SQL, httpMessageData.data.sql, false);
+ }
+ return true;
+ } else {
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.EXECUTION_END);
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.SET_MESSAGE, httpMessageData.data.result);
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.FOCUS_PANEL, PANELS.MESSAGES);
+ onIncorrectSQL();
+ this.resetClientPKIndex();
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.PUSH_HISTORY, {
+ status: false,
+ start_time: this.startTime,
+ query: this.query,
+ row_affected: null,
+ total_time: null,
+ message: httpMessageData.data.result,
+ query_source: this.historyQuerySource,
+ is_pgadmin_query: false,
+ });
+ if(!flags.external) {
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.HIGHLIGHT_ERROR, httpMessageData.data.result);
+ }
+ }
+ if(httpMessageData.data.notifies) {
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.PUSH_NOTICE, httpMessageData.data.notifies);
+ }
+ } catch(e) {
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.EXECUTION_END);
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.HANDLE_API_ERROR,
+ e,
+ {
+ connectionLostCallback: ()=>{
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.EXECUTION_START, query, explainObject, flags.external, true);
+ },
+ checkTransaction: true,
+ }
+ );
+ }
+ return false;
+ }
+
+ poll() {
+ let delay = 1;
+ var seconds = parseInt((Date.now() - this.startTime.getTime()) / 1000);
+ // calculate & return fall back polling timeout
+ if (seconds >= 10 && seconds < 30) {
+ delay = 500;
+ } else if (seconds >= 30 && seconds < 60) {
+ delay = 1000;
+ } else if (seconds >= 60 && seconds < 90) {
+ delay = 2000;
+ } else if (seconds >= 90) {
+ delay = 5000;
+ } else {
+ delay = 1;
+ }
+
+ return new Promise((resolve)=>{
+ setTimeout(() => {
+ resolve(this.api.get(
+ url_for('sqleditor.poll', {
+ 'trans_id': this.transId,
+ })
+ ));
+ }, delay);
+ });
+ }
+
+ handlePollError(error) {
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.EXECUTION_END);
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.FOCUS_PANEL, PANELS.MESSAGES);
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.SET_CONNECTION_STATUS, CONNECTION_STATUS.TRANSACTION_STATUS_INERROR);
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.PUSH_HISTORY, {
+ status: false,
+ start_time: this.startTime,
+ query: this.query,
+ row_affected: null,
+ total_time: this.queryRunTime(),
+ message: parseApiError(error, false),
+ query_source: this.historyQuerySource,
+ is_pgadmin_query: false,
+ });
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.HANDLE_API_ERROR, error);
+ }
+
+ async pollForResult(onResultsAvailable, onExplain, onPollError) {
+ try {
+ let httpMessage = await this.poll();
+ let msg = '';
+ if(httpMessage.data.data.notifies) {
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.PUSH_NOTICE, httpMessage.data.data.notifies);
+ }
+ if (ResultSetUtils.isQueryFinished(httpMessage)) {
+ msg = this.queryFinished(httpMessage, onResultsAvailable, onExplain);
+ } else if (ResultSetUtils.isQueryStillRunning(httpMessage)) {
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.SET_CONNECTION_STATUS, httpMessage.data.data.transaction_status);
+ if(httpMessage.data.data.result) {
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.SET_MESSAGE, httpMessage.data.data.result, true);
+ }
+ return Promise.resolve(this.pollForResult(onResultsAvailable, onExplain, onPollError));
+ } else if (ResultSetUtils.isConnectionToServerLostWhilePolling(httpMessage)) {
+ msg = httpMessage.data.data.result;
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.SET_MESSAGE, msg, true);
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.EXECUTION_END);
+ } else if (ResultSetUtils.isQueryCancelled(httpMessage)) {
+ msg = httpMessage.data.data.result || 'Execution Cancelled!';
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.SET_MESSAGE, httpMessage.data.data.result || 'Execution Cancelled!', true);
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.EXECUTION_END);
+ }
+ Notifier.success(msg);
+ if(!ResultSetUtils.isQueryStillRunning(httpMessage)) {
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.PUSH_HISTORY, {
+ status: true,
+ start_time: this.startTime,
+ query: this.query,
+ row_affected: httpMessage.data.data?.rows_affected,
+ total_time: this.queryRunTime(),
+ message: msg,
+ query_source: this.historyQuerySource,
+ is_pgadmin_query: false,
+ });
+ }
+ } catch (error) {
+ onPollError();
+ this.handlePollError(error);
+ }
+ }
+
+ getMoreRows(all=false) {
+ let url = url_for('sqleditor.fetch', {
+ 'trans_id': this.transId,
+ });
+ if(all) {
+ url = url_for('sqleditor.fetch_all', {
+ 'trans_id': this.transId,
+ 'fetch_all': 1,
+ });
+ }
+ return this.api.get(url);
+ }
+
+ stopExecution() {
+ return this.api.post(
+ url_for('sqleditor.cancel_transaction', {'trans_id': this.transId})
+ );
+ }
+
+ saveData(reqData) {
+ return this.api.post(
+ url_for('sqleditor.save', {
+ 'trans_id': this.transId
+ }),
+ JSON.stringify(reqData)
+ );
+ }
+
+ async saveResultsToFile(fileName) {
+ try {
+ let {data: respData} = await this.api.post(
+ url_for('sqleditor.query_tool_download', {
+ 'trans_id': this.transId,
+ }),
+ {filename: fileName}
+ );
+
+ if(!_.isUndefined(respData.data)) {
+ if(!respData.status) {
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.SET_MESSAGE, respData.data.result);
+ }
+ } else {
+ let respBlob = new Blob([respData], {type : 'text/csv'}),
+ urlCreator = window.URL || window.webkitURL,
+ download_url = urlCreator.createObjectURL(respBlob),
+ link = document.createElement('a');
+
+ document.body.appendChild(link);
+
+ if (getBrowser() === 'IE' && window.navigator.msSaveBlob) {
+ // IE10+ : (has Blob, but not a[download] or URL)
+ window.navigator.msSaveBlob(respBlob, fileName);
+ } else {
+ link.setAttribute('href', download_url);
+ link.setAttribute('download', fileName);
+ link.click();
+ }
+ document.body.removeChild(link);
+ }
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_SAVE_RESULTS_END);
+ } catch (error) {
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_SAVE_RESULTS_END);
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.HANDLE_API_ERROR, error);
+ }
+ }
+
+ includeFilter(reqData) {
+ return this.api.post(
+ url_for('sqleditor.inclusive_filter', {
+ 'trans_id': this.transId,
+ }),
+ JSON.stringify(reqData)
+ );
+ }
+
+ excludeFilter(reqData) {
+ return this.api.post(
+ url_for('sqleditor.exclusive_filter', {
+ 'trans_id': this.transId,
+ }),
+ JSON.stringify(reqData)
+ );
+ }
+
+ removeFilter() {
+ return this.api.post(
+ url_for('sqleditor.remove_filter', {
+ 'trans_id': this.transId,
+ })
+ );
+ }
+
+ setLimit(limit) {
+ return this.api.post(
+ url_for('sqleditor.set_limit', {
+ 'trans_id': this.transId,
+ }), JSON.stringify(parseInt(limit))
+ );
+ }
+
+ getFinalColumn(c, isEditable, isPK, pgTypesOidMap) {
+ let columnTypeInternal = pgTypesOidMap[c.type_code] || 'unknown';
+ let columnType = (isPK ? '[PK] ' : '') + columnTypeInternal;
+ let cellType;
+
+ if (c.precision && c.precision >= 0 && c.precision != 65535) {
+ columnType += ' (' + c.precision;
+ columnType += c.scale && c.scale != 65535 ?
+ ',' + c.scale + ')' :
+ ')';
+ }
+ // Identify cell type of column.
+ switch (columnTypeInternal) {
+ case 'oid':
+ cellType = 'oid';
+ break;
+ case 'json':
+ case 'json[]':
+ case 'jsonb':
+ case 'jsonb[]':
+ cellType = 'Json';
+ break;
+ case 'smallint':
+ case 'smallint[]':
+ case 'integer':
+ case 'integer[]':
+ case 'bigint':
+ case 'bigint[]':
+ case 'decimal':
+ case 'decimal[]':
+ case 'numeric':
+ case 'numeric[]':
+ case 'real':
+ case 'real[]':
+ case 'double precision':
+ case 'double precision[]':
+ cellType = 'number';
+ break;
+ case 'boolean':
+ cellType = 'boolean';
+ break;
+ case 'character':
+ case 'character[]':
+ case '"char"':
+ case '"char"[]':
+ case 'character varying':
+ case 'character varying[]':
+ if (c.internal_size && c.internal_size >= 0 && c.internal_size != 65535) {
+ // Update column type to display length on column header
+ columnType += ' (' + c.internal_size + ')';
+ }
+ cellType = 'string';
+ break;
+ case 'bytea':
+ case 'bytea[]':
+ cellType = 'binary';
+ break;
+ case 'geometry':
+ // PostGIS geometry type
+ cellType = 'geometry';
+ isEditable = false;
+ break;
+ case 'geography':
+ // PostGIS geography type
+ cellType = 'geography';
+ isEditable = false;
+ break;
+ default:
+ cellType = 'string';
+ }
+
+ let arrayBracketIdx = columnTypeInternal.lastIndexOf('[]');
+ return {
+ 'key': c.name,
+ 'name': c.name,
+ 'display_name': c.display_name,
+ 'type': columnTypeInternal,
+ 'display_type': columnType,
+ 'column_type_internal': columnTypeInternal,
+ 'pos': c.pos,
+ 'cell': cellType,
+ 'can_edit': (c.name == 'oid') ? false : isEditable,
+ 'not_null': c.not_null,
+ 'has_default_val': c.has_default_val,
+ 'is_array': arrayBracketIdx > -1 && arrayBracketIdx + 2 == columnTypeInternal.length,
+ };
+ }
+
+ processColumns(data) {
+ let columns = [];
+ let self = this;
+
+ let pgTypesOidMap = {};
+ _.isArray(data.types) && data.types?.forEach((t)=>{
+ pgTypesOidMap[t.oid] = t.typname;
+ });
+
+ // Create columns
+ data.colinfo.forEach(function(c) {
+ var isPK = false,
+ isEditable = data.can_edit && (!self.isQueryTool || c.is_editable);
+
+ // Check whether this column is a primary key
+ if (isEditable) {
+ isPK = _.some(data.primary_keys||[], (_v, key)=>key === c.name);
+ }
+
+ // Create column label and type.
+ columns.push(self.getFinalColumn(c, isEditable, isPK, pgTypesOidMap));
+ });
+
+ return columns;
+ }
+
+ processClipboardVal(columnVal, col) {
+ if(columnVal === '') {
+ if(col.has_default_val) {
+ columnVal = undefined;
+ }
+ }
+ if(col.cell === 'boolean') {
+ if(columnVal == 'true') {
+ columnVal = true;
+ } else if(columnVal == 'false') {
+ columnVal = false;
+ } else {
+ columnVal = null;
+ }
+ }
+ return columnVal;
+ }
+
+ processRows(result, columns, fromClipboard=false) {
+ let retVal = [];
+ if(!_.isArray(result) || !_.size(result)) {
+ return retVal;
+ }
+ for(const rec of result) {
+ // Convert 2darray to dict.
+ let rowObj = {};
+ for(const col of columns) {
+ let columnVal = rec[col.pos];
+ /* If the source is clipboard, then it needs some extra handling */
+ if(fromClipboard) {
+ columnVal = this.processClipboardVal(columnVal, col);
+ }
+ rowObj[col.key] = columnVal;
+ }
+ /* This will used for uniquely identifying selected rows */
+ rowObj[this.clientPK] = this.clientPKLastIndex.toString();
+ retVal.push(rowObj);
+ this.clientPKLastIndex++;
+ }
+ return retVal;
+ }
+
+ getPlanJson(result, data) {
+ if(result && !_.isEmpty(data.colinfo)
+ && data.colinfo[0].name == 'QUERY PLAN' && !_.isEmpty(data.types)
+ && data.types[0] && data.types[0].typname === 'json') {
+ /* json is sent as text, parse it */
+ let planJson = JSON.parse(data.result[0][0]);
+ if (planJson && planJson[0] && planJson[0].hasOwnProperty('Plan') &&
+ _.isObject(planJson[0]['Plan'])
+ ) {
+ return planJson;
+ }
+ }
+ return null;
+ }
+
+ queryFinished(httpMessage, onResultsAvailable, onExplain) {
+ let msg;
+ let endTime = new Date();
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.EXECUTION_END, true);
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.SET_CONNECTION_STATUS, httpMessage.data.data.transaction_status);
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.TASK_END, gettext('Query complete'), endTime);
+ this.setEndTime(endTime);
+
+ msg = gettext('Query returned successfully in %s.', this.queryRunTime());
+ if(this.hasResultsToDisplay(httpMessage.data.data)) {
+ if(!_.isNull(httpMessage.data.data.additional_messages)){
+ msg = httpMessage.data.data.additional_messages + '\n' + msg;
+ }
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.SET_MESSAGE, msg);
+ this.setClientPK(httpMessage.data.data.client_primary_key);
+ let {result} = httpMessage.data.data;
+ let data = {
+ ...this.startData,
+ ...httpMessage.data.data,
+ };
+ data.primary_keys = (_.isEmpty(data.primary_keys) && data.has_oids) ? data.oids : data.primary_keys;
+ data.can_edit = !_.isEmpty(data.primary_keys);
+ let procColumns = this.processColumns(data);
+ onResultsAvailable(data, procColumns, this.processRows(result, procColumns, this.processRows(result, procColumns)));
+ this.setStartData(null);
+ let planJson = this.getPlanJson(result, data);
+ if(planJson) {
+ onExplain(planJson);
+ } else {
+ onExplain(null);
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.FOCUS_PANEL, PANELS.DATA_OUTPUT);
+ }
+ } else {
+ if (httpMessage.data.data.result) {
+ msg = httpMessage.data.data.result + '\n\n' + msg;
+ }
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.SET_MESSAGE, msg, true);
+ this.eventBus.fireEvent(QUERY_TOOL_EVENTS.FOCUS_PANEL, PANELS.MESSAGES);
+ }
+ return msg;
+ }
+}
+
+function dataChangeReducer(state, action) {
+ let dataChange = _.clone(state);
+ let count;
+ switch (action.type) {
+ case 'updated':
+ dataChange.updated[action.clientPK] = {
+ ...dataChange.updated[action.clientPK],
+ ...action.payload,
+ data: {
+ ...dataChange.updated[action.clientPK]?.data,
+ ...action.payload.data,
+ }
+ };
+ break;
+ case 'added':
+ action.add = action.add || {};
+ action.remove = action.remove || [];
+ dataChange.added = _.pickBy(dataChange.added, (_v, k)=>(action.remove.indexOf(k) == -1));
+ dataChange.added_index = _.pickBy(dataChange.added_index, (v)=>(action.remove.indexOf(v) == -1));
+ count = _.max(Object.keys(dataChange.added_index))||0;
+ Object.keys(action.add).forEach((k)=>{
+ dataChange.added_index[++count] = k;
+ });
+ dataChange.added = {
+ ...dataChange.added,
+ ...action.add,
+ };
+ break;
+ case 'deleted':
+ dataChange.deleted = _.pickBy(dataChange.deleted, (_v, k)=>(action.remove.indexOf(k) == -1));
+ dataChange.deleted = {
+ ...dataChange.deleted,
+ ...action.add,
+ };
+ break;
+ case 'reset':
+ dataChange = {
+ updated: {},
+ added: {},
+ added_index: {},
+ deleted: {},
+ };
+ break;
+ default:
+ break;
+ }
+
+ return dataChange;
+}
+
+const useStyles = makeStyles((theme)=>({
+ root: {
+ display: 'flex',
+ height: '100%',
+ flexDirection: 'column',
+ backgroundColor: theme.otherVars.qtDatagridBg,
+ }
+}));
+
+export function ResultSet() {
+ const classes = useStyles();
+ const containerRef = React.useRef(null);
+ const eventBus = useContext(QueryToolEventsContext);
+ const queryToolCtx = useContext(QueryToolContext);
+ const [loaderText, setLoaderText] = useState('');
+ const [queryData, setQueryData] = useState(null);
+ const [rows, setRows] = useState([]);
+ const [columns, setColumns] = useState([]);
+ const [isLoadingMore, setIsLoadingMore] = useState(false);
+ const api = getApiInstance();
+ const rsu = React.useRef(new ResultSetUtils(api, queryToolCtx.params.trans_id, queryToolCtx.params.is_query_tool));
+ const [dataChangeStore, dispatchDataChange] = React.useReducer(dataChangeReducer, {});
+ const [selectedRows, setSelectedRows] = useState(new Set());
+ const [selectedColumns, setSelectedColumns] = useState(new Set());
+ const selectedCell = useRef([]);
+ const setSelectedCell = (val)=>selectedCell.current=val;
+ const [rowsResetKey, setRowsResetKey] = useState(true);
+
+ rsu.current.setEventBus(eventBus);
+
+ const executionStartCallback = async (query, explainObject, external=false, reconnect=false)=>{
+ /* Reset */
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.HIGHLIGHT_ERROR, null);
+ dispatchDataChange({type: 'reset'});
+ setSelectedRows(new Set());
+ setSelectedColumns(new Set());
+ setLoaderText(gettext('Waiting for the query to complete...'));
+ let goForPoll = await rsu.current.startExecution(
+ query, explainObject,
+ ()=>{
+ setColumns([]);
+ setRows([]);
+ },
+ {isQueryTool: queryToolCtx.params.is_query_tool, external: external, reconnect: reconnect}
+ );
+ if(goForPoll) {
+ rsu.current.pollForResult(
+ (procQueryData, procColumns, procRows)=>{
+ setQueryData(procQueryData);
+ setColumns(procColumns);
+ setRows(procRows);
+ setRowsResetKey(!rowsResetKey);
+ },
+ (planJson)=>{
+ /* No need to open if plan is empty */
+ if(!LayoutHelper.isTabOpen(queryToolCtx.docker, PANELS.EXPLAIN) && !planJson) {
+ return;
+ }
+ LayoutHelper.openTab(queryToolCtx.docker, {
+ id: PANELS.EXPLAIN,
+ title:'Explain',
+ content: ,
+ closable: true,
+ }, PANELS.MESSAGES, 'after-tab', true);
+ },
+ ()=>{
+ setColumns([]);
+ setRows([]);
+ }
+ );
+ }
+ };
+
+ useEffect(()=>{
+ eventBus.registerListener(QUERY_TOOL_EVENTS.TRIGGER_STOP_EXECUTION, async ()=>{
+ try {
+ await rsu.current.stopExecution();
+ } catch(e) {
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.HANDLE_API_ERROR, e);
+ }
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.SET_CONNECTION_STATUS, CONNECTION_STATUS.TRANSACTION_STATUS_IDLE);
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.EXECUTION_END);
+ });
+
+ eventBus.registerListener(QUERY_TOOL_EVENTS.EXECUTION_END, ()=>{
+ setLoaderText(null);
+ });
+
+ eventBus.registerListener(QUERY_TOOL_EVENTS.TRIGGER_SAVE_RESULTS, ()=>{
+ let extension = queryToolCtx.preferences?.sqleditor?.csv_field_separator === ',' ? '.csv': '.txt';
+ let fileName = 'data-' + new Date().getTime() + extension;
+ if(!queryToolCtx.params.is_query_tool) {
+ fileName = queryToolCtx.params.node_name + extension;
+ }
+ setLoaderText(gettext('Downloading results...'));
+ rsu.current.saveResultsToFile(fileName);
+ setLoaderText('');
+ });
+
+ eventBus.registerListener(QUERY_TOOL_EVENTS.TRIGGER_SET_LIMIT, async (limit)=>{
+ setLoaderText(gettext('Setting the limit on the result...'));
+ try {
+ await rsu.current.setLimit(limit);
+ setLoaderText('');
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_EXECUTION);
+ } catch(err) {
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.HANDLE_API_ERROR, err, {
+ checkTransaction: true,
+ });
+ setLoaderText('');
+ }
+ });
+
+ eventBus.registerListener(QUERY_TOOL_EVENTS.TRIGGER_REMOVE_FILTER, async ()=>{
+ setLoaderText(gettext('Removing the filter...'));
+ try {
+ await rsu.current.removeFilter();
+ setLoaderText('');
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_EXECUTION);
+ } catch(err) {
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.HANDLE_API_ERROR, err, {
+ checkTransaction: true,
+ });
+ setLoaderText('');
+ }
+ });
+ }, []);
+
+ useEffect(()=>{
+ eventBus.registerListener(QUERY_TOOL_EVENTS.EXECUTION_START, executionStartCallback);
+ return ()=>{
+ eventBus.deregisterListener(QUERY_TOOL_EVENTS.EXECUTION_START, executionStartCallback);
+ };
+ }, [queryToolCtx.docker]);
+
+ useEffect(()=>{
+ const triggerFilter = async (include)=>{
+ if(_.isEmpty(selectedCell.current)) {
+ return;
+ }
+ setLoaderText(gettext('Applying the new filter...'));
+ try {
+ let data = {
+ [selectedCell.current[1].key]: selectedCell.current[0][selectedCell.current[1].key],
+ };
+ if(include) {
+ await rsu.current.includeFilter(data);
+ } else {
+ await rsu.current.excludeFilter(data);
+ }
+ setSelectedCell([]);
+ setLoaderText('');
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_EXECUTION);
+ } catch(err) {
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.HANDLE_API_ERROR, err, {
+ checkTransaction: true,
+ });
+ setLoaderText('');
+ }
+ };
+ eventBus.registerListener(QUERY_TOOL_EVENTS.TRIGGER_INCLUDE_EXCLUDE_FILTER, triggerFilter);
+ return ()=>eventBus.deregisterListener(QUERY_TOOL_EVENTS.TRIGGER_INCLUDE_EXCLUDE_FILTER, triggerFilter);
+ }, [selectedCell.current]);
+
+ useEffect(()=>{
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.SELECTED_ROWS_COLS_CHANGED, selectedRows.size, selectedColumns.size);
+ }, [selectedRows.size, selectedColumns.size]);
+
+ useEffect(()=>{
+ rsu.current.transId = queryToolCtx.params.trans_id;
+ }, [queryToolCtx.params.trans_id]);
+
+ const fetchMoreRows = async (all=false, callback)=>{
+ if(queryData.has_more_rows) {
+ setIsLoadingMore(true);
+ const res = await rsu.current.getMoreRows(all);
+ const newRows = rsu.current.processRows(res.data.data.result, columns);
+ setRows((prevRows)=>[...prevRows, ...newRows]);
+ setQueryData((prev)=>({
+ ...prev,
+ has_more_rows: res.data.data.has_more_rows,
+ rows_fetched_to: res.data.data.rows_fetched_to!=0 ? res.data.data.rows_fetched_to : prev.rows_fetched_to,
+ }));
+ setIsLoadingMore(false);
+ }
+ callback?.();
+ };
+ useEffect(()=>{
+ eventBus.registerListener(QUERY_TOOL_EVENTS.FETCH_MORE_ROWS, fetchMoreRows);
+ return ()=>eventBus.deregisterListener(QUERY_TOOL_EVENTS.FETCH_MORE_ROWS, fetchMoreRows);
+ }, [queryData, columns]);
+
+ useEffect(()=>{
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.ROWS_FETCHED, queryData?.rows_fetched_to, queryData?.rows_affected);
+ }, [queryData]);
+
+ const warnSaveDataClose = ()=>{
+ // No changes.
+ if(!_.size(dataChangeStore.updated) && !_.size(dataChangeStore.added) && !_.size(dataChangeStore.deleted)
+ || !queryToolCtx.preferences?.sqleditor.prompt_save_data_changes) {
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.WARN_SAVE_TEXT_CLOSE);
+ return;
+ }
+ queryToolCtx.modal.showModal(gettext('Save data changes?'), (closeModal)=>(
+ {
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.WARN_SAVE_TEXT_CLOSE);
+ }}
+ onSave={async ()=>{
+ await triggerSaveData();
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.WARN_SAVE_TEXT_CLOSE);
+ }}
+ />
+ ));
+ };
+ useEffect(()=>{
+ let isDirty = _.size(dataChangeStore.updated) || _.size(dataChangeStore.added) || _.size(dataChangeStore.deleted);
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.DATAGRID_CHANGED, isDirty, dataChangeStore);
+
+ eventBus.registerListener(QUERY_TOOL_EVENTS.WARN_SAVE_DATA_CLOSE, warnSaveDataClose);
+ return ()=>{
+ eventBus.deregisterListener(QUERY_TOOL_EVENTS.WARN_SAVE_DATA_CLOSE, warnSaveDataClose);
+ };
+ }, [dataChangeStore]);
+
+ const triggerSaveData = async ()=>{
+ if(!_.size(dataChangeStore.updated) && !_.size(dataChangeStore.added) && !_.size(dataChangeStore.deleted)) {
+ return;
+ }
+ rsu.current.historyQuerySource = QuerySources.SAVE_DATA;
+ setLoaderText(gettext('Saving data...'));
+ try {
+ /* Convert the added info to actual rows */
+ let added = {...dataChangeStore.added};
+ Object.keys(added).map((clientPK)=>{
+ added[clientPK].data = _.find(rows, (r)=>rowKeyGetter(r)==clientPK);
+ });
+ let {data: respData} = await rsu.current.saveData({
+ updated: dataChangeStore.updated,
+ deleted: dataChangeStore.deleted,
+ added_index: dataChangeStore.added_index,
+ added: added,
+ columns: columns,
+ });
+
+ try {
+ respData.data.query_results.forEach((r)=>{
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.PUSH_HISTORY, {
+ 'status': r.status,
+ 'start_time': rsu.current.startTime,
+ 'query': r.sql,
+ 'row_affected': r.rows_affected,
+ 'total_time': null,
+ 'message': r.result,
+ 'query_source': QuerySources.SAVE_DATA,
+ 'is_pgadmin_query': true,
+ 'info': gettext('This query was generated by pgAdmin as part of a "Save Data" operation'),
+ });
+ });
+ } catch (_e) {/* History errors should not bother others */}
+
+ if(!respData.data.status) {
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.SAVE_DATA_DONE, false);
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.SET_MESSAGE, respData.data.result);
+ Notifier.error(respData.data.result, 20000);
+ // If the transaction is not idle, notify the user that previous queries are not rolled back,
+ // only the failed save queries.
+ if (respData.data.transaction_status != CONNECTION_STATUS.TRANSACTION_STATUS_IDLE) {
+ Notifier.info(gettext('Saving data changes was rolled back but the current transaction is ' +
+ 'still active; previous queries are unaffected.'));
+ }
+ setLoaderText(null);
+ return;
+ }
+
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.SAVE_DATA_DONE, true);
+ if(!_.size(dataChangeStore.added)) {
+ // Update the rows in a grid after addition
+ respData.data.query_results.forEach((qr)=>{
+ if(!_.isNull(qr.row_added)) {
+ let rowClientPK = Object.keys(qr.row_added)[0];
+ setRows((prevRows)=>{
+ let rowIdx = prevRows.findIndex((r)=>rowKeyGetter(r)==rowClientPK);
+ return [
+ ...prevRows.slice(0, rowIdx),
+ {
+ ...prevRows[rowIdx],
+ ...qr.row_added[rowClientPK],
+ },
+ ...prevRows.slice(rowIdx+1),
+ ];
+ });
+ }
+ });
+ }
+ let deletedKeys = Object.keys(dataChangeStore.deleted);
+ if(deletedKeys.length == rows.length) {
+ setRows([]);
+ }
+ else if(deletedKeys.length > 0) {
+ setRows((prevRows)=>{
+ return prevRows.filter((row)=>{
+ return deletedKeys.indexOf(row[rsu.current.clientPK]) == -1;
+ });
+ });
+ setColumns(columns);
+ }
+ dispatchDataChange({type: 'reset'});
+ setSelectedRows(new Set());
+ setSelectedColumns(new Set());
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.SET_CONNECTION_STATUS, respData.data.transaction_status);
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.SET_MESSAGE, '');
+ Notifier.success(gettext('Data saved successfully.'));
+ if(respData.data.transaction_status > CONNECTION_STATUS.TRANSACTION_STATUS_IDLE) {
+ Notifier.info(gettext('Auto-commit is off. You still need to commit changes to the database.'));
+ }
+ } catch (error) {
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.SAVE_DATA_DONE, false);
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.HANDLE_API_ERROR, error, {
+ checkTransaction: true,
+ });
+ }
+ setLoaderText(null);
+ };
+
+ useEffect(()=>{
+ eventBus.registerListener(QUERY_TOOL_EVENTS.TRIGGER_SAVE_DATA, triggerSaveData);
+ return ()=>eventBus.deregisterListener(QUERY_TOOL_EVENTS.TRIGGER_SAVE_DATA, triggerSaveData);
+ }, [dataChangeStore, rows, columns]);
+
+ const copyDataFunc = (withHeaders=false)=>{
+ const queryToolPref = queryToolCtx.preferences.sqleditor;
+ let copyData = new CopyData({
+ quoting: queryToolPref.results_grid_quoting,
+ quote_char: queryToolPref.results_grid_quote_char,
+ field_separator: queryToolPref.results_grid_field_separator,
+ });
+ let copyRows=[], copyCols=[];
+ if(selectedRows.size > 0) {
+ copyCols = columns;
+ copyRows = rows.filter((r)=>selectedRows.has(r[rsu.current.clientPK]));
+ } else if(selectedColumns.size > 0) {
+ /* Row num col is added by QueryDataGrid, index will be +1 */
+ copyCols = _.filter(columns, (_c, i)=>selectedColumns.has(i+1));
+ copyRows = _.map(rows, (r)=>_.pick(r, _.map(copyCols, (c)=>c.key)));
+ } else if(selectedCell.current[0] && selectedCell.current[1]) {
+ copyCols = [selectedCell.current[1]];
+ copyRows = [{[selectedCell.current[1].key]: selectedCell.current[0][selectedCell.current[1].key]}];
+ }
+ if(copyRows.length > 0 && copyCols.length >0) {
+ copyData.copyRowsToCsv(copyRows, copyCols, withHeaders);
+ }
+ };
+
+ const triggerDeleteRows = ()=>{
+ if(!queryData.can_edit) {
+ return;
+ }
+ let add = {};
+ let remove = [];
+ let selRowsData = rows.filter((r)=>selectedRows.has(r[rsu.current.clientPK]));
+ let removeNewlyAdded = [];
+ for(let row of selRowsData) {
+ let clientPK = row[rsu.current.clientPK];
+ if(clientPK in dataChangeStore.deleted) {
+ remove.push(clientPK);
+ } else {
+ /* If deleted from newly added */
+ if(clientPK in dataChangeStore.added) {
+ removeNewlyAdded.push(clientPK);
+ } else {
+ let primaryKeys = {};
+ Object.keys(queryData.primary_keys).forEach((k)=>{
+ primaryKeys[k] = row[k];
+ });
+ add[clientPK] = primaryKeys;
+ }
+ }
+ }
+ if(removeNewlyAdded.length > 0) {
+ dispatchDataChange({
+ type: 'added',
+ remove: removeNewlyAdded,
+ });
+ setRows((prev)=>{
+ return prev.filter((r)=>removeNewlyAdded.indexOf(rowKeyGetter(r))==-1);
+ });
+ setSelectedRows((prev)=>{
+ let newRows = new Set(prev);
+ removeNewlyAdded.forEach((rowId)=>{
+ if(newRows.has(rowId)) {
+ newRows.delete(rowId);
+ }
+ });
+ return newRows;
+ });
+ }
+
+ dispatchDataChange({
+ type: 'deleted',
+ add: add,
+ remove: remove,
+ });
+ };
+
+ useEffect(()=>{
+ eventBus.registerListener(QUERY_TOOL_EVENTS.TRIGGER_DELETE_ROWS, triggerDeleteRows);
+ eventBus.registerListener(QUERY_TOOL_EVENTS.COPY_DATA, copyDataFunc);
+ return ()=>{
+ eventBus.deregisterListener(QUERY_TOOL_EVENTS.TRIGGER_DELETE_ROWS, triggerDeleteRows);
+ eventBus.deregisterListener(QUERY_TOOL_EVENTS.COPY_DATA, copyDataFunc);
+ };
+ }, [selectedRows, selectedColumns, queryData, dataChangeStore, selectedCell.current]);
+
+ useEffect(()=>{
+ const triggerAddRows = (_rows)=>{
+ let newRows = rsu.current.processRows(_rows, columns, true);
+ setRows((prev)=>[...newRows, ...prev]);
+ let add = {};
+ newRows.forEach((row)=>{
+ add[rowKeyGetter(row)] = {
+ err: false,
+ };
+ });
+ dispatchDataChange({
+ type: 'added',
+ add: add,
+ });
+ };
+ eventBus.registerListener(QUERY_TOOL_EVENTS.TRIGGER_ADD_ROWS, triggerAddRows);
+ return ()=>eventBus.deregisterListener(QUERY_TOOL_EVENTS.TRIGGER_ADD_ROWS, triggerAddRows);
+ }, [columns]);
+
+ useEffect(()=>{
+ const renderGeometries = (column)=>{
+ let selRowsData = selectedRows.size === 0 ? rows : rows.filter((r)=>selectedRows.has(rowKeyGetter(r)));
+ LayoutHelper.openTab(queryToolCtx.docker, {
+ id: PANELS.GEOMETRY,
+ title:'Geometry Viewer',
+ content: ,
+ closable: true,
+ }, PANELS.MESSAGES, 'after-tab', true);
+ };
+ eventBus.registerListener(QUERY_TOOL_EVENTS.TRIGGER_RENDER_GEOMETRIES, renderGeometries);
+ return ()=>eventBus.deregisterListener(QUERY_TOOL_EVENTS.TRIGGER_RENDER_GEOMETRIES, renderGeometries);
+ }, [rows, columns, selectedRows.size]);
+
+ const handleScroll = (e)=>{
+ if (isLoadingMore || !rsu.current.isAtBottom(e)) return;
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.FETCH_MORE_ROWS);
+ };
+
+ const onRowsChange = (newRows, otherInfo)=>{
+ let row = newRows[otherInfo.indexes[0]];
+ let clientPK = rowKeyGetter(row);
+
+ if(clientPK in (dataChangeStore.added || {})) {
+ /* No need to track this */
+ } else if(clientPK in (dataChangeStore.updated || {})) {
+ dispatchDataChange({
+ type: 'updated',
+ clientPK: clientPK,
+ payload: {
+ data: {[otherInfo.column.key]: row[otherInfo.column.key]},
+ }
+ });
+ } else {
+ let oldRow = rows[otherInfo.indexes[0]];
+ /* If there are no primary keys, then discard */
+ if(queryData.can_edit) {
+ let primaryKeys = {};
+ Object.keys(queryData.primary_keys).forEach((k)=>{
+ primaryKeys[k] = oldRow[k];
+ });
+ dispatchDataChange({
+ type: 'updated',
+ clientPK: clientPK,
+ payload: {
+ err: false,
+ data: {[otherInfo.column.key]: row[otherInfo.column.key]},
+ primary_keys: primaryKeys,
+ }
+ });
+ }
+ }
+ setRows(newRows);
+ };
+
+ const rowKeyGetter = React.useCallback((row)=>row[rsu.current.clientPK]);
+ return (
+
+
+
+ {(columns.length == 0 && rows.length == 0) &&
+
+ }
+ {(columns.length != 0 || rows.length != 0) && <>
+
+
+
+
+ >}
+
+ );
+}
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSetToolbar.jsx b/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSetToolbar.jsx
new file mode 100644
index 000000000..e51e2ad5a
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/ResultSetToolbar.jsx
@@ -0,0 +1,170 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import React, {useContext, useCallback, useEffect, useState} from 'react';
+import { makeStyles } from '@material-ui/styles';
+import { Box } from '@material-ui/core';
+import { PgButtonGroup, PgIconButton } from '../../../../../../static/js/components/Buttons';
+import KeyboardArrowDownIcon from '@material-ui/icons/KeyboardArrowDown';
+import PlaylistAddRoundedIcon from '@material-ui/icons/PlaylistAddRounded';
+import FileCopyRoundedIcon from '@material-ui/icons/FileCopyRounded';
+import DeleteRoundedIcon from '@material-ui/icons/DeleteRounded';
+import { PasteIcon, SaveDataIcon } from '../../../../../../static/js/components/ExternalIcon';
+import GetAppRoundedIcon from '@material-ui/icons/GetAppRounded';
+import {QUERY_TOOL_EVENTS} from '../QueryToolConstants';
+import { QueryToolContext, QueryToolEventsContext } from '../QueryToolComponent';
+import { PgMenu, PgMenuItem } from '../../../../../../static/js/components/Menu';
+import gettext from 'sources/gettext';
+import { useKeyboardShortcuts } from '../../../../../../static/js/custom_hooks';
+import {shortcut_key} from 'sources/keyboard_shortcuts';
+import CopyData from '../QueryToolDataGrid/CopyData';
+import PropTypes from 'prop-types';
+import CustomPropTypes from '../../../../../../static/js/custom_prop_types';
+
+const useStyles = makeStyles((theme)=>({
+ root: {
+ padding: '2px',
+ display: 'flex',
+ alignItems: 'center',
+ gap: '4px',
+ backgroundColor: theme.otherVars.editorToolbarBg,
+ ...theme.mixins.panelBorder.bottom,
+ },
+}));
+
+export function ResultSetToolbar({containerRef, canEdit}) {
+ const classes = useStyles();
+ const eventBus = useContext(QueryToolEventsContext);
+ const queryToolCtx = useContext(QueryToolContext);
+
+ const [buttonsDisabled, setButtonsDisabled] = useState({
+ 'save-data': true,
+ 'delete-rows': true,
+ 'copy-rows': true,
+ });
+ const [menuOpenId, setMenuOpenId] = React.useState(null);
+ const [checkedMenuItems, setCheckedMenuItems] = React.useState({});
+ /* Menu button refs */
+ const copyMenuRef = React.useRef(null);
+
+ const queryToolPref = queryToolCtx.preferences.sqleditor;
+
+ const setDisableButton = useCallback((name, disable=true)=>{
+ setButtonsDisabled((prev)=>({...prev, [name]: disable}));
+ }, []);
+ const saveData = useCallback(()=>{
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_SAVE_DATA);
+ }, []);
+ const deleteRows = useCallback(()=>{
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_DELETE_ROWS);
+ }, []);
+ const pasteRows = useCallback(async ()=>{
+ let copyUtils = new CopyData({
+ quoting: queryToolPref.results_grid_quoting,
+ quote_char: queryToolPref.results_grid_quote_char,
+ field_separator: queryToolPref.results_grid_field_separator,
+ });
+ let copiedRows = copyUtils.getCopiedRows();
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_ADD_ROWS, copiedRows);
+ }, [queryToolPref]);
+ const copyData = ()=>{
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.COPY_DATA, checkedMenuItems['copy_with_headers']);
+ };
+ const addRow = useCallback(()=>{
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_ADD_ROWS, [[]]);
+ }, []);
+ const downloadResult = useCallback(()=>{
+ eventBus.fireEvent(QUERY_TOOL_EVENTS.TRIGGER_SAVE_RESULTS);
+ }, []);
+
+ const openMenu = useCallback((e)=>{
+ setMenuOpenId(e.currentTarget.name);
+ }, []);
+ const handleMenuClose = useCallback(()=>{
+ setMenuOpenId(null);
+ }, []);
+
+ const checkMenuClick = useCallback((e)=>{
+ setCheckedMenuItems((prev)=>{
+ let newVal = !prev[e.value];
+ return {
+ ...prev,
+ [e.value]: newVal,
+ };
+ });
+ }, []);
+
+ useEffect(()=>{
+ eventBus.registerListener(QUERY_TOOL_EVENTS.DATAGRID_CHANGED, (isDirty)=>{
+ setDisableButton('save-data', !isDirty);
+ });
+ eventBus.registerListener(QUERY_TOOL_EVENTS.SELECTED_ROWS_COLS_CHANGED, (rows, cols)=>{
+ setDisableButton('delete-rows', !rows);
+ setDisableButton('copy-rows', (!rows && !cols));
+ });
+ }, []);
+
+ useEffect(()=>{
+ eventBus.registerListener(QUERY_TOOL_EVENTS.TRIGGER_COPY_DATA, copyData);
+ return ()=>eventBus.deregisterListener(QUERY_TOOL_EVENTS.TRIGGER_COPY_DATA, copyData);
+ }, [checkedMenuItems['copy_with_headers']]);
+
+ useKeyboardShortcuts([
+ {
+ shortcut: queryToolPref.save_data,
+ options: {
+ callback: ()=>{saveData();}
+ }
+ },
+ {
+ shortcut: queryToolPref.download_results,
+ options: {
+ callback: (e)=>{e.preventDefault(); downloadResult();}
+ }
+ },
+ ], containerRef);
+
+ return (
+ <>
+
+
+ }
+ accesskey={shortcut_key(queryToolPref.btn_add_row)} disabled={!canEdit} onClick={addRow} />
+ }
+ accesskey={shortcut_key(queryToolPref.btn_copy_row)} disabled={buttonsDisabled['copy-rows']} onClick={copyData} />
+ } splitButton
+ name="menu-copyheader" ref={copyMenuRef} onClick={openMenu} />
+ }
+ accesskey={shortcut_key(queryToolPref.btn_paste_row)} disabled={!canEdit} onClick={pasteRows} />
+ }
+ accesskey={shortcut_key(queryToolPref.btn_delete_row)} disabled={buttonsDisabled['delete-rows'] || !canEdit} onClick={deleteRows} />
+
+
+ }
+ shortcut={queryToolPref.save_data} disabled={buttonsDisabled['save-data'] || !canEdit} onClick={saveData}/>
+
+
+ }
+ onClick={downloadResult} shortcut={queryToolPref.download_results}/>
+
+
+
+ Copy with headers
+
+ >
+ );
+}
+
+ResultSetToolbar.propTypes = {
+ containerRef: CustomPropTypes.ref,
+ canEdit: PropTypes.bool,
+};
diff --git a/web/pgadmin/tools/sqleditor/static/js/components/sections/StatusBar.jsx b/web/pgadmin/tools/sqleditor/static/js/components/sections/StatusBar.jsx
new file mode 100644
index 000000000..df562884e
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/static/js/components/sections/StatusBar.jsx
@@ -0,0 +1,117 @@
+
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import React, { useEffect, useState, useContext } from 'react';
+import { makeStyles } from '@material-ui/styles';
+import { Box } from '@material-ui/core';
+import clsx from 'clsx';
+import _ from 'lodash';
+import { QUERY_TOOL_EVENTS } from '../QueryToolConstants';
+import { useStopwatch } from '../../../../../../static/js/custom_hooks';
+import { QueryToolEventsContext } from '../QueryToolComponent';
+
+
+const useStyles = makeStyles((theme)=>({
+ root: {
+ display: 'flex',
+ alignItems: 'center',
+ ...theme.mixins.panelBorder.top,
+ flexWrap: 'wrap',
+ backgroundColor: theme.otherVars.editorToolbarBg,
+ userSelect: 'text',
+ },
+ padding: {
+ padding: '2px 12px',
+ },
+ divider: {
+ ...theme.mixins.panelBorder.right,
+ },
+ mlAuto: {
+ marginLeft: 'auto',
+ }
+}));
+
+export function StatusBar() {
+ const classes = useStyles();
+ const eventBus = useContext(QueryToolEventsContext);
+ const [position, setPosition] = useState([1, 1]);
+ const [lastTaskText, setLastTaskText] = useState(null);
+ const [rowsCount, setRowsCount] = useState([0, 0]);
+ const [selectedRowsCount, setSelectedRowsCount] = useState(0);
+ const [dataRowChangeCounts, setDataRowChangeCounts] = useState({
+ isDirty: false,
+ added: 0,
+ updated: 0,
+ deleted: 0,
+ });
+ const {seconds, minutes, hours, msec, start:startTimer, pause:pauseTimer, reset:resetTimer} = useStopwatch({});
+
+ useEffect(()=>{
+ eventBus.registerListener(QUERY_TOOL_EVENTS.CURSOR_ACTIVITY, (newPos)=>{
+ setPosition(newPos||[1, 1]);
+ });
+ eventBus.registerListener(QUERY_TOOL_EVENTS.EXECUTION_END, ()=>{
+ pauseTimer();
+ setLastTaskText('Query complete');
+ });
+ eventBus.registerListener(QUERY_TOOL_EVENTS.TASK_START, (taskText, startTime)=>{
+ resetTimer();
+ startTimer(startTime);
+ setLastTaskText(taskText);
+ });
+ eventBus.registerListener(QUERY_TOOL_EVENTS.TASK_END, (taskText, endTime)=>{
+ pauseTimer(endTime);
+ setLastTaskText(taskText);
+ });
+ eventBus.registerListener(QUERY_TOOL_EVENTS.ROWS_FETCHED, (fetched, total)=>{
+ setRowsCount([fetched||0, total||0]);
+ });
+ eventBus.registerListener(QUERY_TOOL_EVENTS.SELECTED_ROWS_COLS_CHANGED, (rows)=>{
+ setSelectedRowsCount(rows);
+ });
+ eventBus.registerListener(QUERY_TOOL_EVENTS.DATAGRID_CHANGED, (_isDirty, dataChangeStore)=>{
+ setDataRowChangeCounts({
+ added: Object.keys(dataChangeStore.added||{}).length,
+ updated: Object.keys(dataChangeStore.updated||{}).length,
+ deleted: Object.keys(dataChangeStore.deleted||{}).length,
+ });
+ });
+ }, []);
+
+ let stagedText = '';
+ if(dataRowChangeCounts.added > 0) {
+ stagedText += ` Added: ${dataRowChangeCounts.added};`;
+ }
+ if(dataRowChangeCounts.updated > 0) {
+ stagedText += ` Updated: ${dataRowChangeCounts.updated};`;
+ }
+ if(dataRowChangeCounts.deleted > 0) {
+ stagedText += ` Deleted: ${dataRowChangeCounts.deleted};`;
+ }
+
+ return (
+
+ Total rows: {rowsCount[0]} of {rowsCount[1]}
+ {lastTaskText &&
+ {lastTaskText} {hours.toString().padStart(2, '0')}:{minutes.toString().padStart(2, '0')}:{seconds.toString().padStart(2, '0')}.{msec.toString().padStart(3, '0')}
+ }
+ {!lastTaskText && !_.isNull(lastTaskText) &&
+ {lastTaskText} {hours.toString().padStart(2, '0')}:{minutes.toString().padStart(2, '0')}:{seconds.toString().padStart(2, '0')}.{msec.toString().padStart(3, '0')}
+ }
+ {Boolean(selectedRowsCount) &&
+ Rows selected: {selectedRowsCount} }
+ {stagedText &&
+
+ Changes staged: {stagedText}
+
+ }
+ Ln {position[0]}, Col {position[1]}
+
+ );
+}
diff --git a/web/pgadmin/tools/sqleditor/static/js/index.js b/web/pgadmin/tools/sqleditor/static/js/index.js
new file mode 100644
index 000000000..6ad35fb34
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/static/js/index.js
@@ -0,0 +1,26 @@
+/////////////////////////////////////////////////////////////
+//
+// pgAdmin 4 - PostgreSQL Tools
+//
+// Copyright (C) 2013 - 2022, The pgAdmin Development Team
+// This software is released under the PostgreSQL Licence
+//
+//////////////////////////////////////////////////////////////
+import pgAdmin from 'sources/pgadmin';
+import pgBrowser from 'top/browser/static/js/browser';
+import SQLEditor from './SQLEditorModule';
+
+/* eslint-disable */
+/* This is used to change publicPath of webpack at runtime for loading chunks */
+/* Do not add let, var, const to this variable */
+__webpack_public_path__ = window.resourceBasePath;
+/* eslint-enable */
+
+if(!pgAdmin.Tools) {
+ pgAdmin.Tools = {};
+}
+pgAdmin.Tools.SQLEditor = SQLEditor.getInstance(pgAdmin, pgBrowser);
+
+module.exports = {
+ SQLEditor: SQLEditor,
+};
diff --git a/web/pgadmin/tools/datagrid/static/js/show_query_tool.js b/web/pgadmin/tools/sqleditor/static/js/show_query_tool.js
similarity index 64%
rename from web/pgadmin/tools/datagrid/static/js/show_query_tool.js
rename to web/pgadmin/tools/sqleditor/static/js/show_query_tool.js
index 157db3335..2f677d7d2 100644
--- a/web/pgadmin/tools/datagrid/static/js/show_query_tool.js
+++ b/web/pgadmin/tools/sqleditor/static/js/show_query_tool.js
@@ -9,7 +9,7 @@
import gettext from '../../../../static/js/gettext';
import url_for from '../../../../static/js/url_for';
-import {getPanelTitle} from './datagrid_panel_title';
+import {getPanelTitle} from './sqleditor_title';
import {getRandomInt} from 'sources/utils';
import $ from 'jquery';
import Notify from '../../../../static/js/helpers/Notifier';
@@ -18,18 +18,20 @@ function hasDatabaseInformation(parentData) {
return parentData.database;
}
-function generateUrl(trans_id, title, parentData, sqlId) {
- let url_endpoint = url_for('datagrid.panel', {
+export function generateUrl(trans_id, parentData, sqlId) {
+ let url_endpoint = url_for('sqleditor.panel', {
'trans_id': trans_id,
});
url_endpoint += `?is_query_tool=${true}`
+`&sgid=${parentData.server_group._id}`
- +`&sid=${parentData.server._id}`
- +`&server_type=${parentData.server.server_type}`;
+ +`&sid=${parentData.server._id}`;
if (hasDatabaseInformation(parentData)) {
url_endpoint += `&did=${parentData.database._id}`;
+ if(parentData.database.label) {
+ url_endpoint += `&database_name=${parentData.database.label}`;
+ }
}
if(sqlId) {
@@ -47,7 +49,7 @@ function generateTitle(pgBrowser, aciTreeIdentifier) {
return getPanelTitle(pgBrowser, aciTreeIdentifier);
}
-export function showQueryTool(datagrid, pgBrowser, url, aciTreeIdentifier, transId) {
+export function showQueryTool(queryToolMod, pgBrowser, url, aciTreeIdentifier, transId) {
const sURL = url || '';
const queryToolTitle = generateTitle(pgBrowser, aciTreeIdentifier);
@@ -66,15 +68,15 @@ export function showQueryTool(datagrid, pgBrowser, url, aciTreeIdentifier, trans
return;
}
- const gridUrl = generateUrl(transId, queryToolTitle, parentData);
- launchDataGrid(datagrid, transId, gridUrl, queryToolTitle, sURL);
+ const gridUrl = generateUrl(transId, parentData);
+ launchQueryTool(queryToolMod, transId, gridUrl, queryToolTitle, sURL);
}
-export function generateScript(parentData, datagrid) {
+export function generateScript(parentData, queryToolMod) {
const queryToolTitle = `${parentData.database}/${parentData.user}@${parentData.server}`;
const transId = getRandomInt(1, 9999999);
- let url_endpoint = url_for('datagrid.panel', {
+ let url_endpoint = url_for('sqleditor.panel', {
'trans_id': transId,
});
@@ -82,12 +84,13 @@ export function generateScript(parentData, datagrid) {
+`&sgid=${parentData.sgid}`
+`&sid=${parentData.sid}`
+`&server_type=${parentData.stype}`
- +`&did=${parentData.did}`;
+ +`&did=${parentData.did}`
+ +`&sql_id=${parentData.sql_id}`;
- launchDataGrid(datagrid, transId, url_endpoint, queryToolTitle, '');
+ launchQueryTool(queryToolMod, transId, url_endpoint, queryToolTitle, '');
}
-export function showERDSqlTool(parentData, erdSqlId, queryToolTitle, datagrid) {
+export function showERDSqlTool(parentData, erdSqlId, queryToolTitle, queryToolMod) {
const transId = getRandomInt(1, 9999999);
parentData = {
server_group: {
@@ -102,12 +105,12 @@ export function showERDSqlTool(parentData, erdSqlId, queryToolTitle, datagrid) {
},
};
- const gridUrl = generateUrl(transId, queryToolTitle, parentData, erdSqlId);
- launchDataGrid(datagrid, transId, gridUrl, queryToolTitle, '');
+ const gridUrl = generateUrl(transId, parentData, erdSqlId);
+ launchQueryTool(queryToolMod, transId, gridUrl, queryToolTitle, '');
}
-export function launchDataGrid(datagrid, transId, gridUrl, queryToolTitle, sURL) {
- let retVal = datagrid.launch_grid(transId, gridUrl, true, queryToolTitle, sURL);
+export function launchQueryTool(queryToolMod, transId, gridUrl, queryToolTitle, sURL) {
+ let retVal = queryToolMod.launch(transId, gridUrl, true, queryToolTitle, sURL);
if(!retVal) {
Notify.alert(
@@ -119,23 +122,17 @@ export function launchDataGrid(datagrid, transId, gridUrl, queryToolTitle, sURL)
}
}
-function setPanelTitle(panel, value) {
- if(value) {
- $('#' + panel.$title.index() + ' div:first').addClass('wcPanelTab-dynamic');
- } else {
- $('#' + panel.$title.index() + ' div:first').removeClass('wcPanelTab-dynamic');
- }
-}
-
export function _set_dynamic_tab(pgBrowser, value){
- var datagrid_panels = pgBrowser.docker.findPanels('frm_datagrid');
- datagrid_panels.forEach(panel => {
- setPanelTitle(panel, value);
- });
+ var sqleditor_panels = pgBrowser.docker.findPanels('frm_sqleditor');
+ const process = panel => {
+ if(value) {
+ $('#' + panel.$title.index() + ' div:first').addClass('wcPanelTab-dynamic');
+ } else {
+ $('#' + panel.$title.index() + ' div:first').removeClass('wcPanelTab-dynamic');
+ }
+ };
+ sqleditor_panels.forEach(process);
var debugger_panels = pgBrowser.docker.findPanels('frm_debugger');
- debugger_panels.forEach(panel => {
- setPanelTitle(panel, value);
- });
-
+ debugger_panels.forEach(process);
}
diff --git a/web/pgadmin/tools/datagrid/static/js/show_data.js b/web/pgadmin/tools/sqleditor/static/js/show_view_data.js
similarity index 87%
rename from web/pgadmin/tools/datagrid/static/js/show_data.js
rename to web/pgadmin/tools/sqleditor/static/js/show_view_data.js
index f418e7da7..a76fd5f15 100644
--- a/web/pgadmin/tools/datagrid/static/js/show_data.js
+++ b/web/pgadmin/tools/sqleditor/static/js/show_view_data.js
@@ -8,24 +8,24 @@
//////////////////////////////////////////////////////////////
import gettext from '../../../../static/js/gettext';
import url_for from '../../../../static/js/url_for';
-import {getDatabaseLabel, generateTitle} from './datagrid_panel_title';
+import {getDatabaseLabel, generateTitle} from './sqleditor_title';
import CodeMirror from 'bundled_codemirror';
import * as SqlEditorUtils from 'sources/sqleditor_utils';
import $ from 'jquery';
import _ from 'underscore';
import Notify from '../../../../static/js/helpers/Notifier';
-export function showDataGrid(
- datagrid,
+export function showViewData(
+ queryToolMod,
pgBrowser,
alertify,
connectionData,
- aciTreeIdentifier,
+ treeIdentifier,
transId,
filter=false,
preferences=null
) {
- const node = pgBrowser.tree.findNodeByDomElement(aciTreeIdentifier);
+ const node = pgBrowser.tree.findNodeByDomElement(treeIdentifier);
if (node === undefined || !node.getData()) {
Notify.alert(
gettext('Data Grid Error'),
@@ -34,7 +34,7 @@ export function showDataGrid(
return;
}
- const parentData = pgBrowser.tree.getTreeNodeHierarchy( aciTreeIdentifier
+ const parentData = pgBrowser.tree.getTreeNodeHierarchy( treeIdentifier
);
if (hasServerOrDatabaseConfiguration(parentData)
@@ -48,30 +48,33 @@ export function showDataGrid(
}
const gridUrl = generateUrl(transId, connectionData, node.getData(), parentData);
- const queryToolTitle = generateDatagridTitle(pgBrowser, aciTreeIdentifier);
+ const queryToolTitle = generateViewDataTitle(pgBrowser, treeIdentifier);
if(filter) {
initFilterDialog(alertify, pgBrowser);
const validateUrl = generateFilterValidateUrl(node.getData(), parentData);
let okCallback = function(sql) {
- datagrid.launch_grid(transId, gridUrl, false, queryToolTitle, null, sql);
+ queryToolMod.launch(transId, gridUrl, false, queryToolTitle, null, sql);
};
- $.get(url_for('datagrid.filter'),
+ $.get(url_for('sqleditor.filter'),
function(data) {
alertify.filterDialog(gettext('Data Filter - %s', queryToolTitle), data, validateUrl, preferences, okCallback)
.resizeTo(pgBrowser.stdW.sm,pgBrowser.stdH.sm);
}
);
} else {
- datagrid.launch_grid(transId, gridUrl, false, queryToolTitle);
+ queryToolMod.launch(transId, gridUrl, false, queryToolTitle);
}
}
export function retrieveNameSpaceName(parentData) {
- if (parentData.schema !== undefined) {
+ if(!parentData) {
+ return null;
+ }
+ else if (parentData.schema !== undefined) {
return parentData.schema.label;
}
else if (parentData.view !== undefined) {
@@ -83,8 +86,24 @@ export function retrieveNameSpaceName(parentData) {
return '';
}
+export function retrieveNodeName(parentData) {
+ if(!parentData) {
+ return null;
+ }
+ else if (parentData.table !== undefined) {
+ return parentData.table.label;
+ }
+ else if (parentData.view !== undefined) {
+ return parentData.view.label;
+ }
+ else if (parentData.catalog !== undefined) {
+ return parentData.catalog.label;
+ }
+ return '';
+}
+
function generateUrl(trans_id, connectionData, nodeData, parentData) {
- let url_endpoint = url_for('datagrid.panel', {
+ let url_endpoint = url_for('sqleditor.panel', {
'trans_id': trans_id,
});
@@ -108,7 +127,7 @@ function generateFilterValidateUrl(nodeData, parentData) {
'obj_id': nodeData._id,
};
- return url_for('datagrid.filter_validate', url_params);
+ return url_for('sqleditor.filter_validate', url_params);
}
function initFilterDialog(alertify, pgBrowser) {
@@ -286,15 +305,15 @@ function hasSchemaOrCatalogOrViewInformation(parentData) {
parentData.catalog !== undefined;
}
-export function generateDatagridTitle(pgBrowser, aciTreeIdentifier, custom_title=null, backend_entity=null) {
+export function generateViewDataTitle(pgBrowser, treeIdentifier, custom_title=null, backend_entity=null) {
var preferences = pgBrowser.get_preferences_for_module('browser');
const parentData = pgBrowser.tree.getTreeNodeHierarchy(
- aciTreeIdentifier
+ treeIdentifier
);
const namespaceName = retrieveNameSpaceName(parentData);
const db_label = !_.isUndefined(backend_entity) && backend_entity != null && backend_entity.hasOwnProperty('db_name') ? backend_entity['db_name'] : getDatabaseLabel(parentData);
- const node = pgBrowser.tree.findNodeByDomElement(aciTreeIdentifier);
+ const node = pgBrowser.tree.findNodeByDomElement(treeIdentifier);
var dtg_title_placeholder = '';
if(custom_title) {
@@ -310,7 +329,7 @@ export function generateDatagridTitle(pgBrowser, aciTreeIdentifier, custom_title
'server': parentData.server.label,
'schema': namespaceName,
'table': node.getData().label,
- 'type': 'datagrid',
+ 'type': 'view_data',
};
return generateTitle(dtg_title_placeholder, title_data);
}
diff --git a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
deleted file mode 100644
index 35c6aad9a..000000000
--- a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js
+++ /dev/null
@@ -1,5189 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-/* eslint-disable */
-/* This is used to change publicPath of webpack at runtime for loading chunks */
-/* Do not add let, var, const to this variable */
-__webpack_public_path__ = window.resourceBasePath;
-/* eslint-enable */
-
-import {launchDataGrid} from 'tools/datagrid/static/js/show_query_tool';
-import {generateDatagridTitle} from 'tools/datagrid/static/js/show_data';
-import Notify from '../../../../static/js/helpers/Notifier';
-
-define('tools.querytool', [
- 'sources/gettext', 'sources/url_for', 'jquery', 'jquery.ui',
- 'jqueryui.position', 'underscore', 'pgadmin.alertifyjs',
- 'sources/pgadmin', 'backbone', 'bundled_codemirror', 'sources/utils',
- 'pgadmin.misc.explain',
- 'pgadmin.user_management.current_user',
- 'sources/selection/grid_selector',
- 'sources/selection/active_cell_capture',
- 'sources/selection/clipboard',
- 'sources/selection/copy_data',
- 'sources/selection/range_selection_helper',
- 'sources/slickgrid/event_handlers/handle_query_output_keyboard_event',
- 'sources/selection/xcell_selection_model',
- 'sources/selection/set_staged_rows',
- 'sources/sqleditor_utils',
- 'sources/sqleditor/execute_query',
- 'sources/sqleditor/query_tool_http_error_handler',
- 'sources/sqleditor/filter_dialog',
- 'sources/sqleditor/new_connection_dialog',
- 'sources/sqleditor/geometry_viewer',
- 'sources/sqleditor/history/history_collection.js',
- 'sources/sqleditor/history/query_history',
- 'sources/sqleditor/history/query_sources',
- 'sources/keyboard_shortcuts',
- 'sources/sqleditor/query_tool_actions',
- 'sources/sqleditor/query_tool_notifications',
- 'pgadmin.datagrid',
- 'sources/modify_animation',
- 'sources/sqleditor/calculate_query_run_time',
- 'sources/sqleditor/call_render_after_poll',
- 'sources/sqleditor/query_tool_preferences',
- 'sources/sqleditor/query_txn_status_constants',
- 'sources/csrf',
- 'tools/datagrid/static/js/datagrid_panel_title',
- 'sources/window',
- 'sources/is_native',
- 'sources/sqleditor/macro',
- 'pgadmin.authenticate.kerberos',
- 'sources/../bundle/slickgrid',
- 'pgadmin.file_manager',
- 'slick.pgadmin.formatters',
- 'slick.pgadmin.editors',
- 'slick.pgadmin.plugins/slick.autocolumnsize',
- 'pgadmin.browser',
- 'pgadmin.tools.user_management',
-], function(
- gettext, url_for, $, jqueryui, jqueryui_position, _, alertify, pgAdmin, Backbone, codemirror, pgadminUtils,
- pgExplain, current_user, GridSelector, ActiveCellCapture, clipboard, copyData, RangeSelectionHelper, handleQueryOutputKeyboardEvent,
- XCellSelectionModel, setStagedRows, SqlEditorUtils, ExecuteQuery, httpErrorHandler, FilterHandler, newConnectionHandler,
- GeometryViewer, historyColl, queryHist, querySources,
- keyboardShortcuts, queryToolActions, queryToolNotifications, Datagrid,
- modifyAnimation, calculateQueryRunTime, callRenderAfterPoll, queryToolPref, queryTxnStatus, csrfToken, panelTitleFunc,
- pgWindow, isNative, MacroHandler, Kerberos) {
- /* Return back, this has been called more than once */
- if (pgAdmin.SqlEditor)
- return pgAdmin.SqlEditor;
-
- // Some scripts do export their object in the window only.
- // Generally the one, which do no have AMD support.
- var wcDocker = window.wcDocker,
- pgBrowser = pgAdmin.Browser,
- CodeMirror = codemirror.default,
- Slick = window.Slick,
- HistoryCollection = historyColl.default,
- QueryHistory = queryHist.default,
- QuerySources = querySources.QuerySources;
-
- csrfToken.setPGCSRFToken(pgAdmin.csrf_token_header, pgAdmin.csrf_token);
-
- var is_query_running = false;
-
- const EMPTY_DATA_OUTPUT_CONTENT = '' +
- gettext('No data output. Execute a query to get output.') +
- '
';
-
- const EMPTY_EXPLAIN_CONTENT = '' +
- gettext('Use Explain/Explain analyze button to generate the plan for a query. Alternatively, you can also execute "EXPLAIN (FORMAT JSON) [QUERY]".') +
- '
';
-
- // Defining Backbone view for the sql grid.
- var SQLEditorView = Backbone.View.extend({
- initialize: function(opts) {
- this.$el = opts.el;
- this.handler = opts.handler;
- this.handler['col_size'] = {};
- let browser = pgWindow.default.pgAdmin.Browser;
- this.preferences = browser.get_preferences_for_module('sqleditor');
- this.browser_preferences = browser.get_preferences_for_module('browser');
- this.handler.preferences = this.preferences;
- this.handler.browser_preferences = this.browser_preferences;
- this.connIntervalId = null;
- this.layout = opts.layout;
- this.set_server_version(opts.server_ver);
- this.trigger('pgadmin-sqleditor:view:initialised');
- this.connection_list = [
- {'server_group': null,'server': null, 'database': null, 'user': null, 'role': null, 'conn_title': '<' + gettext('New Connection') + '>'},
- ];
- },
-
- // Bind all the events
- events: {
- 'click #btn-show-query-tool': 'on_show_query_tool',
- 'click .btn-load-file': 'on_file_load',
- 'click #btn-save-file': 'on_save_file',
- 'click #btn-file-menu-save': 'on_save_file',
- 'click #btn-file-menu-save-as': 'on_save_as',
- 'click #btn-find': 'on_find',
- 'click #btn-find-menu-find': 'on_find',
- 'click #btn-find-menu-find-next': 'on_find_next',
- 'click #btn-find-menu-find-previous': 'on_find_previous',
- 'click #btn-find-menu-replace': 'on_replace',
- 'click #btn-find-menu-replace-all': 'on_replace_all',
- 'click #btn-find-menu-find-persistent': 'on_find_persistent',
- 'click #btn-find-menu-jump': 'on_jump',
- 'click #btn-delete-row': 'on_delete',
- 'click #btn-save-data': 'on_save_data',
- 'click #btn-filter': 'on_show_filter',
- 'click #btn-filter-menu': 'on_show_filter',
- 'click #btn-include-filter': 'on_include_filter',
- 'click #btn-exclude-filter': 'on_exclude_filter',
- 'click #btn-remove-filter': 'on_remove_filter',
- 'click #btn-cancel': 'on_cancel',
- 'click #btn-copy-row': 'on_copy_row',
- 'click #btn-copy-with-header': 'on_copy_row_with_header',
- 'click #btn-paste-row': 'on_paste_row',
- 'click #btn-flash': 'on_flash',
- 'click #btn-flash-menu': 'on_flash',
- 'click #btn-cancel-query': 'on_cancel_query',
- 'click #btn-save-results-to-file': 'on_download',
- 'click #btn-clear': 'on_clear',
- 'click #btn-auto-commit': 'on_auto_commit',
- 'click #btn-auto-rollback': 'on_auto_rollback',
- 'click #btn-clear-history': 'on_clear_history',
- 'click .noclose': 'do_not_close_menu',
- 'click #btn-explain': 'on_explain',
- 'click #btn-explain-analyze': 'on_explain_analyze',
- 'click #btn-explain-verbose': 'on_explain_verbose',
- 'click #btn-explain-costs': 'on_explain_costs',
- 'click #btn-explain-buffers': 'on_explain_buffers',
- 'click #btn-explain-timing': 'on_explain_timing',
- 'click #btn-explain-summary': 'on_explain_summary',
- 'click #btn-explain-settings': 'on_explain_settings',
- 'change .limit': 'on_limit_change',
- 'keydown': 'keyAction',
- // Comment options
- 'click #btn-comment-code': 'on_toggle_comment_block_code',
- 'click #btn-toggle-comment-block': 'on_toggle_comment_block_code',
- 'click #btn-comment-line': 'on_comment_line_code',
- 'click #btn-uncomment-line': 'on_uncomment_line_code',
- // Indentation options
- 'click #btn-indent-code': 'on_indent_code',
- 'click #btn-unindent-code': 'on_unindent_code',
- // Format
- 'click #btn-format-sql': 'on_format_sql',
- // Transaction control
- 'click #btn-commit': 'on_commit_transaction',
- 'click #btn-rollback': 'on_rollback_transaction',
- // Manage Macros
- 'click #btn-manage-macros': 'on_manage_macros',
- 'click .btn-macro': 'on_execute_macro',
- },
-
- render_connection: function(data_list) {
- if(this.handler.is_query_tool) {
- var dropdownElement = document.getElementById('connections-list');
- dropdownElement.innerHTML = '';
- data_list.forEach((option, index) => {
- var opt = '';
- if ('is_selected' in option && option['is_selected']) {
- opt = ''+ _.escape(option.conn_title) +' ';
- } else {
- opt = ''+ _.escape(option.conn_title) +' ';
- }
- $('#connections-list').append(opt);
- });
- var self = this;
- $('.connection-list-item').click(function() {
- self.get_connection_data(this);
- });
- } else {
- $('.conn-info-dd').hide();
- $('.connection-data').css({pointerEvents: 'none', cursor: 'arrow'});
- }
- },
-
- get_connection_data: function(event){
- var index = $(event).attr('data-index');
- var connection_details = this.connection_list[index];
- if(connection_details.server_group) {
- this.on_change_connection(connection_details);
- } else {
- this.on_new_connection();
- }
-
- },
-
- reflectPreferences: function() {
- let self = this,
- browser = pgWindow.default.pgAdmin.Browser,
- browser_preferences = browser.get_preferences_for_module('browser');
-
- /* pgBrowser is different obj from pgWindow.default.pgAdmin.Browser
- * Make sure to get only the latest update. Older versions will be discarded
- * if function is called by older events.
- * This works for new tab sql editor also as it polls if latest version available
- * This is required because sql editor can update preferences directly
- */
- if(pgBrowser.preference_version() < browser.preference_version()){
- pgBrowser.preference_version(browser.preference_version());
- self.preferences = browser.get_preferences_for_module('sqleditor');
- self.preferences.show_query_tool = browser_preferences.sub_menu_query_tool;
- self.handler.preferences = self.preferences;
- queryToolPref.updateUIPreferences(self);
- }
- },
-
- buildDefaultLayout: function(docker) {
- let sql_panel_obj = docker.addPanel('sql_panel', wcDocker.DOCK.TOP);
-
- docker.addPanel('scratch', wcDocker.DOCK.RIGHT, sql_panel_obj);
- docker.addPanel('history', wcDocker.DOCK.STACKED, sql_panel_obj);
-
- let data_output_panel = docker.addPanel('data_output', wcDocker.DOCK.BOTTOM);
- docker.addPanel('explain', wcDocker.DOCK.STACKED, data_output_panel);
- docker.addPanel('messages', wcDocker.DOCK.STACKED, data_output_panel);
- docker.addPanel('notifications', wcDocker.DOCK.STACKED, data_output_panel);
- },
-
- set_server_version: function(server_ver) {
- let self = this;
- self.server_ver = server_ver;
-
- this.$el.find('*[data-min-ver]').map(function() {
- let minVer = 0,
- ele = $(this);
- minVer = parseInt(ele.attr('data-min-ver'));
- if(minVer > self.server_ver) {
- ele.addClass('d-none');
- } else {
- ele.removeClass('d-none');
- }
- });
- },
-
- set_editor_title: function(title) {
- this.$el.find('.editor-title').text(_.unescape(title));
- this.render_connection(this.connection_list);
- },
-
- // This function is used to render the template.
- render: function() {
- var self = this;
-
- // Updates connection status flag
- self.gain_focus = function() {
- setTimeout(function() {
- SqlEditorUtils.updateConnectionStatusFlag('visible');
- }, 100);
- };
- // Updates connection status flag
- self.lost_focus = function() {
- setTimeout(function() {
- SqlEditorUtils.updateConnectionStatusFlag('hidden');
- }, 100);
- };
-
- // Create main wcDocker instance
- self.docker = new wcDocker(
- '#editor-panel', {
- allowContextMenu: true,
- allowCollapse: false,
- loadingClass: 'pg-sp-icon',
- themePath: url_for('static', {
- 'filename': 'css',
- }),
- theme: 'webcabin.overrides.css',
- }
- );
-
- // Create the panels
- var sql_panel = new pgAdmin.Browser.Panel({
- name: 'sql_panel',
- title: gettext('Query Editor'),
- width: '75%',
- height: '33%',
- isCloseable: false,
- isPrivate: true,
- });
-
- var data_output = new pgAdmin.Browser.Panel({
- name: 'data_output',
- title: gettext('Data Output'),
- width: '100%',
- height: '100%',
- isCloseable: false,
- isPrivate: true,
- extraClasses: 'hide-vertical-scrollbar',
- content: `
-
-
${EMPTY_DATA_OUTPUT_CONTENT}
-
`,
- });
-
- var explain = new pgAdmin.Browser.Panel({
- name: 'explain',
- title: gettext('Explain'),
- width: '100%',
- height: '100%',
- isCloseable: false,
- isPrivate: true,
- content: `${EMPTY_EXPLAIN_CONTENT}
`,
- });
-
- var messages = new pgAdmin.Browser.Panel({
- name: 'messages',
- title: gettext('Messages'),
- width: '100%',
- height: '100%',
- isCloseable: false,
- isPrivate: true,
- content: '
',
- });
-
- var history = new pgAdmin.Browser.Panel({
- name: 'history',
- title: gettext('Query History'),
- width: '100%',
- height: '33%',
- isCloseable: false,
- isPrivate: true,
- content: '
',
- });
-
- var scratch = new pgAdmin.Browser.Panel({
- name: 'scratch',
- title: gettext('Scratch Pad'),
- width: '25%',
- height: '33%',
- isCloseable: true,
- isPrivate: false,
- content: '
',
- });
-
- var notifications = new pgAdmin.Browser.Panel({
- name: 'notifications',
- title: gettext('Notifications'),
- width: '100%',
- height: '100%',
- isCloseable: false,
- isPrivate: true,
- content: '
',
- });
-
- var geometry_viewer = new pgAdmin.Browser.Panel({
- name: 'geometry_viewer',
- title: gettext('Geometry Viewer'),
- width: '100%',
- height: '100%',
- isCloseable: true,
- isPrivate: true,
- isLayoutMember: false,
- content: '
',
- });
-
- // Load all the created panels
- sql_panel.load(self.docker);
- data_output.load(self.docker);
- explain.load(self.docker);
- messages.load(self.docker);
- history.load(self.docker);
- scratch.load(self.docker);
- notifications.load(self.docker);
- geometry_viewer.load(self.docker);
-
- // restore the layout if present else fallback to buildDefaultLayout
- pgBrowser.restore_layout(self.docker, this.layout, this.buildDefaultLayout.bind(this));
-
- self.docker.on(wcDocker.EVENT.LAYOUT_CHANGED, function() {
- pgBrowser.save_current_layout('SQLEditor/Layout', self.docker);
- });
-
- self.sql_panel_obj = self.docker.findPanels('sql_panel')[0];
- self.history_panel = self.docker.findPanels('history')[0];
- self.data_output_panel = self.docker.findPanels('data_output')[0];
- self.explain_panel = self.docker.findPanels('explain')[0];
- self.messages_panel = self.docker.findPanels('messages')[0];
- self.notifications_panel = self.docker.findPanels('notifications')[0];
-
- if (_.isUndefined(self.sql_panel_obj) || _.isUndefined(self.history_panel) ||
- _.isUndefined(self.data_output_panel) || _.isUndefined(self.explain_panel) ||
- _.isUndefined(self.messages_panel) || _.isUndefined(self.notifications_panel)) {
- Notify.alert(
- gettext('Panel Loading Error'),
- gettext('Something went wrong while loading the panels.'
- + ' Please make sure to reset the layout (File > Reset Layout) for the better user experience.')
- );
- }
-
- // Refresh Code mirror on SQL panel resize to
- // display its value properly
- self.sql_panel_obj.on(wcDocker.EVENT.RESIZE_ENDED, function() {
- setTimeout(function() {
- if (self && self.query_tool_obj) {
- self.query_tool_obj.refresh();
- }
- }, 200);
- });
-
- self.render_history_grid();
- pgBrowser.Events.on('pgadmin:query_tool:connected:'+self.handler.transId, ()=>{
- self.fetch_query_history();
- });
-
- self.handler.on('pgadmin-sqleditor:check_synchronous_db_name_change', (result)=>{
- self.handler.check_db_name_change(result);
- });
-
- queryToolNotifications.renderNotificationsGrid(self.notifications_panel);
-
- var text_container = $(' ');
- var output_container = $('SQL Editor
').append(text_container);
- self.sql_panel_obj.$container.find('.pg-panel-content').append(output_container);
-
- self.query_tool_obj = CodeMirror.fromTextArea(text_container.get(0), {
- tabindex: '0',
- lineNumbers: true,
- styleSelectedText: true,
- mode: 'text/x-pgsql',
- foldOptions: {
- widget: '\u2026',
- },
- foldGutter: true,
- gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
- extraKeys: pgBrowser.editor_shortcut_keys,
- scrollbarStyle: 'simple',
- dragDrop: false,
- screenReaderLabel: gettext('SQL editor'),
- });
-
- if(self.handler.is_query_tool) {
- self.query_tool_obj.setOption('dragDrop', true);
- self.query_tool_obj.on('drop', (editor, e) => {
- var dropDetails = null;
- try {
- dropDetails = JSON.parse(e.dataTransfer.getData('text'));
-
- /* Stop firefox from redirecting */
-
- if(e.preventDefault) {
- e.preventDefault();
- }
- if (e.stopPropagation) {
- e.stopPropagation();
- }
- } catch(error) {
- /* if parsing fails, it must be the drag internal of codemirror text */
- return;
- }
-
- var cursor = editor.coordsChar({
- left: e.x,
- top: e.y,
- });
- editor.replaceRange(dropDetails.text, cursor);
- editor.focus();
- editor.setSelection({
- ...cursor,
- ch: cursor.ch + dropDetails.cur.from,
- },{
- ...cursor,
- ch: cursor.ch +dropDetails.cur.to,
- });
- });
- }
-
- pgBrowser.Events.on('pgadmin:query_tool:sql_panel:focus', ()=>{
- self.query_tool_obj.focus();
- });
-
- pgBrowser.Events.on('pgadmin:query_tool:explain:focus', ()=>{
- setTimeout(function () {
- $('.sql-editor-explain .backform-tab .nav-link.active').focus();
- }, 200);
- });
-
- // Prevent browser from opening the drag file.
- $('#datagrid').bind('dragover drop', function (event) {
- event.stopPropagation();
- event.preventDefault();
- });
-
- var open_new_tab = self.browser_preferences.new_browser_tab_open;
- if (_.isNull(open_new_tab) || _.isUndefined(open_new_tab) || !open_new_tab.includes('qt')) {
- // Listen on the panel closed event and notify user to save modifications.
- _.each(pgWindow.default.pgAdmin.Browser.docker.findPanels('frm_datagrid'), function(p) {
- if (p.trans_id == self.transId) {
- self.currentPanel = p;
- p.on(wcDocker.EVENT.CLOSING, function() {
- return self.handler.check_needed_confirmations_before_closing_panel(true);
- });
-
- // Set focus on query tool of active panel
- p.on(wcDocker.EVENT.GAIN_FOCUS, function() {
- var $container = $(this.$container),
- transId = self.handler.transId;
-
- if (!$container.hasClass('wcPanelTabContentHidden')) {
-
- let modal_list = ['fileSelectionDlg', 'createModeDlg',
- 'confirm', 'alert', 'confirmSave', 'newConnectionDialog',
- 'macroDialog'];
-
- /* check the modals inside the sqleditor are open, if not,
- focus on the editor instead. */
- if(!SqlEditorUtils.isModalOpen(modal_list)) {
- setTimeout(function () {
- self.handler.gridView.query_tool_obj.focus();
- }, 200);
-
- // Trigger an event to update connection status flag
- pgBrowser.Events.trigger(
- 'pgadmin:query_tool:panel:gain_focus:' + transId
- );
- }
- }
- });
-
- // When any query tool panel lost it focus then
- p.on(wcDocker.EVENT.LOST_FOCUS, function () {
- var $container = $(this.$container),
- transId = self.handler.transId;
- // Trigger an event to update connection status flag
- if ($container.hasClass('wcPanelTabContentHidden')) {
- pgBrowser.Events.trigger(
- 'pgadmin:query_tool:panel:lost_focus:' + transId
- );
- }
- });
- }
- });
-
- // Code to update connection status polling flag
- pgBrowser.Events.on(
- 'pgadmin:query_tool:panel:gain_focus:' + self.handler.transId,
- self.gain_focus, self
- );
- pgBrowser.Events.on(
- 'pgadmin:query_tool:panel:lost_focus:' + self.handler.transId,
- self.lost_focus, self
- );
- }
-
- // set focus on query tool once loaded
- setTimeout(function() {
- self.query_tool_obj.focus();
- }, 500);
-
- /* We have override/register the hint function of CodeMirror
- * to provide our own hint logic.
- */
- CodeMirror.registerHelper('hint', 'sql', function(editor) {
- var data = [],
- doc = editor.getDoc(),
- cur = doc.getCursor(),
- // Get the current cursor position
- current_cur = cur.ch,
- // function context
- ctx = {
- editor: editor,
- // URL for auto-complete
- url: url_for('sqleditor.autocomplete', {
- 'trans_id': self.transId,
- }),
- data: data,
- // Get the line number in the cursor position
- current_line: cur.line,
- /*
- * Render function for hint to add our own class
- * and icon as per the object type.
- */
- hint_render: function(elt, data_arg, cur_arg) {
- var el = document.createElement('span');
-
- switch (cur_arg.type) {
- case 'database':
- el.className = 'sqleditor-hint pg-icon-' + cur_arg.type;
- break;
- case 'datatype':
- el.className = 'sqleditor-hint icon-type';
- break;
- case 'keyword':
- el.className = 'fa fa-key';
- break;
- case 'table alias':
- el.className = 'fa fa-at';
- break;
- default:
- el.className = 'sqleditor-hint icon-' + cur_arg.type;
- }
-
- el.appendChild(document.createTextNode(cur_arg.text));
- elt.appendChild(el);
- },
- };
-
- data.push(doc.getValue());
- // Get the text from start to the current cursor position.
- data.push(
- doc.getRange({
- line: 0,
- ch: 0,
- }, {
- line: ctx.current_line,
- ch: current_cur,
- })
- );
-
- return {
- then: function(cb) {
- var self_local = this;
- // Make ajax call to find the autocomplete data
- $.ajax({
- url: self_local.url,
- method: 'POST',
- contentType: 'application/json',
- data: JSON.stringify(self_local.data),
- })
- .done(function(res) {
- var result = [];
-
- _.each(res.data.result, function(obj, key) {
- result.push({
- text: key,
- type: obj.object_type,
- render: self_local.hint_render,
- });
- });
-
- // Sort function to sort the suggestion's alphabetically.
- result.sort(function(a, b) {
- var textA = a.text.toLowerCase(),
- textB = b.text.toLowerCase();
- if (textA < textB) //sort string ascending
- return -1;
- if (textA > textB)
- return 1;
- return 0; //default return value (no sorting)
- });
-
- /*
- * Below logic find the start and end point
- * to replace the selected auto complete suggestion.
- */
- var token = self_local.editor.getTokenAt(cur),
- start, end, search;
- if (token.end > cur.ch) {
- token.end = cur.ch;
- token.string = token.string.slice(0, cur.ch - token.start);
- }
-
- if (token.string.match(/^[.`\w@]\w*$/)) {
- search = token.string;
- start = token.start;
- end = token.end;
- } else {
- start = end = cur.ch;
- search = '';
- }
-
- /*
- * Added 1 in the start position if search string
- * started with "." or "`" else auto complete of code mirror
- * will remove the "." when user select any suggestion.
- */
- if (search.charAt(0) == '.' || search.charAt(0) == '``')
- start += 1;
-
- cb({
- list: result,
- from: {
- line: self_local.current_line,
- ch: start,
- },
- to: {
- line: self_local.current_line,
- ch: end,
- },
- });
- })
- .fail(function(e) {
- return httpErrorHandler.handleLoginRequiredAndTransactionRequired(
- pgAdmin, self_local, e, null, [], false
- );
- });
- }.bind(ctx),
- };
- });
-
- /* If the screen width is small and we hover over the Explain Options,
- * the submenu goes behind the screen on the right side.
- * Below logic will make it appear on the left.
- */
- $('.dropdown-submenu').on('mouseenter',function() {
- var menu = $(this).find('ul.dropdown-menu');
- var menupos = $(menu).offset();
-
- if (menupos.left + menu.width() > $(window).width()) {
- var newpos = -$(menu).width();
- menu.css('left',newpos);
- }
- }).on('mouseleave', function() {
- var menu = $(this).find('ul.dropdown-menu');
- menu.css('left','');
- });
-
- self.reflectPreferences();
-
- /* Set Auto-commit and auto-rollback on query editor */
- if (self.preferences.auto_commit) {
- $('.auto-commit').removeClass('visibility-hidden');
- }
- else {
- $('.auto-commit').addClass('visibility-hidden');
- }
- if (self.preferences.auto_rollback) {
- $('.auto-rollback').removeClass('visibility-hidden');
- }
- else {
- $('.auto-rollback').addClass('visibility-hidden');
- }
-
- /* Register for preference changed event broadcasted in parent
- * to reload the shorcuts. As sqleditor is in iFrame of wcDocker
- * window parent is referred
- */
- pgWindow.default.pgAdmin.Browser.onPreferencesChange('sqleditor', function() {
- self.reflectPreferences();
- });
-
- /* If sql editor is in a new tab, event fired is not available
- * instead, a poller is set up who will check
- */
- var open_new_tab_qt = self.browser_preferences.new_browser_tab_open;
- if(open_new_tab_qt && open_new_tab_qt.includes('qt')) {
- pgBrowser.bind_beforeunload();
- setInterval(()=>{
- if(pgWindow.default.pgAdmin) {
- self.reflectPreferences();
- }
- }, 1000);
- }
-
- /* Register to log the activity */
- pgBrowser.register_to_activity_listener(document, ()=>{
- Notify.alert(gettext('Timeout'), gettext('Your session has timed out due to inactivity. Please close the window and login again.'));
- });
-
- self.render_connection(self.connection_list);
- },
-
- /* Regarding SlickGrid usage in render_grid function.
-
- SlickGrid Plugins:
- ------------------
- 1) Slick.AutoTooltips
- - This plugin is useful for displaying cell data as tooltip when
- user hover mouse on cell if data is large
- 2) Slick.CheckboxSelectColumn
- - This plugin is useful for selecting rows using checkbox
- 3) RowSelectionModel
- - This plugin is needed by CheckboxSelectColumn plugin to select rows
- 4) Slick.HeaderButtons
- - This plugin is useful for add buttons in column header
-
- Grid Options:
- -------------
- 1) editable
- - This option allow us to make grid editable
- 2) enableAddRow
- - This option allow us to add new rows at the end of grid
- 3) enableCellNavigation
- - This option allow us to navigate cells using keyboard
- 4) enableColumnReorder
- - This option allow us to record column
- 5) asyncEditorLoading
- - This option allow us to open editor async
- 6) autoEdit
- - This option allow us to enter in edit mode directly when user clicks on it
- otherwise user have to double click or manually press enter on cell to go
- in cell edit mode
-
- Handling of data:
- -----------------
- We are doing data handling manually,what user adds/updates/deletes etc
- we will use `data_store` object to store everything user does within grid data
-
- - updated:
- This will hold all the data which user updates in grid
- - added:
- This will hold all the new row(s) data which user adds in grid
- - staged_rows:
- This will hold all the data which user copies/pastes/deletes in grid
- - deleted:
- This will hold all the data which user deletes in grid
-
- Events handling:
- ----------------
- 1) onCellChange
- - We are using this event to listen to changes on individual cell.
- 2) onAddNewRow
- - We are using this event to listen to new row adding functionality.
- 3) onSelectedRangesChanged
- - We are using this event to listen when user selects rows for copy/delete operation.
- 4) onBeforeEditCell
- - We are using this event to save the data before users modified them
- 5) onKeyDown
- - We are using this event for Copy operation on grid
- */
-
- // This function is responsible to create and render the SlickGrid.
- render_grid: function(collection, columns, is_editable, client_primary_key, rows_affected) {
- var self = this;
-
- self.handler.numberOfModifiedCells = 0;
-
- self.handler.reset_data_store();
-
- // keep track of newly added rows
- self.handler.rows_to_disable = new Array();
- // Temporarily hold new rows added
- self.handler.temp_new_rows = new Array();
-
- // To store primary keys before they gets changed
- self.handler.primary_keys_data = {};
-
- self.client_primary_key = client_primary_key;
-
- self.client_primary_key_counter = 0;
-
- // Remove any existing grid first
- if (self.handler.slickgrid) {
- self.handler.slickgrid.destroy();
- }
-
- if (!_.isArray(collection) || !_.size(collection)) {
- collection = [];
- }
-
- var grid_columns = [],
- table_name;
- var column_size = self.handler['col_size'],
- query = self.handler.query,
- // Extract table name from query
- table_list = query.match(/select.*from\s+\w+\.*(\w+)/i);
-
- if (!table_list) {
- table_name = SqlEditorUtils.getHash(query);
- } else {
- table_name = table_list[1];
- }
-
- self.handler['table_name'] = table_name;
- column_size[table_name] = column_size[table_name] || {};
-
- // Keep track of column_data_auto_resize preferences value
- if (_.isUndefined(self.auto_resize_column_based_on_data) || self.auto_resize_column_based_on_data !== self.preferences.column_data_auto_resize) {
- self.auto_resize_column_based_on_data = self.preferences.column_data_auto_resize;
- column_size[table_name] = {};
- }
-
- // Keep track of column_data_max_width
- self.max_width_changed = false;
- if (_.isUndefined(self.old_column_data_max_width) || self.old_column_data_max_width != self.preferences.column_data_max_width) {
- self.old_column_data_max_width = self.preferences.column_data_max_width;
- self.max_width_changed = true;
- }
-
-
- _.each(columns, function(c) {
- c.display_name = _.escape(c.display_name);
- c.column_type = _.escape(c.column_type);
-
- // If the keys have name from existing JS keywords then it may
- // create problem. eg - contructor, hasOwnProperty.
- // nonative_field is field with extra double quotes
- var options = {
- id: _.escape(c.name),
- pos: c.pos,
- field: c.name,
- nonative_field: `"${c.name}"`,
- name: c.label,
- display_name: c.display_name,
- column_type: c.column_type,
- column_type_internal: c.column_type_internal,
- cell: c.cell,
- not_null: c.not_null,
- has_default_val: c.has_default_val,
- is_array: c.is_array,
- can_edit: c.can_edit,
- };
-
- // Get the columns width based on longer string among data type or
- // column name.
- var column_type = c.column_type.trim();
- var label = c.name.length > column_type.length ? _.escape(c.display_name) : column_type;
- var iconWidth = 0;
- // increase width to add 'view' button
- if (c.cell == 'geometry' || c.cell == 'geography') {
- iconWidth += 28;
- }
- // Increase width for editable/read-only icon
- if(!_.isUndefined(c.can_edit)) {
- iconWidth += 12;
- }
-
- if (_.isUndefined(column_size[table_name][options.nonative_field])) {
- /* If column_data_auto_resize is 'by_data' then for the first time set
- * the addWidth parameter to iconWidth and if it is 'by_name' then
- * calculate width based on longer string among data type or
- * column name.
- */
- if (self.preferences.column_data_auto_resize === 'by_data') {
- options['addWidth'] = iconWidth;
- options['width'] = NaN;
- } else {
- options['width'] = SqlEditorUtils.calculateColumnWidth(label);
- options['width'] += iconWidth;
- column_size[table_name][c.nonative_field] = options['width'];
- }
- } else {
- options['width'] = column_size[table_name][options.nonative_field];
- }
-
- // If grid is editable then add editor else make it readonly
- if (c.cell == 'oid' && c.name == 'oid') {
- options['editor'] = null;
- } else if (c.cell == 'Json') {
- options['editor'] = c.can_edit ? Slick.Editors.JsonText :
- Slick.Editors.ReadOnlyJsonText;
- options['formatter'] = Slick.Formatters.JsonString;
- } else if (c.cell == 'number' || c.cell == 'oid' ||
- $.inArray(c.type, ['xid', 'real']) !== -1
- ) {
- options['editor'] = c.can_edit ? Slick.Editors.CustomNumber :
- Slick.Editors.ReadOnlyText;
- options['formatter'] = Slick.Formatters.Numbers;
- } else if (c.cell == 'boolean') {
- options['editor'] = c.can_edit ? Slick.Editors.Checkbox :
- Slick.Editors.ReadOnlyCheckbox;
- options['formatter'] = Slick.Formatters.Checkmark;
- } else if (c.cell == 'binary') {
- // We do not support editing binary data in SQL editor and data grid.
- options['formatter'] = Slick.Formatters.Binary;
- } else if (c.cell == 'geometry' || c.cell == 'geography') {
- // increase width to add 'view' button
- options['can_edit'] = false;
- } else {
- options['editor'] = c.can_edit ? Slick.Editors.pgText :
- Slick.Editors.ReadOnlypgText;
- options['formatter'] = Slick.Formatters.Text;
- }
-
- if(!_.isUndefined(c.can_edit)) {
- let tooltip = '';
- if(c.can_edit)
- tooltip = gettext('Editable column');
- else
- tooltip = gettext('Read-only column');
-
- options['toolTip'] = tooltip;
- }
-
- grid_columns.push(options);
- });
-
- var gridSelector = new GridSelector();
- grid_columns = self.grid_columns = gridSelector.getColumnDefinitions(grid_columns);
-
- _.each(grid_columns, function (c) {
- // Add 'view' button in geometry and geography type column headers
- if (c.column_type_internal == 'geometry' || c.column_type_internal == 'geography') {
- GeometryViewer.add_header_button(c);
- }
- // Add editable/read-only icon to columns
- if (!_.isUndefined(c.can_edit)) {
- SqlEditorUtils.addEditableIcon(c, c.can_edit);
- }
- });
-
- if (rows_affected) {
- // calculate with for header row column.
- grid_columns[0]['width'] = SqlEditorUtils.calculateColumnWidth(rows_affected);
- }
-
- var grid_options = {
- editable: true,
- enableAddRow: is_editable,
- enableCellNavigation: true,
- enableColumnReorder: false,
- asyncEditorLoading: false,
- autoEdit: false,
- };
-
- var $data_grid = $('#datagrid');
- // Calculate height based on panel size at runtime & set it
- var grid_height = $(this.data_output_panel.$container.parent().parent()).height() - 35;
- $data_grid.height(grid_height);
-
- var dataView = self.dataView = new Slick.Data.DataView(),
- grid = self.grid = new Slick.Grid($data_grid, dataView, grid_columns, grid_options);
-
- // Add-on function which allow us to identify the faulty row after insert/update
- // and apply css accordingly
-
- dataView.getItemMetadata = function(rows) {
- var cssClass = '',
- data_store = self.handler.data_store;
-
- if (_.has(self.handler, 'data_store')) {
- if (rows in data_store.added_index &&
- data_store.added_index[rows] in data_store.added) {
- cssClass = 'new_row';
- if (data_store.added[data_store.added_index[rows]].err) {
- cssClass += ' error';
- }
- } else if (rows in data_store.updated_index && rows in data_store.updated) {
- cssClass = 'updated_row';
- if (data_store.updated[data_store.updated_index[rows]].err) {
- cssClass += ' error';
- }
- }
- }
-
- // Disable rows having default values
- if (!_.isUndefined(self.handler.rows_to_disable) &&
- self.handler.rows_to_disable.length > 0 &&
- _.indexOf(self.handler.rows_to_disable, rows) !== -1) {
- cssClass += ' disabled_row';
- }
-
- return {
- 'cssClasses': cssClass,
- };
- };
-
- grid.registerPlugin(new Slick.AutoTooltips({
- enableForHeaderCells: false,
- }));
- grid.registerPlugin(new ActiveCellCapture());
- grid.setSelectionModel(new XCellSelectionModel());
- grid.registerPlugin(gridSelector);
- grid.registerPlugin(new Slick.AutoColumnSize());
- var headerButtonsPlugin = new Slick.Plugins.HeaderButtons();
- headerButtonsPlugin.onCommand.subscribe(function (e, args) {
- let command = args.command;
- if (command === 'view-geometries') {
- let cols = args.grid.getColumns();
- let columnIndex = cols.indexOf(args.column);
- let selectedRows = args.grid.getSelectedRows();
- if (selectedRows.length === 0) {
- // if no rows are selected, load and render all the rows
- if (self.handler.has_more_rows) {
- self.fetch_next_all(function () {
- // trigger onGridSelectAll manually with new event data.
- gridSelector.onGridSelectAll.notify(args, new Slick.EventData());
- let items = args.grid.getData().getItems();
- GeometryViewer.render_geometries(self.handler, items, cols, columnIndex);
- });
- } else {
- gridSelector.onGridSelectAll.notify(args, new Slick.EventData());
- let items = args.grid.getData().getItems();
- GeometryViewer.render_geometries(self.handler, items, cols, columnIndex);
- }
- } else {
- // render selected rows
- let items = args.grid.getData().getItems();
- let selectedItems = _.map(selectedRows, function (row) {
- return items[row];
- });
- GeometryViewer.render_geometries(self.handler, selectedItems, cols, columnIndex);
- }
- }
- });
- grid.registerPlugin(headerButtonsPlugin);
-
- var editor_data = {
- keys: (_.isEmpty(self.handler.primary_keys) && self.handler.has_oids) ? self.handler.oids : self.handler.primary_keys,
- vals: collection,
- columns: columns,
- grid: grid,
- selection: grid.getSelectionModel(),
- editor: self,
- client_primary_key: self.client_primary_key,
- has_oids: self.handler.has_oids,
- };
-
- self.handler.slickgrid = grid;
- // Add listener on data-grid table scroll.
- self.handler.slickgrid.onScroll.subscribe(function() {
- // Mark selected rows cells as selected.
- setTimeout(() => {
- // Can't use setSelectedRows as we are using cellSelectionModel.
- var cellSelectionModel = self.handler.gridView.grid.getSelectionModel();
- var ranges = cellSelectionModel.getSelectedRanges();
-
- if (ranges.length > 1) {
- // Set selected rows cell as selected.
- cellSelectionModel.setSelectedRanges(ranges);
- }
- }, 100);
-
- if(Object.keys(self.handler.data_store.deleted).length > 0) {
- setTimeout(() => {
- $(self.handler.gridView.grid.getCanvasNode()).find('div.selected').removeClass('strikeout');
- $(self.handler.gridView.grid.getCanvasNode()).find('div.selected').addClass('strikeout');
- }, 100);
- }
- });
- self.handler.slickgrid.CSVOptions = {
- quoting: self.preferences.results_grid_quoting,
- quote_char: self.preferences.results_grid_quote_char,
- field_separator: self.preferences.results_grid_field_separator,
- };
-
- // Listener function to watch selected rows from grid
- if (editor_data.selection) {
- editor_data.selection.onSelectedRangesChanged.subscribe(
- setStagedRows.bind(editor_data));
- }
-
- grid.onColumnsResized.subscribe(function() {
- var cols = this.getColumns();
- _.each(cols, function(col) {
- var col_size = self.handler['col_size'];
- col_size[self.handler['table_name']][col['nonative_field']] = col['width'];
- });
- }.bind(grid));
-
- gridSelector.onBeforeGridSelectAll.subscribe(function(e, args) {
- if (self.handler.has_more_rows) {
- // this will prevent selection un-till we load all data
- e.stopImmediatePropagation();
- self.fetch_next_all(function() {
- // since we've stopped event propagation we need to
- // trigger onGridSelectAll manually with new event data.
- gridSelector.onGridSelectAll.notify(args, new Slick.EventData());
- });
- }
- });
-
- gridSelector.onBeforeGridColumnSelectAll.subscribe(function(e, args) {
- if (self.handler.has_more_rows) {
- // this will prevent selection un-till we load all data
- e.stopImmediatePropagation();
- self.fetch_next_all(function() {
- // since we've stopped event propagation we need to
- // trigger onGridColumnSelectAll manually with new event data.
- gridSelector.onGridColumnSelectAll.notify(args, new Slick.EventData());
- });
- }
- });
-
- // listen for row count change.
- dataView.onRowCountChanged.subscribe(function() {
- grid.updateRowCount();
- grid.render();
- });
-
- // listen for rows change.
- dataView.onRowsChanged.subscribe(function(e, args) {
- grid.invalidateRows(args.rows);
- grid.render();
- // Resize all columns if column_data_auto_resize is 'by_data'.
- if (self.preferences.column_data_auto_resize === 'by_data') {
- grid.resizeAllColumns && grid.resizeAllColumns(self.preferences.column_data_max_width, self.max_width_changed);
- }
- });
-
- // Listener function which will be called before user updates existing cell
- // This will be used to collect primary key for that row
- grid.onBeforeEditCell.subscribe(function(e, args) {
- if (args.column.column_type_internal == 'bytea' ||
- args.column.column_type_internal == 'bytea[]') {
- return false;
- }
-
- var before_data = args.item;
-
- // If newly added row is saved but grid is not refreshed,
- // then disable cell editing for that row
- if (self.handler.rows_to_disable &&
- _.contains(self.handler.rows_to_disable, args.row)) {
- return false;
- }
-
- if (self.handler.can_edit && before_data && self.client_primary_key in before_data) {
- var _pk = before_data[self.client_primary_key],
- _keys = self.handler.primary_keys,
- current_pk = {};
-
- // If already have primary key data then no need to go ahead
- if (_pk in self.handler.primary_keys_data) {
- return;
- }
-
- // Fetch primary keys for the row before they gets modified
- _.each(_keys, function(value, key) {
- current_pk[key] = before_data[key];
- });
- // Place it in main variable for later use
- self.handler.primary_keys_data[_pk] = current_pk;
- }
- });
-
- grid.onKeyDown.subscribe(function(event, args) {
- var KEY_A = 65;
- var modifiedKey = event.keyCode;
- var isModifierDown = event.ctrlKey || event.metaKey;
- // Intercept Ctrl/Cmd + A key board event.
- // As we might want to load all rows before selecting all.
- if (isModifierDown && modifiedKey == KEY_A && self.handler.has_more_rows) {
- self.fetch_next_all(function() {
- handleQueryOutputKeyboardEvent(event, args);
- });
- } else {
- handleQueryOutputKeyboardEvent(event, args);
- }
- });
-
- // Handles blur event for slick grid cell
- $('.slick-viewport').on('blur', 'input.editor-text', function () {
- window.setTimeout(function() {
- if (Slick.GlobalEditorLock.isActive())
- Slick.GlobalEditorLock.commitCurrentEdit();
- });
- });
-
- // Listener function which will be called when user updates existing rows
- grid.onCellChange.subscribe(function(e, args) {
- // self.handler.data_store.updated will holds all the updated data
- var changed_column = args.grid.getColumns()[args.cell].field,
- updated_data = args.item[changed_column], // New value for current field
- _pk = args.item[self.client_primary_key] || null, // Unique key to identify row
- column_data = {};
-
- // Highlight the changed cell
- self.handler.numberOfModifiedCells++;
- args.grid.addCellCssStyles(self.handler.numberOfModifiedCells, {
- [args.row] : {
- [changed_column]: 'highlighted_grid_cells',
- },
- });
-
- // Access to row/cell value after a cell is changed.
- // The purpose is to remove row_id from temp_new_row
- // if new row has primary key instead of [default_value]
- // so that cell edit is enabled for that row.
- var grid_edit = args.grid,
- row_data = grid_edit.getDataItem(args.row),
- is_primary_key = self.primary_keys &&
- _.all(
- _.values(
- _.pick(
- row_data, self.primary_keys
- )
- ),
- function(val) {
- return val != undefined;
- }
- );
-
- // temp_new_rows is available only for view data.
- if (is_primary_key && self.handler.temp_new_rows) {
- var index = self.handler.temp_new_rows.indexOf(args.row);
- if (index > -1) {
- self.handler.temp_new_rows.splice(index, 1);
- }
- }
-
- column_data[changed_column] = updated_data;
-
-
- if (_pk) {
- // Check if it is in newly added row by user?
- if (_pk in self.handler.data_store.added) {
- _.extend(
- self.handler.data_store.added[_pk]['data'],
- column_data);
- //Find type for current column
- self.handler.data_store.added[_pk]['err'] = false;
- // Check if it is updated data from existing rows?
- } else if (_pk in self.handler.data_store.updated) {
- _.extend(
- self.handler.data_store.updated[_pk]['data'],
- column_data
- );
- self.handler.data_store.updated[_pk]['err'] = false;
- } else {
- // First updated data for this primary key
- self.handler.data_store.updated[_pk] = {
- 'err': false,
- 'data': column_data,
- 'primary_keys': self.handler.primary_keys_data[_pk],
- };
- self.handler.data_store.updated_index[args.row] = _pk;
- }
- }
- // Enable save button
- $('#btn-save-data').prop('disabled', false);
- }.bind(editor_data));
-
- // Listener function which will be called when user adds new rows
- grid.onAddNewRow.subscribe(function(e, args) {
- // self.handler.data_store.added will holds all the newly added rows/data
- var column = args.column,
- item_current = args.item,
- data_length = this.grid.getDataLength(),
- _key = (self.client_primary_key_counter++).toString(),
- data_view = this.grid.getData();
-
- // Add new row in list to keep track of it
- if (_.isUndefined(item_current[0])) {
- self.handler.temp_new_rows.push(data_length);
- }
-
- // If copied item has already primary key, use it.
- if (item_current) {
- item_current[self.client_primary_key] = _key;
- }
-
- // When adding new rows, mark all native JS keywords undefined if not already set
- _.each(args.grid.getColumns(), function(col){
- if(isNative(item_current[col.field])) {
- item_current[col.field] = undefined;
- }
- });
-
- data_view.addItem(item_current);
- self.handler.data_store.added[_key] = {
- 'err': false,
- 'data': item_current,
- };
- self.handler.data_store.added_index[data_length] = _key;
-
- // Fetch data type & add it for the column
- var temp = {};
- temp[column.name] = _.where(this.columns, {
- pos: column.pos,
- })[0]['type'];
- grid.updateRowCount();
- grid.render();
-
- // Highlight the first added cell of the new row
- var row = data_view.getRowByItem(item_current);
- self.handler.numberOfModifiedCells++;
- args.grid.addCellCssStyles(self.handler.numberOfModifiedCells, {
- [row] : {
- [column.field]: 'highlighted_grid_cells',
- },
- });
-
- // Enable save button
- $('#btn-save-data').prop('disabled', false);
- }.bind(editor_data));
-
- // Listen grid viewportChanged event to load next chunk of data.
- grid.onViewportChanged.subscribe(function(e, args) {
- var rendered_range = args.grid.getRenderedRange(),
- data_len = args.grid.getDataLength();
- // start fetching next batch of records before reaching to bottom.
- if (self.handler.has_more_rows && !self.handler.fetching_rows && rendered_range.bottom > data_len - 100) {
- // fetch asynchronous
- setTimeout(self.fetch_next.bind(self));
- }
- });
-
- grid.onValidationError.subscribe(function (e, args) {
- Notify.error(args.validationResults.msg);
- });
-
- // Resize SlickGrid when window resize
- $(window).resize(function() {
- // Resize grid only when 'Data Output' panel is visible.
- if (self.data_output_panel.isVisible()) {
- self.grid_resize(grid);
- }
- });
-
- // Resize SlickGrid when output Panel resize
- self.data_output_panel.on(wcDocker.EVENT.RESIZE_ENDED, function() {
- // Resize grid only when 'Data Output' panel is visible.
- if (self.data_output_panel.isVisible()) {
- self.grid_resize(grid);
- }
- });
-
- self.data_output_panel.on(wcDocker.EVENT.RESIZED, function() {
- // Resize grid only when 'Data Output' panel is visible.
- if (self.data_output_panel.isVisible()) {
- if (self.preferences.column_data_auto_resize === 'by_data') {
- grid.resizeAllColumns && grid.resizeAllColumns(
- self.preferences.column_data_max_width, self.max_width_changed);
- }else{
- self.grid.resizeAllColumns && self.grid.resizeAllColumns();
- }
- }
- });
-
- // Resize SlickGrid when output Panel gets focus
- self.data_output_panel.on(wcDocker.EVENT.VISIBILITY_CHANGED, function() {
- // Resize grid only if output panel is visible
- if (self.data_output_panel.isVisible())
- self.grid_resize(grid);
- });
-
- for (var i = 0; i < collection.length; i++) {
- // Convert to dict from 2darray
- var item = {};
- for (var j = 1; j < grid_columns.length; j++) {
- item[grid_columns[j]['field']] = collection[i][grid_columns[j]['pos']];
- }
-
- item[self.client_primary_key] = (self.client_primary_key_counter++).toString();
- collection[i] = item;
- }
- dataView.setItems(collection, self.client_primary_key);
- /* Resize the columns once if data empty */
- if (collection.length === 0 && self.preferences.column_data_auto_resize === 'by_data') {
- self.grid.resizeAllColumns && self.grid.resizeAllColumns();
- }
- },
-
- fetch_next_all: function(cb) {
- this.fetch_next(true, cb);
- },
-
- fetch_next: function(fetch_all, cb) {
- var self = this,
- url = '';
-
- // This will prevent fetch operation if previous fetch operation is
- // already in progress.
- self.handler.fetching_rows = true;
-
- $('#btn-flash').prop('disabled', true);
- $('#btn-save-results-to-file').prop('disabled', true);
-
- if (fetch_all) {
- self.handler.trigger(
- 'pgadmin-sqleditor:loading-icon:show',
- gettext('Fetching all records...')
- );
- url = url_for('sqleditor.fetch_all', {
- 'trans_id': self.transId,
- 'fetch_all': 1,
- });
- } else {
- url = url_for('sqleditor.fetch', {
- 'trans_id': self.transId,
- });
- }
-
- $.ajax({
- url: url,
- method: 'GET',
- })
- .done(function(res) {
- self.handler.has_more_rows = res.data.has_more_rows;
- setTimeout(() => {
- $('#btn-flash').prop('disabled', false);
- }, 700);
- $('#btn-save-results-to-file').prop('disabled', false);
- self.handler.trigger('pgadmin-sqleditor:loading-icon:hide');
- self.update_grid_data(res.data.result);
- self.handler.fetching_rows = false;
- if (typeof cb == 'function') {
- cb();
- }
- })
- .fail(function(e) {
- $('#btn-flash').prop('disabled', false);
- $('#btn-save-results-to-file').prop('disabled', false);
- self.handler.trigger('pgadmin-sqleditor:loading-icon:hide');
- self.handler.has_more_rows = false;
- self.handler.fetching_rows = false;
- if (typeof cb == 'function') {
- cb();
- }
-
- let msg = httpErrorHandler.handleQueryToolAjaxError(
- pgAdmin, self, e, null, [], false
- );
- if (msg)
- self.update_msg_history(false, msg);
- });
- },
-
- update_grid_data: function(data) {
- this.dataView.beginUpdate();
-
- for (let data_val of data) {
- // Convert 2darray to dict.
- var item = {};
- for (var j = 1; j < this.grid_columns.length; j++) {
- item[this.grid_columns[j]['field']] = data_val[this.grid_columns[j]['pos']];
- }
-
- item[this.client_primary_key] = (this.client_primary_key_counter++).toString();
- this.dataView.addItem(item);
- }
-
- this.dataView.endUpdate();
- },
-
- /* This function is responsible to render output grid */
- grid_resize: function(grid) {
- var prev_height = $('#datagrid').height(),
- h = $(this.data_output_panel.$container.parent().parent()).height() - 35,
- prev_viewport = grid.getViewport(),
- prev_viewport_rows = grid.getRenderedRange(),
- prev_cell = grid.getActiveCell();
-
- // Apply css only if necessary, To avoid DOM operation
- if (prev_height != h) {
- $('#datagrid').css({
- 'height': h + 'px',
- });
- }
-
- grid.resizeCanvas();
-
- /*
- * If there is an active cell from user then we have to go to that cell
- */
- if (prev_cell) {
- grid.scrollCellIntoView(prev_cell.row, prev_cell.cell);
- }
-
- // If already displaying from first row
- if (prev_viewport.top == prev_viewport_rows.top) {
- return;
- }
- // if user has scroll to the end/last row
- else if (prev_viewport.bottom - 2 == prev_viewport_rows.bottom) {
- grid.scrollRowIntoView(prev_viewport.bottom);
- } else {
- grid.scrollRowIntoView(prev_viewport.bottom - 2);
- }
- },
-
- fetch_query_history: function() {
- let self = this;
- $.ajax({
- url: url_for('sqleditor.get_query_history', {
- 'trans_id': self.handler.transId,
- }),
- method: 'GET',
- contentType: 'application/json',
- }).done(function(res) {
- res.data.result.map((entry) => {
- let newEntry = JSON.parse(entry);
- newEntry.start_time = new Date(newEntry.start_time);
- self.history_collection.add(newEntry);
- });
- }).fail(function() {
- /* history fetch fail should not affect query tool */
- });
- },
- /* This function is responsible to create and render the history tab. */
- render_history_grid: function() {
- var self = this;
-
- /* Should not reset if function called again */
- if(!self.history_collection) {
- self.history_collection = new HistoryCollection([]);
- }
-
- if(!self.historyComponent) {
- self.historyComponent = new QueryHistory($('#history_grid'), self.history_collection);
-
- /* Copy query to query editor, set the focus to editor and move cursor to end */
- self.historyComponent.onCopyToEditorClick((query)=>{
- self.query_tool_obj.setValue(query);
- self.sql_panel_obj.focus();
- setTimeout(() => {
- self.query_tool_obj.focus();
- self.query_tool_obj.setCursor(self.query_tool_obj.lineCount(), 0);
- }, 100);
- });
-
- self.historyComponent.render();
-
- self.history_panel.off(wcDocker.EVENT.VISIBILITY_CHANGED);
- self.history_panel.on(wcDocker.EVENT.VISIBILITY_CHANGED, function() {
- if (self.history_panel.isVisible()) {
- setTimeout(()=>{
- self.historyComponent.focus();
- }, 100);
- }
- });
- }
-
- if(!self.handler.is_query_tool) {
- self.historyComponent.setEditorPref({'copy_to_editor':false});
- }
- },
-
- // Callback function for delete button click.
- on_delete: function() {
- var self = this;
-
- // Trigger the deleterow signal to the SqlEditorController class
- self.handler.trigger(
- 'pgadmin-sqleditor:button:deleterow',
- self,
- self.handler
- );
- },
-
- _stopEventPropogation: function(ev) {
- ev = ev || window.event;
- ev.cancelBubble = true;
- ev.stopPropagation();
- ev.stopImmediatePropagation();
- ev.preventDefault();
- },
-
- _closeDropDown: function(ev) {
- var target = ev && (ev.currentTarget || ev.target);
- if (target) {
- $(target).closest('.editor-toolbar').find('.show').removeClass('show');
- }
- },
-
- // Callback function for Save button click.
- on_save_file: function(ev) {
- var self = this;
-
- this._stopEventPropogation(ev);
- this._closeDropDown(ev);
-
- self.handler.close_on_save = false;
- // Trigger the save signal to the SqlEditorController class
- self.handler.trigger(
- 'pgadmin-sqleditor:button:save_file'
- );
- },
-
- // Callback function for Save button click.
- on_save_as: function(ev) {
- var self = this;
-
- this._stopEventPropogation(ev);
- this._closeDropDown(ev);
-
- self.handler.close_on_save = false;
- // Trigger the save signal to the SqlEditorController class
- self.handler.trigger(
- 'pgadmin-sqleditor:button:save_file',
- self,
- self.handler,
- true
- );
- },
-
- // Callback function for the find button click.
- on_find: function(ev) {
- var self = this;
- this._stopEventPropogation(ev);
- this._closeDropDown(ev);
-
- self.query_tool_obj.execCommand('find');
- },
-
- // Callback function for the find next button click.
- on_find_next: function(ev) {
- var self = this;
-
- this._stopEventPropogation(ev);
- this._closeDropDown(ev);
-
- self.query_tool_obj.execCommand('findNext');
- },
-
- // Callback function for the find previous button click.
- on_find_previous: function(ev) {
- var self = this;
- this._stopEventPropogation(ev);
- this._closeDropDown(ev);
-
- self.query_tool_obj.execCommand('findPrev');
- },
-
- // Callback function for the replace button click.
- on_replace: function(ev) {
- var self = this;
- this._stopEventPropogation(ev);
- this._closeDropDown(ev);
-
- self.query_tool_obj.execCommand('replace');
- },
-
- // Callback function for the replace all button click.
- on_replace_all: function(ev) {
- var self = this;
- this._stopEventPropogation(ev);
- this._closeDropDown(ev);
-
- self.query_tool_obj.execCommand('replaceAll');
- },
-
- // Callback function for the find persistent button click.
- on_find_persistent: function(ev) {
- var self = this;
-
- this._stopEventPropogation(ev);
- this._closeDropDown(ev);
-
- self.query_tool_obj.execCommand('findPersistent');
- },
-
- // Callback function for the jump button click.
- on_jump: function(ev) {
- var self = this;
-
- this._stopEventPropogation(ev);
- this._closeDropDown(ev);
-
- self.query_tool_obj.execCommand('jumpToLine');
- },
-
- // Callback function for filter button click.
- on_show_filter: function() {
- var self = this;
-
- // Trigger the show_filter signal to the SqlEditorController class
- self.handler.trigger(
- 'pgadmin-sqleditor:button:show_filter',
- self,
- self.handler
- );
- },
-
- on_new_connection: function() {
- var self = this;
-
- // Trigger the show_filter signal to the SqlEditorController class
- self.handler.trigger(
- 'pgadmin-sqleditor:button:show_new_connection',
- self,
- self.handler
- );
- },
-
- // Callback function for include filter button click.
- on_include_filter: function(ev) {
- var self = this;
-
- this._stopEventPropogation(ev);
- this._closeDropDown(ev);
-
- // Trigger the include_filter signal to the SqlEditorController class
- self.handler.trigger(
- 'pgadmin-sqleditor:button:include_filter',
- self,
- self.handler
- );
- },
-
- // Callback function for exclude filter button click.
- on_exclude_filter: function(ev) {
- var self = this;
-
- this._stopEventPropogation(ev);
- this._closeDropDown(ev);
-
- // Trigger the exclude_filter signal to the SqlEditorController class
- self.handler.trigger(
- 'pgadmin-sqleditor:button:exclude_filter',
- self,
- self.handler
- );
- },
-
- // Callback function for remove filter button click.
- on_remove_filter: function(ev) {
- var self = this;
-
- this._stopEventPropogation(ev);
- this._closeDropDown(ev);
-
- // Trigger the remove_filter signal to the SqlEditorController class
- self.handler.trigger(
- 'pgadmin-sqleditor:button:remove_filter',
- self,
- self.handler
- );
- },
-
- // Callback function for cancel button click.
- on_cancel: function() {
- $('#filter').addClass('d-none');
- $('#editor-panel').removeClass('sql-editor-busy-fetching');
- },
-
- // Callback function for copy button click.
- on_copy_row: function() {
- var self = this;
-
- // Trigger the copy signal to the SqlEditorController class
- self.handler.trigger(
- 'pgadmin-sqleditor:button:copy_row',
- self,
- self.handler
- );
-
- },
-
- // Callback function for copy with header button click.
- on_copy_row_with_header: function(ev) {
- var self = this;
-
- this._stopEventPropogation(ev);
-
- // Toggle the button
- self.handler.trigger(
- 'pgadmin-sqleditor:button:copy_row_with_header',
- self,
- self.handler
- );
-
- },
-
- // Callback function for paste button click.
- on_paste_row: function() {
- var self = this;
-
- // Trigger the paste signal to the SqlEditorController class
- self.handler.trigger(
- 'pgadmin-sqleditor:button:paste_row',
- self,
- self.handler
- );
- },
-
- // Callback function for the change event of combo box
- on_limit_change: function() {
- var self = this;
-
- // Trigger the limit signal to the SqlEditorController class
- self.handler.trigger(
- 'pgadmin-sqleditor:button:limit',
- self,
- self.handler
- );
- },
-
- // Callback function for Save Data Changes button click.
- on_save_data: function() {
- this.handler.history_query_source = QuerySources.SAVE_DATA;
-
- queryToolActions.saveDataChanges(this.handler);
- },
-
- // Callback function for the flash button click.
- on_flash: function() {
- $('#btn-flash').prop('disabled', true);
- let data_click_counter = $('#btn-flash').attr('data-click-counter');
- data_click_counter = (parseInt(data_click_counter) + 1)%10;
- $('#btn-flash').attr('data-click-counter', data_click_counter);
-
- this.handler.history_query_source = QuerySources.EXECUTE;
-
- queryToolActions.executeQuery(this.handler);
- },
-
- // Callback function for the cancel query button click.
- on_cancel_query: function() {
- var self = this;
-
- // Trigger the cancel-query signal to the SqlEditorController class
- self.handler.trigger(
- 'pgadmin-sqleditor:button:cancel-query',
- self,
- self.handler
- );
- },
-
- // Callback function for the line comment code
- on_comment_line_code: function() {
- queryToolActions.commentLineCode(this.handler);
- },
-
- // Callback function for the line uncomment code
- on_uncomment_line_code: function() {
- queryToolActions.uncommentLineCode(this.handler);
- },
-
- // Callback function for the block comment/uncomment code
- on_toggle_comment_block_code: function() {
- queryToolActions.commentBlockCode(this.handler);
- },
-
- on_indent_code: function() {
- var self = this;
- // Trigger the comment signal to the SqlEditorController class
- self.handler.trigger(
- 'pgadmin-sqleditor:indent_selected_code',
- self,
- self.handler
- );
- },
-
- on_unindent_code: function() {
- var self = this;
- // Trigger the comment signal to the SqlEditorController class
- self.handler.trigger(
- 'pgadmin-sqleditor:unindent_selected_code',
- self,
- self.handler
- );
- },
-
- on_format_sql: function() {
- var self = this;
- // Trigger the format signal to the SqlEditorController class
- self.handler.trigger(
- 'pgadmin-sqleditor:format_sql',
- self,
- self.handler
- );
- },
-
- // Callback function for the clear button click.
- on_clear: function(ev) {
- var self = this;
- this._stopEventPropogation(ev);
- this._closeDropDown(ev);
-
- /* If is_query_changed flag is set to false then no need to
- * confirm with the user for unsaved changes.
- */
- if (self.handler.is_query_changed) {
- Notify.confirm(
- gettext('Unsaved changes'),
- gettext('Are you sure you wish to discard the current changes?'),
- function() {
- // Do nothing as user do not want to save, just continue
- self.query_tool_obj.setValue('');
- setTimeout(() => { self.query_tool_obj.focus(); }, 200);
- },
- function() {
- return true;
- }
- );
- } else {
- self.query_tool_obj.setValue('');
- }
- },
-
- // Callback function for the clear history button click.
- on_clear_history: function(ev) {
- var self = this;
- this._stopEventPropogation(ev);
- this._closeDropDown(ev);
- // ask for confirmation only if anything to clear
- if (!self.history_collection.length()) {
- return;
- }
-
- Notify.confirm(gettext('Clear history'),
- gettext('Are you sure you wish to clear the history?') + '' +
- gettext('This will remove all of your query history from this and other sessions for this database.'),
- function() {
- if (self.history_collection) {
- self.history_collection.reset();
- }
-
- if(self.handler.is_query_tool) {
- $.ajax({
- url: url_for('sqleditor.clear_query_history', {
- 'trans_id': self.handler.transId,
- }),
- method: 'DELETE',
- contentType: 'application/json',
- })
- .done(function() { /* This is intentional */ })
- .fail(function() {
- /* history clear fail should not affect query tool */
- });
- }
- setTimeout(() => { self.query_tool_obj.focus(); }, 200);
- },
- function() {
- return true;
- }
- );
- },
-
- // Callback function for the auto commit button click.
- on_auto_commit: function(ev) {
- var self = this;
-
- this._stopEventPropogation(ev);
-
- // Trigger the auto-commit signal to the SqlEditorController class
- self.handler.trigger(
- 'pgadmin-sqleditor:button:auto_commit',
- self,
- self.handler
- );
- },
-
- // Callback function for the auto rollback button click.
- on_auto_rollback: function(ev) {
- var self = this;
-
- this._stopEventPropogation(ev);
-
- // Trigger the download signal to the SqlEditorController class
- self.handler.trigger(
- 'pgadmin-sqleditor:button:auto_rollback',
- self,
- self.handler
- );
- },
-
- // Callback function for explain button click.
- on_explain: function(event) {
- this._stopEventPropogation(event);
- this._closeDropDown(event);
-
- this.handler.history_query_source = QuerySources.EXPLAIN;
- queryToolActions.explain(this.handler);
- },
-
- // Callback function for explain analyze button click.
- on_explain_analyze: function(event) {
- this._stopEventPropogation(event);
- this._closeDropDown(event);
-
- this.handler.history_query_source = QuerySources.EXPLAIN_ANALYZE;
- queryToolActions.explainAnalyze(this.handler);
- },
-
- // Callback function for explain option "verbose" button click
- on_explain_verbose: function(ev) {
- var self = this;
-
- this._stopEventPropogation(ev);
-
- // Trigger the explain "verbose" signal to the SqlEditorController class
- self.handler.trigger(
- 'pgadmin-sqleditor:button:explain-verbose',
- self,
- self.handler
- );
- },
-
- // Callback function for explain option "costs" button click
- on_explain_costs: function(ev) {
- var self = this;
-
- this._stopEventPropogation(ev);
-
- // Trigger the explain "costs" signal to the SqlEditorController class
- self.handler.trigger(
- 'pgadmin-sqleditor:button:explain-costs',
- self,
- self.handler
- );
- },
-
- // Callback function for explain option "buffers" button click
- on_explain_buffers: function(ev) {
- var self = this;
-
- this._stopEventPropogation(ev);
-
- // Trigger the explain "buffers" signal to the SqlEditorController class
- self.handler.trigger(
- 'pgadmin-sqleditor:button:explain-buffers',
- self,
- self.handler
- );
- },
-
- // Callback function for explain option "timing" button click
- on_explain_timing: function(ev) {
- var self = this;
-
- this._stopEventPropogation(ev);
-
- // Trigger the explain "timing" signal to the SqlEditorController class
- self.handler.trigger(
- 'pgadmin-sqleditor:button:explain-timing',
- self,
- self.handler
- );
- },
-
- on_explain_summary: function(ev) {
- var self = this;
-
- this._stopEventPropogation(ev);
-
- self.handler.trigger(
- 'pgadmin-sqleditor:button:explain-summary',
- self,
- self.handler
- );
- },
-
- on_explain_settings: function(ev) {
- var self = this;
-
- this._stopEventPropogation(ev);
-
- self.handler.trigger(
- 'pgadmin-sqleditor:button:explain-settings',
- self,
- self.handler
- );
- },
-
-
- do_not_close_menu: function(ev) {
- ev.stopPropagation();
- },
-
- // callback function for show query tool click.
- on_show_query_tool: function(ev) {
- var self = this;
-
- this._stopEventPropogation(ev);
- this._closeDropDown(ev);
-
- self.handler.trigger(
- 'pgadmin-sqleditor:button:show_query_tool',
- self,
- self.handler
- );
- },
-
- // callback function for load file button click.
- on_file_load: function(ev) {
- var self = this;
-
- this._stopEventPropogation(ev);
- this._closeDropDown(ev);
-
- // Trigger the save signal to the SqlEditorController class
- self.handler.trigger(
- 'pgadmin-sqleditor:button:load_file',
- self,
- self.handler
- );
- },
-
- on_download: function() {
- queryToolActions.download(this.handler);
- },
-
- keyAction: function(event) {
- var panel_type='';
-
- panel_type = keyboardShortcuts.processEventQueryTool(
- this.handler, queryToolActions, event, this.docker
- );
-
- if(!_.isNull(panel_type) && !_.isUndefined(panel_type) && panel_type != '') {
- setTimeout(function() {
- pgBrowser.Events.trigger(`pgadmin:query_tool:${panel_type}:focus`);
- }, 100);
- }
- },
-
- // Callback function for the commit button click.
- on_commit_transaction: function() {
- this.handler.close_on_idle_transaction = false;
- this.handler.history_query_source = QuerySources.COMMIT;
-
- queryToolActions.executeCommit(this.handler);
- },
-
- // Callback function for the rollback button click.
- on_rollback_transaction: function() {
- this.handler.close_on_idle_transaction = false;
- this.handler.history_query_source = QuerySources.ROLLBACK;
-
- queryToolActions.executeRollback(this.handler);
- },
-
- // Callback function for manage macros button click.
- on_manage_macros: function() {
- var self = this;
-
- // Trigger the show_filter signal to the SqlEditorController class
- self.handler.trigger(
- 'pgadmin-sqleditor:button:manage_macros',
- self,
- self.handler
- );
- },
-
- // Callback function for manage macros button click.
- on_execute_macro: function(e) {
- let macroId = $(e.currentTarget).data('macro-id');
- this.handler.history_query_source = QuerySources.EXECUTE;
- queryToolActions.executeMacro(this.handler, macroId);
- },
-
- set_selected_option: function(selected_config) {
- this.connection_list.forEach(option =>{
- if(option['server'] == selected_config['server'] && option['database'] == selected_config['database'] && option['user'] == selected_config['user'] && option['role'] == selected_config['role']) {
- selected_config['is_selected'] = true;
- } else {
- option['is_selected'] = false;
- }
- });
- },
-
- on_change_connection: function(connection_details, ref, add_new_connection=true) {
- if(!connection_details['is_selected']) {
- var self = this;
- if(add_new_connection) {
- Notify.confirm(gettext('Change connection'),
- gettext('By changing the connection you will lose all your unsaved data for the current connection. Do you want to continue?'),
- function() {
- self.change_connection(connection_details, ref, true);
- },
- function() {
- var loadingDiv = $('#main_loader');
- loadingDiv.addClass('d-none');
- alertify.newConnectionDialog().destroy();
- return true;
- }
- );
- } else {
- self.change_connection(connection_details, ref, false);
- }
- }
- },
-
- change_connection: function(connection_details, ref, add_new_connection) {
- var self = this;
- var loadingDiv = null;
- var msgDiv = null;
- if(ref){
- loadingDiv = $('#show_filter_progress');
- loadingDiv.removeClass('d-none');
- msgDiv = loadingDiv.find('.sql-editor-busy-text');
- msgDiv.text('Connecting to database...');
- } else{
- loadingDiv = $('#main_loader');
- loadingDiv.removeClass('d-none');
- }
- self.set_selected_option(connection_details);
- $.ajax({
- url: url_for('datagrid.update_query_tool_connection', {
- 'trans_id': self.transId,
- 'sgid': connection_details['server_group'],
- 'sid': connection_details['server'],
- 'did': connection_details['database'],
- }),
- method: 'POST',
- contentType: 'application/json',
- data: JSON.stringify(connection_details),
- })
- .done(function(res) {
- if(res.success) {
- delete connection_details.password;
- self.transId = res.data.tran_id;
- self.handler.transId = res.data.tran_id;
- self.handler.url_params = {
- 'did': connection_details['database'],
- 'is_query_tool': self.handler.url_params.is_query_tool,
- 'server_type': self.handler.url_params.server_type,
- 'sgid': connection_details['server_group'],
- 'sid': connection_details['server'],
- 'title': connection_details['title'],
- };
- self.set_editor_title(_.unescape(connection_details['conn_title']));
- self.handler.setTitle(_.unescape(self.handler.url_params.title));
- let success_msg = connection_details['server_name'] + '/' + connection_details['database_name'] + '- Database connected';
- Notify.success(success_msg);
- if(ref){
- let connection_data = {
- 'server_group': self.handler.url_params.sgid,
- 'server': connection_details['server'],
- 'database': connection_details['database'],
- 'user': connection_details['user'],
- 'title': connection_details['title'],
- 'conn_title': connection_details['conn_title'],
- 'role': connection_details['role'],
- 'is_allow_new_connection': true,
- 'database_name': connection_details['database_name'],
- 'server_name': connection_details['server_name'],
- 'is_selected': true,
- };
- delete connection_data.password;
- if(add_new_connection) {
- self.connection_list.unshift(connection_data);
- }
-
- self.render_connection(self.connection_list);
- loadingDiv.addClass('d-none');
- alertify.newConnectionDialog().destroy();
- alertify.connectServer().destroy();
- } else {
- loadingDiv.addClass('d-none');
- alertify.connectServer().destroy();
- }
- }
- return true;
- })
- .fail(function(xhr) {
- if(xhr.status == 428) {
- var connection_info = connection_details;
- if(ref) {
- connection_info = {};
- }
- alertify.connectServer('Connect to server', xhr.responseJSON.result, connection_details['server'], false, connection_info);
- } else {
- Notify.error(xhr.responseJSON['errormsg']);
- }
- });
- },
- });
-
-
-
- /* Defining controller class for data grid, which actually
- * perform the operations like executing the sql query, poll the result,
- * render the data in the grid, Save/Refresh the data etc...
- */
- var SqlEditorController = function() {
- this.initialize.apply(this, arguments);
- };
-
- /* This function is used to check whether user have closed
- * the main window when query tool is opened on new tab
- */
- var is_main_window_alive = function() {
-
- if((pgWindow.default && pgWindow.default.closed) ||
- pgWindow.default.pgAdmin && pgWindow.default.pgAdmin.Browser
- && pgWindow.default.pgAdmin.Browser.preference_version() <= 0) {
-
- Notify.alert(gettext('Connection lost'),
- gettext('The pgAdmin browser window has been closed and the connection to the server is lost. Please close this window and open a new pgAdmin session.'),
- function(){
- //Close the window after connection is lost
- window.close();
- },
- gettext('Close')
- );
- }
- };
-
- _.extend(
- SqlEditorController.prototype,
- Backbone.Events,
- {
- initialize: function(container) {
- var self = this;
- this.container = container;
- this.state = {};
- this.csrf_token = pgAdmin.csrf_token;
-
- //call to check whether user have closed the parent window and trying to refresh, if yes return error.
- is_main_window_alive();
-
- // Disable animation first
- modifyAnimation.modifyAlertifyAnimation();
-
- if (!alertify.dlgGetServerPass) {
- alertify.dialog('dlgGetServerPass', function factory() {
- return {
- main: function(
- title, message
- ) {
- this.set('title', title);
- this.setting('message',message);
- },
- setup:function() {
- return {
- buttons:[
- {
- text: gettext('OK'),
- key: 13,
- className: 'btn btn-primary',
- },
- {
- text: gettext('Cancel'),
- key: 27,
- className: 'btn btn-danger',
- },
- ],
- focus: {
- element: '#password',
- select: true,
- },
- options: {
- modal: 0,
- resizable: false,
- maximizable: false,
- pinnable: false,
- },
- };
- },
- build:function() {/* */},
- settings:{
- message: null,
- },
- prepare:function() {
- this.setContent(this.setting('message'));
- },
- callback: function(closeEvent) {
- if (closeEvent.button.text == gettext('OK')) {
- var passdata = $(this.elements.content).find('#frmPassword').serialize();
- self.init_connection(false, passdata);
- }
- },
- };
- });
- }
- this.on('pgadmin-datagrid:transaction:created', function(trans_obj) {
- self.transId = trans_obj.gridTransId;
- self.warn_before_continue();
- });
- pgBrowser.Events.on('pgadmin:user:logged-in', function() {
- self.initTransaction();
- });
- },
- saveState: function(fn, args) {
- if (fn) {
- this.state = {
- 'fn': fn,
- 'args': args,
- };
- } else {
- this.state = {};
- }
- },
-
- initTransaction: function() {
- var self = this, url_endpoint;
- if (self.is_query_tool) {
- url_endpoint = 'datagrid.initialize_query_tool';
-
- // If database not present then use Maintenance database
- // We will handle this at server side
- if (self.url_params.did) {
- url_endpoint = 'datagrid.initialize_query_tool_with_did';
- }
-
- } else {
- url_endpoint = 'datagrid.initialize_datagrid';
- }
-
- var baseUrl = url_for(url_endpoint, {
- ...self.url_params,
- 'trans_id': self.transId,
- });
-
- $.ajax({
- url: baseUrl,
- type: 'POST',
- data: self.is_query_tool?null:JSON.stringify(self.url_params.sql_filter),
- contentType: 'application/json',
- }).done((res)=>{
- pgBrowser.Events.trigger(
- 'pgadmin:query_tool:connected:' + self.transId, res.data
- );
- }).fail((xhr, status, error)=>{
- if (xhr.status === 410) {
- //checking for Query tool in new window.
- var open_new_tab = self.browser_preferences.new_browser_tab_open;
- if(open_new_tab && open_new_tab.includes('qt')) {
- pgBrowser.report_error(gettext('Error fetching rows - %s.', xhr.statusText), xhr.responseJSON.errormsg, undefined, window.close);
- } else {
- pgBrowser.report_error(gettext('Error fetching rows - %s.', xhr.statusText), xhr.responseJSON.errormsg, undefined, self.close.bind(self));
- }
- } else {
- if (xhr.responseText.search('Ticket expired') !== -1) {
- let fetchTicket = Kerberos.fetch_ticket();
- fetchTicket.then(
- function() {
- self.initTransaction();
- },
- function() {
- pgBrowser.Events.trigger(
- 'pgadmin:query_tool:connected_fail:' + self.transId, xhr, error
- );
- }
- );
- } else {
- pgBrowser.Events.trigger(
- 'pgadmin:query_tool:connected_fail:' + self.transId, xhr, error
- );
- }
- }
- });
- },
-
- handle_connection_lost: function(create_transaction, xhr) {
- /* If responseJSON is undefined then it could be object of
- * axios(Promise HTTP) response, so we should check accordingly.
- */
- if (xhr.responseJSON !== undefined &&
- xhr.responseJSON.data && !xhr.responseJSON.data.conn_id) {
- // if conn_id is null then this is maintenance db.
- // so attempt connection connect without prompt.
- this.init_connection(create_transaction);
- } else if (xhr.data !== undefined &&
- xhr.data.data && !xhr.data.data.conn_id) {
- // if conn_id is null then this is maintenance db.
- // so attempt connection connect without prompt.
- this.init_connection(create_transaction);
- } else {
- this.warn_before_continue();
- }
- },
- handle_cryptkey_missing: function() {
- pgBrowser.set_master_password('', ()=>{
- this.warn_before_continue();
- });
- },
- warn_before_continue: function() {
- var self = this;
-
- Notify.confirm(
- gettext('Connection Warning'),
- ''+
- ''+
- ' '+
- '
'+
- ''+
- ''+
- ' '+
- ''+
- gettext('⁃ If the connection was idle it may have been forcibly disconnected.')+
- ' '+
- gettext('⁃ The application server or database server may have been restarted.')+
- ' '+
- gettext('⁃ The user session may have timed out.')+
- ' '+
- ' '+
- ''+
- '
',
- function() {
- if ('fn' in self.state) {
- var fn = self.state['fn'],
- args = self.state['args'];
- self.saveState();
- if (args.indexOf('connect') == -1) {
- args.push('connect');
- }
- if (fn in self) {
- self[fn].apply(self, args);
- } else {
- console.warn('The callback is not valid for this context');
- }
-
- }
- }, function() {
- self.saveState();
- },
- gettext('Continue'),
- gettext('Cancel')
- );
- },
- init_connection: function(create_transaction, passdata) {
- var self = this;
- $.post(url_for('NODE-server.connect_id', {
- 'gid': this.url_params.sgid,
- 'sid': this.url_params.sid,
- }),passdata)
- .done(function(res) {
- if (res.success == 1) {
- Notify.success(res.info);
- if (create_transaction) {
- self.initTransaction();
- } else if ('fn' in self.state) {
- var fn = self.state['fn'],
- args = self.state['args'];
- self.saveState();
- self[fn].apply(self, args);
- }
- }
- })
- .fail(function(xhr) {
- let msg = httpErrorHandler.handleQueryToolAjaxError(
- pgAdmin, self, xhr, null, [], false
- );
- if (msg)
- alertify.dlgGetServerPass(
- gettext('Connect to Server'), msg
- );
- });
- },
- /* This function is used to create instance of SQLEditorView,
- * call the render method of the grid view to render the slickgrid
- * header and loading icon and start execution of the sql query.
- */
- start: function(transId, url_params, layout, macros) {
- var self = this;
-
- self.is_query_tool = url_params.is_query_tool==='true'?true:false;
- self.rows_affected = 0;
- self.marked_line_no = 0;
- self.has_more_rows = false;
- self.fetching_rows = false;
- self.close_on_save = false;
- self.close_on_idle_transaction = false;
- self.last_transaction_status = -1;
- self.server_type = url_params.server_type;
- self.url_params = url_params;
- self.is_transaction_buttons_disabled = true;
- self.is_save_results_to_file_disabled = true;
-
- // We do not allow to call the start multiple times.
- if (self.gridView)
- return;
-
- self.gridView = new SQLEditorView({
- el: self.container,
- handler: self,
- layout: layout,
- });
- self.transId = self.gridView.transId = transId;
- self.macros = self.gridView.macros = macros;
-
- self.gridView.current_file = undefined;
-
- // Render the header
- self.gridView.render();
-
- // Listen on events to show/hide loading-icon and change messages.
- // Parallelly, also update the bottom message.
- let loadingDiv = self.gridView.data_output_panel.$container.find('#fetching_data'),
- msgDiv = loadingDiv.find('.sql-editor-busy-text'),
- statusDiv = $('.sql-editor-busy-text-status');
-
- self.on('pgadmin-sqleditor:loading-icon:message', function(msg) {
- msgDiv.text(msg);
- statusDiv.text(msg);
- }).on('pgadmin-sqleditor:loading-icon:show', function(msg) {
- loadingDiv.removeClass('d-none');
- statusDiv.removeClass('d-none');
-
- msgDiv.text(msg);
- statusDiv.text(msg);
- }).on('pgadmin-sqleditor:loading-icon:hide', function() {
- loadingDiv.addClass('d-none');
- statusDiv.addClass('d-none');
- });
-
- $('#main_loader').addClass('d-none');
- self.trigger('pgadmin-sqleditor:loading-icon:hide');
-
- self.gridView.set_editor_title('(' + gettext('Obtaining connection...') + ` ${_.unescape(url_params.title)}`);
-
- let afterConn = function() {
- let enableBtns = [];
-
- if(self.is_query_tool){
- enableBtns = ['#btn-flash', '#btn-explain', '#btn-explain-analyze'];
- } else {
- enableBtns = ['#btn-flash'];
- }
-
- enableBtns.forEach((selector)=>{
- $(selector).prop('disabled', false);
- });
-
- $('#btn-conn-status i').removeClass('obtaining-conn');
-
- var tree_data = pgWindow.default.pgAdmin.Browser.tree.getTreeNodeHierarchy(pgWindow.default.pgAdmin.Browser.tree.selected());
- let conn_title = ` ${_.unescape(url_params.title)}`;
- self.gridView.set_editor_title(_.unescape(conn_title));
- let connection_data = {
- 'server_group': self.gridView.handler.url_params.sgid,
- 'server': self.gridView.handler.url_params.sid,
- 'database': self.gridView.handler.url_params.did,
- 'user': tree_data.server.user.name,
- 'role': null,
- 'title': _.unescape(url_params.title),
- 'conn_title': _.unescape(conn_title),
- 'is_allow_new_connection': false,
- 'database_name': _.unescape(tree_data.database.label),
- 'server_name': _.unescape(tree_data.server.label),
- 'is_selected': true,
- };
- delete connection_data.password;
- self.gridView.connection_list.unshift(connection_data);
- self.gridView.render_connection(self.gridView.connection_list);
- };
-
- pgBrowser.Events.on('pgadmin:query_tool:connected:' + transId, afterConn);
- pgBrowser.Events.on('pgadmin:query_tool:connected_fail:' + transId, afterConn);
-
- pgBrowser.Events.on('pgadmin:query_tool:connected:' + transId, (res_data)=>{
- self.gridView.set_server_version(res_data.serverVersion);
- });
-
- pgBrowser.Events.on('pgadmin:query_tool:connected_fail:' + transId, (xhr, error)=>{
- Notify.pgRespErrorNotify(xhr, error);
- });
-
- self.initTransaction();
-
- /* wcDocker focuses on window always, and all our shortcuts are
- * bind to editor-panel. So when we use wcDocker focus, editor-panel
- * loses focus and events don't work.
- */
- $(window).on('keydown', (e)=>{
- if(($('.sql-editor').find(e.target).length !== 0 || e.target == $('body.wcDesktop')[0]) && self.gridView.keyAction) {
- self.gridView.keyAction(e);
- }
- });
-
- self.init_events();
- if (self.is_query_tool) {
- // Fetch the SQL for Scripts (eg: CREATE/UPDATE/DELETE/SELECT)
- // Call AJAX only if script type url is present
- if (url_params.query_url) {
- $.ajax({
- url: url_params.query_url,
- type:'GET',
- })
- .done(function(res) {
- self.gridView.query_tool_obj.refresh();
- if (res) {
- self.gridView.query_tool_obj.setValue(res);
- }
- })
- .fail(function(jqx) {
- let msg = '';
-
- msg = httpErrorHandler.handleQueryToolAjaxError(
- pgAdmin, self, jqx, null, [], false
- );
- if (msg) {
- var open_new_tab = self.browser_preferences.new_browser_tab_open;
- if(open_new_tab && open_new_tab.includes('qt')) {
- pgBrowser.report_error(gettext('Error fetching SQL for script - %s.', jqx.statusText), jqx.responseJSON.errormsg, undefined, window.close);
- } else {
- pgBrowser.report_error(gettext('Error fetching SQL for script - %s.', jqx.statusText), jqx.responseJSON.errormsg, undefined, self.close.bind(self));
- }
- }
-
- });
- } else if(url_params.sql_id) {
- let sqlValue = localStorage.getItem(url_params.sql_id);
- localStorage.removeItem(url_params.sql_id);
- if(sqlValue) {
- self.gridView.query_tool_obj.setValue(sqlValue);
- }
- }
- }
- else {
- // Disable codemirror by setting readOnly option to true, background to dark, and cursor, hidden.
- self.gridView.query_tool_obj.setOption('readOnly', true);
- var cm = self.gridView.query_tool_obj.getWrapperElement();
- if (cm) {
- cm.className += ' bg-gray-lighter opacity-5 hide-cursor-workaround';
- }
- self.disable_tool_buttons(true);
- pgBrowser.Events.on('pgadmin:query_tool:connected:'+ transId,()=>{
- self.check_data_changes_to_execute_query();
- });
- }
- },
-
- set_value_to_editor: function(query) {
- if (this.gridView && this.gridView.query_tool_obj && !_.isUndefined(query) && query != '') {
- this.gridView.query_tool_obj.setValue(query);
- }
- },
-
- init_events: function() {
- var self = this;
- // Listen to the file manager button events
- pgAdmin.Browser.Events.on('pgadmin-storage:finish_btn:select_file', self._select_file_handler, self);
- pgAdmin.Browser.Events.on('pgadmin-storage:finish_btn:create_file', self._save_file_handler, self);
-
- // Listen to the codemirror on text change event
- // only in query editor tool
- if (self.is_query_tool) {
- self.gridView.query_tool_obj.on('change', self._on_query_change.bind(self));
- }
-
- // Listen on events come from SQLEditorView for the button clicked.
- self.on('pgadmin-sqleditor:button:load_file', self._load_file, self);
- self.on('pgadmin-sqleditor:button:save_file', self._save_file, self);
- self.on('pgadmin-sqleditor:button:deleterow', self._delete, self);
- self.on('pgadmin-sqleditor:button:show_filter', self._show_filter, self);
- self.on('pgadmin-sqleditor:button:show_new_connection', self._show_new_connection, self);
- self.on('pgadmin-sqleditor:button:include_filter', self._include_filter, self);
- self.on('pgadmin-sqleditor:button:exclude_filter', self._exclude_filter, self);
- self.on('pgadmin-sqleditor:button:remove_filter', self._remove_filter, self);
- self.on('pgadmin-sqleditor:button:copy_row', self._copy_row, self);
- self.on('pgadmin-sqleditor:button:copy_row_with_header', self._copy_row_with_header, self);
- self.on('pgadmin-sqleditor:button:paste_row', self._paste_row, self);
- self.on('pgadmin-sqleditor:button:limit', self._set_limit, self);
- self.on('pgadmin-sqleditor:button:cancel-query', self._cancel_query, self);
- self.on('pgadmin-sqleditor:button:auto_rollback', self._auto_rollback, self);
- self.on('pgadmin-sqleditor:button:auto_commit', self._auto_commit, self);
- self.on('pgadmin-sqleditor:button:explain-verbose', self._explain_verbose, self);
- self.on('pgadmin-sqleditor:button:explain-costs', self._explain_costs, self);
- self.on('pgadmin-sqleditor:button:explain-buffers', self._explain_buffers, self);
- self.on('pgadmin-sqleditor:button:explain-timing', self._explain_timing, self);
- self.on('pgadmin-sqleditor:button:explain-summary', self._explain_summary, self);
- self.on('pgadmin-sqleditor:button:explain-settings', self._explain_settings, self);
- self.on('pgadmin-sqleditor:button:show_query_tool', self._show_query_tool, self);
- // Indentation related
- self.on('pgadmin-sqleditor:indent_selected_code', self._indent_selected_code, self);
- self.on('pgadmin-sqleditor:unindent_selected_code', self._unindent_selected_code, self);
- // Format
- self.on('pgadmin-sqleditor:format_sql', self._format_sql, self);
- self.on('pgadmin-sqleditor:button:manage_macros', self._manage_macros, self);
- self.on('pgadmin-sqleditor:button:execute_macro', self._execute_macro, self);
-
- window.parent.$(window.parent.document).on('pgadmin-sqleditor:rows-copied', self._copied_in_other_session);
- },
-
- // Checks if there is any dirty data in the grid before executing a query
- check_data_changes_to_execute_query: function(explain_prefix=null, shouldReconnect=false, macroId=undefined) {
- var self = this;
-
- // Check if the data grid has any changes before running query
- if (_.has(self, 'data_store') &&
- (_.size(self.data_store.added) ||
- _.size(self.data_store.updated) ||
- _.size(self.data_store.deleted))
- ) {
- Notify.confirm(gettext('Unsaved changes'),
- gettext('The data has been modified, but not saved. Are you sure you wish to discard the changes?'),
- function() {
- // The user does not want to save, just continue
- if (macroId !== undefined) {
- self._execute_macro_query(explain_prefix, shouldReconnect, macroId);
- }
- else if(self.is_query_tool) {
- self._execute_sql_query(explain_prefix, shouldReconnect);
- }
- else {
- self._execute_view_data_query();
- }
- },
- function() {
- // Stop, User wants to save
- $('#btn-flash').prop('disabled', false);
- return true;
- }
- );
- } else {
- if (macroId !== undefined) {
- self._execute_macro_query(explain_prefix, shouldReconnect, macroId);
- }
- else if(self.is_query_tool) {
- self._execute_sql_query(explain_prefix, shouldReconnect);
- }
- else {
- self._execute_view_data_query();
- }
- }
- },
-
- // Makes the ajax call to execute the sql query in View Data mode
- _execute_view_data_query: function() {
- var self = this,
- url = url_for('sqleditor.view_data_start', {
- 'trans_id': self.transId,
- });
-
- self.query_start_time = new Date();
- self.rows_affected = 0;
- self._init_polling_flags();
-
- self.has_more_rows = false;
- self.fetching_rows = false;
-
- self.trigger(
- 'pgadmin-sqleditor:loading-icon:show',
- gettext('Running query...')
- );
-
- $('#btn-flash').prop('disabled', true);
- self.enable_disable_download_btn(true);
-
- self.trigger(
- 'pgadmin-sqleditor:loading-icon:message',
- gettext('Waiting for the query to complete...')
- );
-
- if (arguments.length > 0 &&
- arguments[arguments.length - 1] == 'connect') {
- url += '?connect=1';
- }
-
- $.ajax({
- url: url,
- method: 'GET',
- })
- .done(function(res) {
- if (res.data.status) {
- self.can_edit = res.data.can_edit;
- self.can_filter = res.data.can_filter;
- self.info_notifier_timeout = res.data.info_notifier_timeout;
-
- // Set the sql query to the SQL panel
- self.gridView.query_tool_obj.setValue(res.data.sql);
- self.query = res.data.sql;
-
-
- /* If filter is applied then remove class 'btn-secondary'
- * and add 'btn-primary' to change the colour of the button.
- */
- if (self.can_filter && res.data.filter_applied) {
- $('#btn-filter').removeClass('btn-secondary');
- $('#btn-filter-dropdown').removeClass('btn-secondary');
- $('#btn-filter').addClass('btn-primary');
- $('#btn-filter-dropdown').addClass('btn-primary');
- } else {
- $('#btn-filter').removeClass('btn-primary');
- $('#btn-filter-dropdown').removeClass('btn-primary');
- $('#btn-filter').addClass('btn-secondary');
- $('#btn-filter-dropdown').addClass('btn-secondary');
- }
-
- $('#btn-copy-row').prop('disabled', true);
- $('#btn-paste-row').prop('disabled', true);
-
- // Set the combo box value
- $('.limit').val(res.data.limit);
-
- // If status is True then poll the result.
- self._poll();
- } else {
- self.trigger('pgadmin-sqleditor:loading-icon:hide');
- self.update_msg_history(false, res.data.result);
- }
- })
- .fail(function(e) {
- self.trigger('pgadmin-sqleditor:loading-icon:hide');
- let msg = httpErrorHandler.handleQueryToolAjaxError(
- pgAdmin, self, e, '_execute_view_data_query', [], true
- );
- if (msg)
- self.update_msg_history(false, msg);
- });
- },
-
- // Executes sql query for macroin the editor in Query Tool mode
- _execute_macro_query: function(explain_prefix, shouldReconnect, macroId) {
- var self = this;
-
- self.has_more_rows = false;
- self.fetching_rows = false;
-
- $.ajax({
- url: url_for('sqleditor.get_macro', {'macro_id': macroId, 'trans_id': self.transId}),
- method: 'GET',
- contentType: 'application/json',
- dataType: 'json',
- })
- .done(function(res) {
- if (res) {
- // Replace the place holder
- const regex = /\$SELECTION\$/gi;
- let query = res.sql.replace(regex, self.gridView.query_tool_obj.getSelection());
-
- const executeQuery = new ExecuteQuery.ExecuteQuery(self, pgAdmin.Browser.UserManagement);
- executeQuery.poll = pgBrowser.override_activity_event_decorator(executeQuery.poll).bind(executeQuery);
- executeQuery.execute(query, explain_prefix, shouldReconnect);
- } else {
- // Let it be for now
- }
- })
- .fail(function() {
- /* failure should not be ignored */
- });
-
- },
-
- // Executes sql query in the editor in Query Tool mode
- _execute_sql_query: function(explain_prefix, shouldReconnect) {
- var self = this, sql = '';
-
- self.has_more_rows = false;
- self.fetching_rows = false;
-
- if (!_.isUndefined(self.special_sql)) {
- sql = self.special_sql;
- } else {
- /* If code is selected in the code mirror then execute
- * the selected part else execute the complete code.
- */
- var selected_code = self.gridView.query_tool_obj.getSelection();
- if (selected_code.length > 0)
- sql = selected_code;
- else
- sql = self.gridView.query_tool_obj.getValue();
- }
-
- const executeQuery = new ExecuteQuery.ExecuteQuery(this, pgAdmin.Browser.UserManagement);
- executeQuery.poll = pgBrowser.override_activity_event_decorator(executeQuery.poll).bind(executeQuery);
- executeQuery.execute(sql, explain_prefix, shouldReconnect);
- },
-
- // This is a wrapper to call_render function
- // We need this because we have separated columns route & result route
- // We need to combine both result here in wrapper before rendering grid
- call_render_after_poll: function(queryResult) {
- callRenderAfterPoll.callRenderAfterPoll(this, Notify, queryResult);
- },
-
-
- /* This function makes the ajax call to poll the result,
- * if status is Busy then recursively call the poll function
- * till the status is 'Success' or 'NotConnected'. If status is
- * 'Success' then call the render method to render the data.
- */
- _poll: function() {
- const executeQuery = new ExecuteQuery.ExecuteQuery(this, pgAdmin.Browser.UserManagement);
- executeQuery.delayedPoll(this);
- },
-
- /* This function is used to create the slickgrid columns
- * and render the data in the slickgrid.
- */
- _render: function(data) {
- var self = this;
- self.colinfo = data.colinfo;
- self.primary_keys = (_.isEmpty(data.primary_keys) && data.has_oids) ? data.oids : data.primary_keys;
- self.client_primary_key = data.client_primary_key;
- self.cell_selected = false;
- self.selected_model = null;
- self.changedModels = [];
- self.has_oids = data.has_oids;
- self.oids = data.oids;
- $('.sql-editor-explain').html(EMPTY_EXPLAIN_CONTENT);
- self.explain_plan = false;
-
- /* If object don't have primary keys then set the
- * can_edit flag to false.
- */
- if ((self.primary_keys === null || self.primary_keys === undefined ||
- _.size(self.primary_keys) === 0) && self.has_oids == false)
- self.can_edit = false;
- else
- self.can_edit = true;
-
- /* If user can filter the data then we should enabled
- * Filter and Limit buttons.
- */
- if (self.can_filter) {
- $('.limit').prop('disabled', false);
- $('.limit').addClass('limit-enabled');
- $('#btn-filter').prop('disabled', false);
- $('#btn-filter-dropdown').prop('disabled', false);
- }
-
- // No data to save initially
- $('#btn-save-data').prop('disabled', true);
-
- // Initial settings for delete row, copy row and paste row buttons.
- $('#btn-delete-row').prop('disabled', true);
-
- if (!self.can_edit) {
- $('#btn-delete-row').prop('disabled', true);
- $('#btn-copy-row').prop('disabled', true);
- $('#btn-paste-row').prop('disabled', true);
- }
-
- // Fetch the columns metadata
- self._fetch_column_metadata.call(
- self, data,
- function() {
- var self_col = this;
-
- self_col.trigger(
- 'pgadmin-sqleditor:loading-icon:message',
- gettext('Loading data from the database server and rendering...'),
- self_col
- );
-
- // Show message in message and history tab in case of query tool
- self_col.total_time = calculateQueryRunTime.calculateQueryRunTime(
- self_col.query_start_time,
- self_col.query_end_time
- );
- var msg1 = gettext('Successfully run. Total query runtime: %s.',self_col.total_time);
- var msg2 = gettext('%s rows affected.',self_col.rows_affected);
-
- // Display the notifier if the timeout is set to >= 0
- if (self_col.info_notifier_timeout >= 0) {
- Notify.success(msg1 + ' ' + msg2, self_col.info_notifier_timeout);
- }
-
- var _msg = msg1 + '\n' + msg2;
-
-
- // If there is additional messages from server then add it to message
- if (!_.isNull(data.additional_messages) &&
- !_.isUndefined(data.additional_messages)) {
- _msg = data.additional_messages + '\n' + _msg;
- }
-
- self_col.update_msg_history(true, _msg, false);
-
- /* Add the data to the collection and render the grid.
- * In case of Explain draw the graph on explain panel
- * and add json formatted data to collection and render.
- */
- var explain_data_array = [],
- explain_data_json = null;
-
- if(data.result && !_.isEmpty(self_col.colinfo)
- && self_col.colinfo[0].name == 'QUERY PLAN' && !_.isEmpty(data.types)
- && data.types[0] && data.types[0].typname === 'json') {
- /* json is sent as text, parse it */
- explain_data_json = JSON.parse(data.result[0][0]);
- }
-
- if (explain_data_json && explain_data_json[0] &&
- explain_data_json[0].hasOwnProperty('Plan') &&
- _.isObject(explain_data_json[0]['Plan'])
- ) {
- var explain_data = [JSON.stringify(explain_data_json, null, 2)];
- explain_data_array.push(explain_data);
- // Make sure - the 'Data Output' panel is visible, before - we
- // start rendering the grid.
- self_col.gridView.data_output_panel.focus();
- setTimeout(
- function() {
- self_col.gridView.render_grid(
- explain_data_array, self_col.columns, self_col.can_edit,
- self_col.client_primary_key, 0
- );
- // Make sure - the 'Explain' panel is visible, before - we
- // start rendering the grid.
- self_col.gridView.explain_panel.focus();
- pgExplain.DrawJSONPlan(
- $('.sql-editor-explain'), explain_data_json
- );
- }, 10
- );
- } else {
- // Make sure - the 'Data Output' panel is visible, before - we
- // start rendering the grid.
- self_col.gridView.data_output_panel.focus();
- setTimeout(
- function() {
- self_col.gridView.render_grid(data.result, self_col.columns,
- self_col.can_edit, self_col.client_primary_key, data.rows_affected);
- }, 10
- );
- }
-
- // Hide the loading icon
- self_col.trigger('pgadmin-sqleditor:loading-icon:hide');
-
- // Enable/Disable download button based on query result
- if (!_.isUndefined(data) && Array.isArray(data.result) && data.result.length > 0) {
- self.enable_disable_download_btn(false);
- }
- else {
- self.enable_disable_download_btn(true);
- }
- }.bind(self)
- );
- },
-
- // This function creates the columns as required by the backgrid
- _fetch_column_metadata: function(data, cb) {
- var colinfo = data.colinfo,
- primary_keys = data.primary_keys,
- columns = [],
- self = this;
- // Store pg_types in an array
- var pg_types = new Array();
- _.each(data.types, function(r) {
- pg_types[r.oid] = [r.typname];
- });
-
- // Create columns required by slick grid to render
- _.each(colinfo, function(c) {
- var is_primary_key = false,
- is_editable = self.can_edit && (!self.is_query_tool || c.is_editable);
-
- // Check whether this column is a primary key
- if (is_editable && _.size(primary_keys) > 0) {
- _.each(primary_keys, function(value, key) {
- if (key === c.name)
- is_primary_key = true;
- });
- }
-
- // To show column label and data type in multiline,
- // The elements should be put inside the div.
- // Create column label and type.
- var col_type = '',
- column_label = '',
- col_cell;
- var type = 'unknown';
- if (pg_types[c.type_code]) {
- type = pg_types[c.type_code][0];
- } else if (pg_types[pg_types.length - 1][0]) {
- type = pg_types[pg_types.length - 1][0];
- }
-
- if (!is_primary_key)
- col_type += type;
- else
- col_type += '[PK] ' + type;
-
- if (c.precision && c.precision >= 0 && c.precision != 65535) {
- col_type += ' (' + c.precision;
- col_type += c.scale && c.scale != 65535 ?
- ',' + c.scale + ')' :
- ')';
- }
- // Identify cell type of column.
- switch (type) {
- case 'oid':
- col_cell = 'oid';
- break;
- case 'json':
- case 'json[]':
- case 'jsonb':
- case 'jsonb[]':
- col_cell = 'Json';
- break;
- case 'smallint':
- case 'smallint[]':
- case 'integer':
- case 'integer[]':
- case 'bigint':
- case 'bigint[]':
- case 'decimal':
- case 'decimal[]':
- case 'numeric':
- case 'numeric[]':
- case 'real':
- case 'real[]':
- case 'double precision':
- case 'double precision[]':
- col_cell = 'number';
- break;
- case 'boolean':
- col_cell = 'boolean';
- break;
- case 'character':
- case 'character[]':
- case '"char"':
- case '"char"[]':
- case 'character varying':
- case 'character varying[]':
- if (c.internal_size && c.internal_size >= 0 && c.internal_size != 65535) {
- // Update column type to display length on column header
- col_type += ' (' + c.internal_size + ')';
- }
- col_cell = 'string';
- break;
- case 'bytea':
- case 'bytea[]':
- col_cell = 'binary';
- break;
- case 'geometry':
- // PostGIS geometry type
- col_cell = 'geometry';
- break;
- case 'geography':
- // PostGIS geography type
- col_cell = 'geography';
- break;
- default:
- col_cell = 'string';
- }
-
- column_label = c.display_name + ' ' + col_type;
-
- var array_type_bracket_index = type.lastIndexOf('[]'),
- col = {
- 'name': c.name,
- 'display_name': c.display_name,
- 'column_type': col_type,
- 'column_type_internal': type,
- 'pos': c.pos,
- 'label': column_label,
- 'cell': col_cell,
- 'can_edit': (c.name == 'oid') ? false : is_editable,
- 'type': type,
- 'not_null': c.not_null,
- 'has_default_val': c.has_default_val,
- 'is_array': array_type_bracket_index > -1 && array_type_bracket_index + 2 == type.length,
- };
- columns.push(col);
- });
-
- self.columns = columns;
- if (cb && typeof(cb) == 'function') {
- cb();
- }
- },
-
- resetQueryHistoryObject: function(history) {
- history.total_time = '-';
- },
-
- set_sql_message(msg, append=false) {
- if(append) {
- $('.sql-editor-message').append(msg);
- } else {
- $('.sql-editor-message').text(msg);
- }
-
- // Scroll automatically when msgs appends to element
- setTimeout(function() {
- $('.sql-editor-message').scrollTop($('.sql-editor-message')[0].scrollHeight);
- }, 10);
- },
-
- // This function is used to raise appropriate message.
- update_msg_history: function(status, msg, clear_grid) {
- var self = this;
- if (clear_grid === undefined)
- clear_grid = true;
-
- self.gridView.messages_panel.focus();
-
- if (clear_grid) {
- // Delete grid
- if (self.gridView.handler.slickgrid) {
- self.gridView.handler.slickgrid.destroy();
-
- }
- // Misc cleaning
- self.columns = undefined;
- self.collection = undefined;
-
- self.set_sql_message(msg);
- } else {
- self.set_sql_message(_.escape(msg), true);
- }
-
- if (status != 'Busy') {
- setTimeout(() => {
- $('#btn-flash').prop('disabled', false);
- }, 400);
-
- self.trigger('pgadmin-sqleditor:loading-icon:hide');
-
- if(!self.total_time) {
- self.total_time = calculateQueryRunTime.calculateQueryRunTime(
- self.query_start_time,
- new Date());
- }
-
- if(_.isUndefined(self.history_query_source)) {
- self.history_query_source = QuerySources.VIEW_DATA;
- }
-
- let history_entry = {
- 'status': status,
- 'start_time': self.query_start_time,
- 'query': self.query,
- 'row_affected': self.rows_affected,
- 'total_time': self.total_time,
- 'message': msg,
- 'query_source': self.history_query_source,
- 'is_pgadmin_query': !self.is_query_tool,
- };
-
- if(!self.is_query_tool) {
- var info_msg = gettext('This query was generated by pgAdmin as part of a "View/Edit Data" operation');
- history_entry.info = info_msg;
- }
-
- self.add_to_history(history_entry);
- }
- },
-
- /* Make ajax call to save the history data */
- add_to_history: function(history_entry) {
- var self = this;
-
- $.ajax({
- url: url_for('sqleditor.add_query_history', {
- 'trans_id': self.transId,
- }),
- method: 'POST',
- contentType: 'application/json',
- data: JSON.stringify(history_entry),
- })
- .done(function() { /* This is intentional */ })
- .fail(function() { /* This is intentional */ });
-
- self.gridView.history_collection.add(history_entry);
- },
-
- /* This function is used to check whether cell
- * is editable or not depending on primary keys
- * and staged_rows flag
- */
- is_editable: function(obj) {
- var self = this;
- if (obj instanceof Backbone.Collection)
- return false;
- return (self.get('can_edit'));
- },
-
- enable_disable_download_btn: function(is_save_results_to_file_disabled) {
- var self = this;
- self.is_save_results_to_file_disabled = is_save_results_to_file_disabled;
- $('#btn-save-results-to-file').prop('disabled', is_save_results_to_file_disabled);
- },
-
- rows_to_delete: function(data) {
- let self = this;
- let tmp_keys = self.primary_keys;
-
- // re-calculate rows with no primary keys
- self.temp_new_rows = [];
- data.forEach(function(d, idx) {
- let p_keys_list = _.pick(d, _.keys(tmp_keys));
- let is_primary_key = Object.keys(p_keys_list).length > 0;
-
- if (!is_primary_key) {
- self.temp_new_rows.push(idx);
- }
- });
- self.rows_to_disable = _.clone(self.temp_new_rows);
- },
-
- // This function will delete selected row.
- _delete: function() {
- var self = this,
- deleted_keys = [],
- is_added = _.size(self.data_store.added),
- is_updated = _.size(self.data_store.updated);
-
- // Remove newly added rows from staged rows as we don't want to send them on server
- if (is_added) {
- _.each(self.data_store.added, function(val, key) {
- if (key in self.data_store.staged_rows) {
- // Remove the row from data store so that we do not send it on server
- deleted_keys.push(key);
- }
- });
- }
- // If only newly rows to delete and no data is there to send on server
- // then just re-render the grid
- if (_.size(self.data_store.staged_rows) > 0 && (_.size(self.data_store.staged_rows) === _.size(deleted_keys))) {
- var grid = self.slickgrid,
- dataView = grid.getData();
-
- grid.resetActiveCell();
-
- dataView.beginUpdate();
- for (let del_val of deleted_keys) {
- delete self.data_store.staged_rows[del_val];
- delete self.data_store.added[del_val];
- delete self.data_store.added_index[del_val];
- dataView.deleteItem(del_val);
- }
- dataView.endUpdate();
- self.rows_to_delete.apply(self, [dataView.getItems()]);
- grid.resetActiveCell();
- grid.setSelectedRows([]);
- grid.invalidate();
-
- // Nothing to copy or delete here
- $('#btn-delete-row').prop('disabled', true);
- $('#btn-copy-row').prop('disabled', true);
- if (_.size(self.data_store.added) || is_updated) {
- // Do not disable save button if there are
- // any other changes present in grid data
- $('#btn-save-data').prop('disabled', false);
- } else {
- $('#btn-save-data').prop('disabled', true);
- }
- Notify.success(gettext('Row(s) deleted.'));
- } else {
-
- let strikeout = true;
- _.each(_.keys(self.data_store.staged_rows), function(key) {
- if(key in self.data_store.deleted) {
- strikeout = false;
- }
- });
-
- if (!strikeout) {
- $(self.gridView.grid.getCanvasNode()).find('div.selected').removeClass('strikeout');
- _.each(_.keys(self.data_store.staged_rows), function(key) {
- if(key in self.data_store.deleted) {
- delete self.data_store.deleted[key];
- }
- });
- } else {
- // Strike out the rows to be deleted
- self.data_store.deleted = Object.assign({}, self.data_store.deleted, self.data_store.staged_rows);
- $(self.gridView.grid.getCanvasNode()).find('div.selected').addClass('strikeout');
- }
-
- if (_.size(self.data_store.added) || is_updated || _.size(self.data_store.deleted)) {
- // Do not disable save button if there are
- // any other changes present in grid data
- $('#btn-save-data').prop('disabled', false);
- } else {
- $('#btn-save-data').prop('disabled', true);
- }
- }
- },
-
- // This function will open save file dialog conditionally.
-
- _save_file: function(save_as=false) {
- var self = this;
-
- var current_file = self.gridView.current_file;
- if (!_.isUndefined(current_file) && !save_as) {
- self._save_file_handler(current_file);
- } else {
- // provide custom option to save file dialog
- var params = {
- 'supported_types': ['*', 'sql'],
- 'dialog_type': 'create_file',
- 'dialog_title': 'Save File',
- 'btn_primary': 'Save',
- };
- pgAdmin.FileManager.init();
- pgAdmin.FileManager.show_dialog(params);
- }
- },
-
- /* This function will fetch the list of changed models and make
- * the ajax call to save the data into the database server.
- */
- save_data: function() {
- var self = this;
-
- if(!self.can_edit)
- return;
-
- var is_added = _.size(self.data_store.added),
- is_updated = _.size(self.data_store.updated),
- is_deleted = _.size(self.data_store.deleted);
-
- if (!is_added && !is_updated && !is_deleted) {
- return; // Nothing to save here
- }
-
- self.trigger(
- 'pgadmin-sqleditor:loading-icon:show',
- gettext('Saving the updated data...')
- );
- // Disable query tool buttons and cancel button only if query tool
- if(self.is_query_tool)
- self.disable_tool_buttons(true, true);
-
- // Add the columns to the data so the server can remap the data
- var req_data = self.data_store, view = self.gridView;
- req_data.columns = view ? view.handler.columns : self.columns;
-
- var save_successful = false, save_start_time = new Date();
-
- // Make ajax call to save the data
- $.ajax({
- url: url_for('sqleditor.save', {
- 'trans_id': self.transId,
- }),
- method: 'POST',
- contentType: 'application/json',
- data: JSON.stringify(req_data),
- })
- .done(function(res) {
- var grid = self.slickgrid,
- dataView = grid.getData(),
- data_length = dataView.getLength(),
- data = [];
-
- var transaction_status = res.data.transaction_status;
-
- // Update last transaction status
- self.last_transaction_status = transaction_status;
-
- var is_commit_required = transaction_status > 0; // 0 is idle
-
- // Enable/Disable commit and rollback button.
- if (is_commit_required) {
- self.disable_transaction_buttons(false);
- } else {
- self.disable_transaction_buttons(true);
- }
- // Enable query tool buttons and cancel button only if query tool
- if(self.is_query_tool)
- self.disable_tool_buttons(false);
-
- if (res.data.status) {
- // Disable Save Data Changes button
- $('#btn-save-data').prop('disabled', true);
-
- save_successful = true;
-
- // Remove highlighted cells styling
- for (let i = 1; i <= self.numberOfModifiedCells; i++)
- grid.removeCellCssStyles(i);
-
- self.numberOfModifiedCells = 0;
-
- if(is_added) {
- // Update the rows in a grid after addition
- dataView.beginUpdate();
- _.each(res.data.query_results, function(r) {
- if (!_.isNull(r.row_added)) {
- // Fetch temp_id returned by server after addition
- var row_id = Object.keys(r.row_added)[0];
- _.each(req_data.added_index, function(v, k) {
- if (v == row_id) {
- // Fetch item data through row index
- var item_fetched = grid.getDataItem(k);
- _.extend(item_fetched, r.row_added[row_id]);
- }
- });
- }
- });
- dataView.endUpdate();
- }
- // Remove flag is_row_copied from copied rows
- _.each(data, function(row) {
- if (row.is_row_copied) {
- delete row.is_row_copied;
- }
- });
-
- // Remove 2d copied_rows array
- if (grid.copied_rows) {
- delete grid.copied_rows;
- }
-
- // Remove deleted rows from client as well
- if (is_deleted) {
- var rows = _.keys(self.data_store.deleted);
- if (data_length == rows.length) {
- // This means all the rows are selected, clear all data
- data = [];
- dataView.setItems(data, self.client_primary_key);
- } else {
- dataView.beginUpdate();
- for (let row_val of rows) {
- var item = grid.getData().getItemById(row_val);
- data.push(item);
- dataView.deleteItem(item[self.client_primary_key]);
- }
- dataView.endUpdate();
- }
- self.rows_to_delete.apply(self, [data]);
- }
-
- grid.setSelectedRows([]);
-
- // Reset data store
- self.reset_data_store();
-
- // Reset old primary key data now
- self.primary_keys_data = {};
-
- // Clear msgs after successful save
- self.set_sql_message('');
-
- Notify.success(gettext('Data saved successfully.'));
-
- if(is_commit_required)
- Notify.info(gettext('Auto-commit is off. You still need to commit changes to the database.'));
-
-
- } else {
- // Something went wrong while saving data on the db server
- self.set_sql_message(res.data.result);
- var err_msg = gettext('%s.', res.data.result);
- Notify.error(err_msg, 20000);
- // If the transaction is not idle, notify the user that previous queries are not rolled back,
- // only the failed save queries.
- if (transaction_status != 0)
- Notify.info(gettext('Saving data changes was rolled back but the current transaction is ' +
- 'still active; previous queries are unaffected.'));
- grid.setSelectedRows([]);
- // To highlight the row at fault
- if (_.has(res.data, '_rowid') &&
- (!_.isUndefined(res.data._rowid) || !_.isNull(res.data._rowid))) {
- var _row_index = self._find_rowindex(res.data._rowid);
- if (_row_index in self.data_store.added_index) {
- // Remove new row index from temp_list if save operation
- // fails
- var index = self.handler.temp_new_rows.indexOf(res.data._rowid);
- if (index > -1) {
- self.handler.temp_new_rows.splice(index, 1);
- }
- self.data_store.added[self.data_store.added_index[_row_index]].err = true;
- } else if (_row_index in self.data_store.updated_index) {
- self.data_store.updated[self.data_store.updated_index[_row_index]].err = true;
- }
- }
- grid.gotoCell(_row_index, 1);
- }
-
- var query_history_info_msg = gettext('This query was generated by pgAdmin as part of a "Save Data" operation');
-
- _.each(res.data.query_results, function(r) {
- var history_entry = {
- 'status': r.status,
- 'start_time': save_start_time,
- 'query': r.sql,
- 'row_affected': r.rows_affected,
- 'total_time': null,
- 'message': r.result,
- 'query_source': QuerySources.SAVE_DATA,
- 'is_pgadmin_query': true,
- 'info': query_history_info_msg,
- };
- self.add_to_history(history_entry);
- });
-
- self.trigger('pgadmin-sqleditor:loading-icon:hide');
-
- grid.invalidate();
- if (self.close_on_save) {
- if(save_successful) {
- // Check for any other needed confirmations before closing
- self.check_needed_confirmations_before_closing_panel();
- }
- else {
- self.close_on_save = false;
- }
- }
- })
- .fail(function(e) {
- let stateParams = [view];
- let msg = httpErrorHandler.handleQueryToolAjaxError(
- pgAdmin, self, e, 'save_data', stateParams, true
- );
- // Enable query tool buttons and cancel button only if query tool
- if(self.is_query_tool)
- self.disable_tool_buttons(false);
- if (msg)
- self.update_msg_history(false, msg);
- });
- },
-
- reset_data_store: function() {
- var self = this;
- // This holds all the inserted/updated/deleted data from grid
- self.data_store = {
- updated: {},
- added: {},
- staged_rows: {},
- deleted: {},
- updated_index: {},
- added_index: {},
- };
- },
-
- // Find index of row at fault from grid data
- _find_rowindex: function(rowid) {
- var self = this,
- grid = self.slickgrid,
- dataView = grid.getData(),
- data = dataView.getItems(),
- _rowid,
- count = 0,
- _idx = -1;
-
- // If _rowid is object then it's update/delete operation
- if (_.isObject(rowid)) {
- _rowid = rowid;
- } else if (_.isString(rowid)) { // Insert operation
- rowid = {};
- rowid[self.client_primary_key] = rowid;
- _rowid = rowid;
- } else {
- // Something is wrong with unique id
- return _idx;
- }
-
- _.find(data, function(d) {
- // search for unique id in row data if found than its the row
- // which error out on server side
- var tmp = []; //_.findWhere needs array of object to work
- tmp.push(d);
- if (_.findWhere(tmp, _rowid)) {
- _idx = count;
- // Now exit the loop by returning true
- return true;
- }
- count++;
- });
-
- // Not able to find in grid Data
- return _idx;
- },
-
- // Save as
- _save_as: function() {
- return this._save_file(true);
- },
-
- // Set panel title.
- setTitle: function(title, is_file, is_dirty_editor=false) {
- var self = this;
- var open_new_tab = self.browser_preferences.new_browser_tab_open;
- if(open_new_tab && open_new_tab.includes('qt')) {
- window.document.title = _.escape(title);
- } else {
- _.each(pgWindow.default.pgAdmin.Browser.docker.findPanels('frm_datagrid'), function(p) {
- if (p.isVisible()) {
- if(is_dirty_editor) {
- p.is_dirty_editor = true;
- }
- panelTitleFunc.setQueryToolDockerTitle(p, self.is_query_tool, title, is_file);
- }
- });
- }
- },
-
- // load select file dialog
- _load_file: function() {
- var self = this;
-
- /* If is_query_changed flag is set to false then no need to
- * confirm with the user for unsaved changes.
- */
- if (self.is_query_changed) {
- Notify.confirm(gettext('Unsaved changes'),
- gettext('Are you sure you wish to discard the current changes?'),
- function() {
- // User do not want to save, just continue
- self._open_select_file_manager();
- },
- function() {
- return true;
- }
- );
- } else {
- self._open_select_file_manager();
- }
-
- },
-
- // Open FileManager
- _open_select_file_manager: function() {
- var params = {
- 'supported_types': ['*', 'sql'], // file types allowed
- 'dialog_type': 'select_file', // open select file dialog
- };
- pgAdmin.FileManager.init();
- pgAdmin.FileManager.show_dialog(params);
- },
-
- // read file data and return as response
- _select_file_handler: function(e) {
- var self = this,
- _e = e,
- data = {
- 'file_name': decodeURI(e),
- };
-
- self.trigger(
- 'pgadmin-sqleditor:loading-icon:show',
- gettext('Loading the file...')
- );
- // set cursor to progress before file load
- var $busy_icon_div = $('.sql-editor-busy-fetching');
- $busy_icon_div.addClass('show_progress');
-
- // Make ajax call to load the data from file
- $.ajax({
- url: url_for('sqleditor.load_file'),
- method: 'POST',
- contentType: 'application/json',
- data: JSON.stringify(data),
- })
- .done(function(res) {
- self.gridView.query_tool_obj.setValue(res);
- self.gridView.current_file = e;
- self.gridView.query_tool_obj.file_data = res;
- self.setTitle(self.gridView.current_file.split('\\').pop().split('/').pop(), true);
- self.trigger('pgadmin-sqleditor:loading-icon:hide');
- // hide cursor
- $busy_icon_div.removeClass('show_progress');
-
- // disable save button on file save
- $('#btn-save-file').prop('disabled', true);
- $('#btn-file-menu-save').css('display', 'none');
-
- // Update the flag as new content is just loaded.
- self.is_query_changed = false;
- setTimeout(() => { self.gridView.query_tool_obj.focus(); }, 200);
- })
- .fail(function(er) {
- self.trigger('pgadmin-sqleditor:loading-icon:hide');
- let stateParams = [_e];
- let msg = httpErrorHandler.handleQueryToolAjaxError(
- pgAdmin, self, er, '_select_file_handler', stateParams, false
- );
- if (msg)
- Notify.error(msg);
- // hide cursor
- $busy_icon_div.removeClass('show_progress');
- });
- },
-
- // read data from codemirror and write to file
- _save_file_handler: function(e) {
- var self = this,
- _e = e,
- data = {
- 'file_name': decodeURI(e),
- 'file_content': self.gridView.query_tool_obj.getValue(),
- };
- var file_data = self.gridView.query_tool_obj.getValue();
- self.trigger(
- 'pgadmin-sqleditor:loading-icon:show',
- gettext('Saving the queries in the file...')
- );
-
- // Make ajax call to save the data to file
- $.ajax({
- url: url_for('sqleditor.save_file'),
- method: 'POST',
- contentType: 'application/json',
- data: JSON.stringify(data),
- })
- .done(function(res) {
- if (res.data.status) {
- Notify.success(gettext('File saved successfully.'));
- self.gridView.current_file = e;
- self.setTitle(self.gridView.current_file.replace(/^.*[\\\/]/g, ''), true);
- self.gridView.query_tool_obj.file_data = file_data;
- // disable save button on file save
- $('#btn-save-file').prop('disabled', true);
- $('#btn-file-menu-save').css('display', 'none');
-
- // Update the flag as query is already saved.
- self.is_query_changed = false;
- setTimeout(() => { self.gridView.query_tool_obj.focus(); }, 200);
- }
- self.trigger('pgadmin-sqleditor:loading-icon:hide');
- if (self.close_on_save) {
- // Check for any other needed confirmations before closing
- self.check_needed_confirmations_before_closing_panel();
- }
- })
- .fail(function(er) {
- self.trigger('pgadmin-sqleditor:loading-icon:hide');
- let stateParams = [_e];
- let msg = httpErrorHandler.handleQueryToolAjaxError(
- pgAdmin, self, er, '_save_file_handler', stateParams, false
- );
- if (msg)
- Notify.error(msg);
- });
- },
-
- // codemirror text change event
- _on_query_change: function() {
- var self = this;
-
- if (!self.is_query_changed) {
- // Update the flag as query is going to changed.
- self.is_query_changed = true;
-
- if (self.gridView.current_file) {
- var title = self.gridView.current_file.replace(/^.*[\\\/]/g, '') + ' *';
- self.setTitle(title, true);
- } else {
- var open_new_tab = self.browser_preferences.new_browser_tab_open;
- var is_dirty_editor = false;
- if(open_new_tab && open_new_tab.includes('qt')) {
- title = window.document.title + ' *';
- } else {
- // Find the title of the visible panel
- _.each(pgWindow.default.pgAdmin.Browser.docker.findPanels('frm_datagrid'), function(p) {
- if (p.isVisible()) {
- self.gridView.panel_title = $(p._title).text();
- }
- });
-
- title = self.gridView.panel_title + ' *';
- is_dirty_editor = true;
- }
- self.setTitle(title, false, is_dirty_editor);
- }
-
- $('#btn-save-file').prop('disabled', false);
- $('#btn-file-menu-save').css('display', 'block');
- $('#btn-file-menu-dropdown').prop('disabled', false);
- } else {
- if(self.gridView.current_file) {
- if (self.gridView.query_tool_obj.file_data == self.gridView.query_tool_obj.getValue()) {
- title = self.gridView.current_file.replace(/^.*[\\\/]/g, '');
- is_dirty_editor = false;
- } else {
- title = self.gridView.current_file.replace(/^.*[\\\/]/g, '') + ' *';
- is_dirty_editor = true;
- }
-
- self.setTitle(title, true, is_dirty_editor);
- }
- }
- },
-
- // This function will set the required flag for polling response data
- _init_polling_flags: function() {
- var self = this;
-
- // To get a timeout for polling fallback timer in seconds in
- // regards to elapsed time
- self.POLL_FALLBACK_TIME = function() {
- var seconds = parseInt((Date.now() - self.query_start_time.getTime()) / 1000);
- // calculate & return fall back polling timeout
- if (seconds >= 10 && seconds < 30) {
- return 500;
- } else if (seconds >= 30 && seconds < 60) {
- return 1000;
- } else if (seconds >= 60 && seconds < 90) {
- return 2000;
- } else if (seconds >= 90) {
- return 5000;
- } else {
- return 1;
- }
- };
- },
- // This function will show the filter in the text area.
- _show_filter: function() {
- let self = this,
- reconnect = false;
-
- /* When server is disconnected and connected, connection is lost,
- * To reconnect pass true
- */
- if (arguments.length > 0 &&
- arguments[arguments.length - 1] == 'connect') {
- reconnect = true;
- }
- FilterHandler.dialog(self, reconnect);
- },
- // This function will show the new connection.
- _show_new_connection: function() {
- let self = this,
- reconnect = false;
-
- /* When server is disconnected and connected, connection is lost,
- * To reconnect pass true
- */
- if (arguments.length > 0 && arguments[arguments.length - 1] == 'connect') {
- reconnect = true;
- }
-
- newConnectionHandler.dialog(self, reconnect, self.browser_preferences);
- },
- // This function will include the filter by selection.
- _include_filter: function() {
- var self = this,
- data = {},
- grid, active_column, column_info, _values;
-
- grid = self.slickgrid;
- active_column = grid.getActiveCell();
-
- // If no cell is selected then return from the function
- if (_.isNull(active_column) || _.isUndefined(active_column))
- return;
-
- column_info = grid.getColumns()[active_column.cell];
-
- // Fetch current row data from grid
- _values = grid.getDataItem(active_column.row, active_column.cell);
- if (_.isNull(_values) || _.isUndefined(_values))
- return;
-
- // Add column position and it's value to data
- data[column_info.field] = _.isUndefined(_values[column_info.field]) ? '' : _values[column_info.field];
-
- self.trigger(
- 'pgadmin-sqleditor:loading-icon:show',
- gettext('Applying the new filter...')
- );
-
- // Make ajax call to include the filter by selection
- $.ajax({
- url: url_for('sqleditor.inclusive_filter', {
- 'trans_id': self.transId,
- }),
- method: 'POST',
- contentType: 'application/json',
- data: JSON.stringify(data),
- })
- .done(function(res) {
- self.trigger('pgadmin-sqleditor:loading-icon:hide');
- setTimeout(
- function() {
- if (res.data.status) {
- // Refresh the sql grid
- queryToolActions.executeQuery(self);
- } else {
- Notify.alert(gettext('Filter By Selection Error'), res.data.result);
- }
- }
- );
- })
- .fail(function(e) {
- self.trigger('pgadmin-sqleditor:loading-icon:hide');
- let msg = httpErrorHandler.handleQueryToolAjaxError(
- pgAdmin, self, e, '_include_filter', [], true
- );
- if (msg)
- Notify.alert(gettext('Filter By Selection Error'), msg);
- });
- },
-
- // This function will exclude the filter by selection.
- _exclude_filter: function() {
- var self = this,
- data = {},
- grid, active_column, column_info, _values;
-
- grid = self.slickgrid;
- active_column = grid.getActiveCell();
-
- // If no cell is selected then return from the function
- if (_.isNull(active_column) || _.isUndefined(active_column))
- return;
-
- column_info = grid.getColumns()[active_column.cell];
-
- // Fetch current row data from grid
- _values = grid.getDataItem(active_column.row, active_column.cell);
- if (_.isNull(_values) || _.isUndefined(_values))
- return;
-
- // Add column position and it's value to data
- data[column_info.field] = _.isUndefined(_values[column_info.field]) ? '' : _values[column_info.field];
-
- self.trigger(
- 'pgadmin-sqleditor:loading-icon:show',
- gettext('Applying the new filter...')
- );
-
- // Make ajax call to exclude the filter by selection.
- $.ajax({
- url: url_for('sqleditor.exclusive_filter', {
- 'trans_id': self.transId,
- }),
- method: 'POST',
- contentType: 'application/json',
- data: JSON.stringify(data),
- })
- .done(function(res) {
- self.trigger('pgadmin-sqleditor:loading-icon:hide');
- setTimeout(
- function() {
- if (res.data.status) {
- // Refresh the sql grid
- queryToolActions.executeQuery(self);
- } else {
- Notify.alert(gettext('Filter Exclude Selection Error'), res.data.result);
- }
- }, 10
- );
- })
- .fail(function(e) {
- self.trigger('pgadmin-sqleditor:loading-icon:hide');
- let msg = httpErrorHandler.handleQueryToolAjaxError(
- pgAdmin, self, e, '_exclude_filter', [], true
- );
- if (msg)
- Notify.alert(gettext('Filter Exclude Selection Error'), msg);
- });
- },
-
- // This function will remove the filter.
- _remove_filter: function() {
- var self = this;
-
- self.trigger(
- 'pgadmin-sqleditor:loading-icon:show',
- gettext('Removing the filter...')
- );
-
- // Make ajax call to exclude the filter by selection.
- $.ajax({
- url: url_for('sqleditor.remove_filter', {
- 'trans_id': self.transId,
- }),
- method: 'POST',
- })
- .done(function(res) {
- self.trigger('pgadmin-sqleditor:loading-icon:hide');
- setTimeout(
- function() {
- if (res.data.status) {
- // Refresh the sql grid
- queryToolActions.executeQuery(self);
- } else {
- Notify.alert(gettext('Remove Filter Error'), res.data.result);
- }
- }
- );
- })
- .fail(function(e) {
- self.trigger('pgadmin-sqleditor:loading-icon:hide');
- let msg = httpErrorHandler.handleQueryToolAjaxError(
- pgAdmin, self, e, '_remove_filter', [], true
- );
- if (msg)
- Notify.alert(gettext('Remove Filter Error'), msg);
- });
- },
-
- // This function will copy the selected row.
- _copy_row: copyData,
-
- _copy_row_with_header: function() {
- $('.copy-with-header').toggleClass('visibility-hidden');
- },
-
- // This function will enable Paste button if data is copied in some other active session
- _copied_in_other_session: function(e, copiedWithHeaders) {
- pgAdmin.SqlEditor.copiedInOtherSessionWithHeaders = copiedWithHeaders;
- $('#btn-paste-row').prop('disabled', false);
- },
-
- // This function will paste the selected row.
- _paste_row: function() {
- var self = this;
- let rowsText = clipboard.getTextFromClipboard();
- let copied_rows = pgadminUtils.CSVToArray(rowsText, self.preferences.results_grid_field_separator, self.preferences.results_grid_quote_char);
- // Do not parse row if rows are copied with headers
- if(pgAdmin.SqlEditor.copiedInOtherSessionWithHeaders) {
- copied_rows = copied_rows.slice(1);
- }
- var row_index = 0;
- copied_rows = copied_rows.reduce((partial, values) => {
- // split each row with field separator character
- let row = {};
- for (let col in self.columns) {
- let v = values[col];
-
- // set value to default or null depending on column metadata
- if(v === '') {
- if(self.columns[col].has_default_val) {
- v = undefined;
- } else if (self.copied_rows[row_index][self.columns[col].display_name] === null) {
- v = null;
- } else {
- v = '';
- }
- }
-
- if(self.columns[col].cell === 'boolean') {
- if(v == 'true') {
- v = true;
- } else if(v == 'false') {
- v = false;
- } else {
- v = null;
- }
- }
-
- row[self.columns[col].name] = v;
- }
- partial.push(row);
- row_index ++;
- return partial;
- }, []);
-
- // If there are rows to paste?
- if (copied_rows.length > 0) {
- // Enable save button so that user can
- // save newly pasted rows on server
- $('#btn-save-data').prop('disabled', false);
-
- var grid = self.slickgrid,
- dataView = grid.getData(),
- count = dataView.getLength(),
- array_types = [];
- // for quick look up create list of array data types
- for (var k in self.columns) {
- if (self.columns[k].is_array) {
- array_types.push(self.columns[k].name);
- }
- }
-
- var arr_to_object = function (arr) {
- var obj = {};
-
- _.each(arr, function (val, i) {
- if (arr[i] !== undefined) {
- // Do not stringify array types.
- if (_.isObject(arr[i]) && array_types.indexOf(i) == -1) {
- obj[String(i)] = JSON.stringify(arr[i]);
- } else {
- obj[String(i)] = arr[i];
- }
- }
- });
- return obj;
- };
-
- // Generate Unique key for each pasted row(s)
- // Convert array values to object to send to server
- // Add flag is_row_copied to handle [default] and [null]
- // for copied rows.
- // Add index of copied row into temp_new_rows
- // Trigger grid.onAddNewRow when a row is copied
- // Reset selection
-
- dataView.beginUpdate();
- _.each(copied_rows, function (row) {
- var new_row = arr_to_object(row),
- _key = (self.gridView.client_primary_key_counter++).toString();
- new_row.is_row_copied = true;
- self.temp_new_rows.push(count);
- new_row[self.client_primary_key] = _key;
- if (self.has_oids && new_row.oid) {
- new_row.oid = null;
- }
-
- dataView.addItem(new_row);
- self.data_store.added[_key] = {
- 'err': false,
- 'data': new_row,
- };
- self.data_store.added_index[count] = _key;
- count++;
- });
- dataView.endUpdate();
- grid.invalidateRow(grid.getSelectedRows());
- grid.updateRowCount();
- grid.render();
- // Pasted row/s always append so bring last row in view port.
- grid.scrollRowIntoView(dataView.getLength());
- grid.setSelectedRows([]);
- }
- },
-
- // This function will set the limit for SQL query
- _set_limit: function() {
- var self = this,
- limit = parseInt($('.limit').val());
-
- self.trigger(
- 'pgadmin-sqleditor:loading-icon:show',
- gettext('Setting the limit on the result...')
- );
- // Make ajax call to change the limit
- $.ajax({
- url: url_for('sqleditor.set_limit', {
- 'trans_id': self.transId,
- }),
- method: 'POST',
- contentType: 'application/json',
- data: JSON.stringify(limit),
- })
- .done(function(res) {
- self.trigger('pgadmin-sqleditor:loading-icon:hide');
- setTimeout(
- function() {
- if (res.data.status) {
- // Refresh the sql grid
- queryToolActions.executeQuery(self);
- } else {
- Notify.alert(gettext('Change limit Error'), res.data.result);
- }
- }, 10
- );
- })
- .fail(function(e) {
- self.trigger('pgadmin-sqleditor:loading-icon:hide');
- let msg = httpErrorHandler.handleQueryToolAjaxError(
- pgAdmin, self, e, '_set_limit', [], true
- );
- if (msg)
- Notify.alert(gettext('Change limit Error'), msg);
- });
- },
-
- // This function is used to enable/disable buttons
- disable_tool_buttons: function(disabled, disable_cancel=null) {
- let mode_disabled = disabled;
-
- /* Buttons be always disabled in view/edit mode */
- if(!this.is_query_tool) {
- mode_disabled = true;
- }
-
- $('#btn-explain').prop('disabled', mode_disabled);
- $('#btn-explain-analyze').prop('disabled', mode_disabled);
- $('#btn-explain-options-dropdown').prop('disabled', mode_disabled);
- $('#btn-edit-dropdown').prop('disabled', mode_disabled);
- $('#btn-load-file').prop('disabled', mode_disabled);
- if(this.gridView.current_file) {
- if(this.gridView.query_tool_obj.file_data != this.gridView.query_tool_obj.getValue()) {
- $('#btn-save-file').prop('disabled', mode_disabled);
- }
- } else {
- $('#btn-save-file').prop('disabled', mode_disabled);
- }
-
- $('#btn-file-menu-dropdown').prop('disabled', mode_disabled);
- $('#btn-find').prop('disabled', mode_disabled);
- $('#btn-find-menu-dropdown').prop('disabled', mode_disabled);
- $('#btn-macro-dropdown').prop('disabled', mode_disabled);
-
- if (this.is_query_tool) {
-
- if(disable_cancel !== null)
- $('#btn-cancel-query').prop('disabled', disable_cancel);
- // Cancel query tool needs opposite behaviour if not explicitly given
- else
- $('#btn-cancel-query').prop('disabled', !disabled);
-
- if(this.is_transaction_buttons_disabled) {
- $('#btn-query-dropdown').prop('disabled', disabled);
- } else {
- $('#btn-query-dropdown').prop('disabled', true);
- }
- } else {
- $('#btn-query-dropdown').prop('disabled', mode_disabled);
- }
- },
-
- // This function is used to enable/disable commit/rollback buttons
- disable_transaction_buttons: function(disabled) {
- this.is_transaction_buttons_disabled = disabled;
- if (this.is_query_tool) {
- $('#btn-commit').prop('disabled', disabled);
- $('#btn-rollback').prop('disabled', disabled);
- }
- },
-
- /* This function is used to highlight the error line and
- * underlining for the error word.
- */
- _highlight_error: function(result) {
- var self = this,
- error_line_no = 0,
- start_marker = 0,
- end_marker = 0,
- selected_line_no = 0;
-
- // Remove already existing marker
- self.gridView.query_tool_obj.removeLineClass(self.marked_line_no, 'wrap', 'CodeMirror-activeline-background');
-
- // In case of selection we need to find the actual line no
- if (self.gridView.query_tool_obj.getSelection().length > 0)
- selected_line_no = self.gridView.query_tool_obj.getCursor(true).line;
-
- // Fetch the LINE string using regex from the result
- var line = /LINE (\d+)/.exec(result),
- // Fetch the Character string using regex from the result
- char = /Character: (\d+)/.exec(result);
-
- // If line and character is null then no need to mark
- if (line != null && char != null) {
- error_line_no = self.marked_line_no = (parseInt(line[1]) - 1) + selected_line_no;
- var error_char_no = (parseInt(char[1]) - 1);
-
- /* We need to loop through each line till the error line and
- * count the total no of character to figure out the actual
- * starting/ending marker point for the individual line. We
- * have also added 1 per line for the "\n" character.
- */
- var prev_line_chars = 0;
- var loop_index = selected_line_no > 0 ? selected_line_no : 0;
- for (var i = loop_index; i < error_line_no; i++)
- prev_line_chars += self.gridView.query_tool_obj.getLine(i).length + 1;
-
- /* Marker starting point for the individual line is
- * equal to error character index minus total no of
- * character till the error line starts.
- */
- start_marker = error_char_no - prev_line_chars;
-
- // Find the next space from the character or end of line
- var error_line = self.gridView.query_tool_obj.getLine(error_line_no);
-
- if (_.isUndefined(error_line)) return;
- end_marker = error_line.indexOf(' ', start_marker);
- if (end_marker < 0)
- end_marker = error_line.length;
-
- // Mark the error text
- self.gridView.marker = self.gridView.query_tool_obj.markText({
- line: error_line_no,
- ch: start_marker,
- }, {
- line: error_line_no,
- ch: end_marker,
- }, {
- className: 'sql-editor-mark',
- });
-
- self.gridView.query_tool_obj.addLineClass(self.marked_line_no, 'wrap', 'CodeMirror-activeline-background');
- }
- },
-
- // This function will cancel the running query.
- _cancel_query: function() {
- var self = this;
- $.ajax({
- url: url_for('sqleditor.cancel_transaction', {
- 'trans_id': self.transId,
- }),
- method: 'POST',
- contentType: 'application/json',
- })
- .done(function(res) {
- if (!res.data.status) {
- Notify.alert(gettext('Cancel Query Error'), res.data.result);
- }
- self.disable_tool_buttons(false);
- is_query_running = false;
- if(!_.isUndefined(self.download_results_obj)) {
- self.download_results_obj.abort();
- $('#btn-flash').prop('disabled', false);
- self.trigger(
- 'pgadmin-sqleditor:loading-icon:hide');
- }
- setTimeout(() => { self.gridView.query_tool_obj.focus(); }, 200);
- })
- .fail(function(e) {
- self.disable_tool_buttons(false);
-
- let msg = httpErrorHandler.handleQueryToolAjaxError(
- pgAdmin, self, e, '_cancel_query', [], false
- );
- if (msg)
- Notify.alert(gettext('Cancel Query Error'), msg);
- });
- },
-
- // Trigger query result download to csv.
- trigger_csv_download: function(filename) {
- var self = this,
- url = url_for('sqleditor.query_tool_download', {
- 'trans_id': self.transId,
- }),
- data = { filename: filename };
-
- // Disable the Execute button
- $('#btn-flash').prop('disabled', true);
- self.enable_disable_download_btn(true);
- self.disable_tool_buttons(true);
- self.set_sql_message('');
- self.trigger(
- 'pgadmin-sqleditor:loading-icon:show',
- gettext('Downloading Results...')
- );
-
- // Get the CSV file
- self.download_results_obj = $.ajax({
- type: 'POST',
- url: url,
- data: data,
- cache: false,
- }).done(function(response) {
- // if response.data present, extract the message
- if(!_.isUndefined(response.data)) {
- if(!response.status) {
- self._highlight_error(response.data.result);
- self.set_sql_message(response.data.result);
- }
- } else {
- let respBlob = new Blob([response], {type : 'text/csv'}),
- urlCreator = window.URL || window.webkitURL,
- download_url = urlCreator.createObjectURL(respBlob),
- current_browser = pgAdmin.Browser.get_browser(),
- link = document.createElement('a');
-
- document.body.appendChild(link);
-
- if (current_browser.name === 'IE' && window.navigator.msSaveBlob) {
- // IE10+ : (has Blob, but not a[download] or URL)
- window.navigator.msSaveBlob(respBlob, filename);
- } else {
- link.setAttribute('href', download_url);
- link.setAttribute('download', filename);
- link.click();
- }
-
- document.body.removeChild(link);
- self.download_results_obj = undefined;
- }
-
- // Enable the execute button
- $('#btn-flash').prop('disabled', false);
- self.enable_disable_download_btn(false);
- self.disable_tool_buttons(false);
- self.trigger('pgadmin-sqleditor:loading-icon:hide');
- }).fail(function(err) {
- let msg = '';
- // Enable the execute button
- $('#btn-flash').prop('disabled', false);
- self.enable_disable_download_btn(false);
- self.disable_tool_buttons(false);
- self.trigger('pgadmin-sqleditor:loading-icon:hide');
-
-
- if (err.statusText == 'abort') {
- msg = gettext('CSV Download cancelled.');
- } else {
- msg = httpErrorHandler.handleQueryToolAjaxError(
- pgAdmin, self, err, 'trigger_csv_download', [], true
- );
- }
- // Check if error message is present
- if (msg)
- Notify.alert(gettext('Download CSV error'), msg);
- });
- },
-
- call_cache_preferences: function() {
- let browser = pgWindow.default.pgAdmin.Browser;
- browser.cache_preferences('sqleditor');
-
- /* This will make sure to get latest updates only and not older events */
- pgBrowser.preference_version(pgBrowser.generate_preference_version());
- },
-
- _auto_rollback: function() {
- var self = this,
- auto_rollback = true;
-
- if ($('.auto-rollback').hasClass('visibility-hidden') === true)
- $('.auto-rollback').removeClass('visibility-hidden');
- else {
- $('.auto-rollback').addClass('visibility-hidden');
- auto_rollback = false;
- }
-
- // Make ajax call to change the limit
- $.ajax({
- url: url_for('sqleditor.auto_rollback', {
- 'trans_id': self.transId,
- }),
- method: 'POST',
- contentType: 'application/json',
- data: JSON.stringify(auto_rollback),
- })
- .done(function(res) {
- if (!res.data.status)
- Notify.alert(gettext('Auto Rollback Error'), res.data.result);
- })
- .fail(function(e) {
-
- let msg = httpErrorHandler.handleQueryToolAjaxError(
- pgAdmin, self, e, '_auto_rollback', [], true
- );
- if (msg)
- Notify.alert(gettext('Auto Rollback Error'), msg);
- });
- },
-
- _auto_commit: function() {
- var self = this,
- auto_commit = true;
-
- if ($('.auto-commit').hasClass('visibility-hidden') === true)
- $('.auto-commit').removeClass('visibility-hidden');
- else {
- $('.auto-commit').addClass('visibility-hidden');
- auto_commit = false;
- }
-
- // Make ajax call to toggle auto commit
- $.ajax({
- url: url_for('sqleditor.auto_commit', {
- 'trans_id': self.transId,
- }),
- method: 'POST',
- contentType: 'application/json',
- data: JSON.stringify(auto_commit),
- })
- .done(function(res) {
- if (!res.data.status)
- Notify.alert(gettext('Auto Commit Error'), res.data.result);
- })
- .fail(function(e) {
- let msg = httpErrorHandler.handleQueryToolAjaxError(
- pgAdmin, self, e, '_auto_commit', [], true
- );
- if (msg)
- Notify.alert(gettext('Auto Commit Error'), msg);
- });
-
- },
-
- _toggle_explain_option: function(type) {
- let selector = `.explain-${type}`;
- $(selector).toggleClass('visibility-hidden');
- },
-
- // This function will toggle "verbose" option in explain
- _explain_verbose: function() {
- this._toggle_explain_option('verbose');
- },
-
- // This function will toggle "costs" option in explain
- _explain_costs: function() {
- this._toggle_explain_option('costs');
- },
-
- // This function will toggle "buffers" option in explain
- _explain_buffers: function() {
- this._toggle_explain_option('buffers');
- },
-
- // This function will toggle "timing" option in explain
- _explain_timing: function() {
- this._toggle_explain_option('timing');
- },
-
- _explain_summary: function() {
- this._toggle_explain_option('summary');
- },
-
- _explain_settings: function() {
- this._toggle_explain_option('settings');
- },
-
- _show_query_tool: function() {
- var self = this;
- var open_new_tab = self.browser_preferences.new_browser_tab_open;
- if (open_new_tab && open_new_tab.includes('qt')) {
- is_main_window_alive();
- }
- this._open_query_tool(self);
- },
-
- _open_query_tool: function(that) {
-
- const transId = pgadminUtils.getRandomInt(1, 9999999);
-
- let url_endpoint = url_for('datagrid.panel', {
- 'trans_id': transId,
- });
-
- url_endpoint += `?is_query_tool=${true}`
- +`&sgid=${that.url_params.sgid}`
- +`&sid=${that.url_params.sid}`
- +`&server_type=${that.url_params.server_type}`;
-
- if(that.url_params.did) {
- url_endpoint += `&did=${that.url_params.did}`;
- }
-
- let panel_title = that.url_params.title;
- if(that.url_params.is_query_tool == 'false') {//check whether query tool is hit from View/Edit
- var split_title = that.url_params.title.split('/');
- if(split_title.length > 2) {
- panel_title = split_title[split_title.length-2] + '/' + split_title[split_title.length-1];
- }
- }
-
- launchDataGrid(pgWindow.default.pgAdmin.DataGrid, transId, url_endpoint, panel_title, '', alertify);
- },
-
- /*
- * This function will indent selected code
- */
- _indent_selected_code: function() {
- var self = this,
- editor = self.gridView.query_tool_obj;
- editor.execCommand('indentMore');
- },
-
- /*
- * This function will unindent selected code
- */
- _unindent_selected_code: function() {
- var self = this,
- editor = self.gridView.query_tool_obj;
- editor.execCommand('indentLess');
- },
-
- /*
- * This function will format the SQL
- */
- _format_sql: function() {
- var self = this,
- editor = self.gridView.query_tool_obj,
- selection = true,
- sql = '';
-
- sql = editor.getSelection();
-
- if (sql == '') {
- sql = editor.getValue();
- selection = false;
- }
-
- $.ajax({
- url: url_for('sql.format'),
- data: JSON.stringify({'sql': sql}),
- method: 'POST',
- contentType: 'application/json',
- dataType: 'json',
- })
- .done(function(res) {
- if (selection === true) {
- editor.replaceSelection(res.data.sql, 'around');
- } else {
- editor.setValue(res.data.sql);
- }
- })
- .fail(function() {
- /* failure should be ignored */
- });
- },
-
- // This function will open the manage macro dialog
- _manage_macros: function() {
- let self = this;
-
- /* When server is disconnected and connected, connection is lost,
- * To reconnect pass true
- */
- MacroHandler.dialog(self);
- },
-
- // This function will open the manage macro dialog
- _execute_macro: function() {
-
- queryToolActions.executeMacro(this.handler);
-
- },
-
-
- isQueryRunning: function() {
- return is_query_running;
- },
-
- setIsQueryRunning: function(value) {
- is_query_running = value;
- },
-
- /* Checks if there is any unsaved data changes, unsaved changes in the query
- or uncommitted transactions before closing a panel */
- check_needed_confirmations_before_closing_panel: function(is_close_event_call = false) {
- var self = this, msg;
-
- /*
- is_close_event_call = true only when the function is called when the
- close panel event is triggered, otherwise (on recursive calls) it is false
- */
- if(!self.ignore_on_close || is_close_event_call)
- self.ignore_on_close = {
- unsaved_data: false,
- unsaved_query: false,
- };
-
- var ignore_unsaved_data = self.ignore_on_close.unsaved_data,
- ignore_unsaved_query = self.ignore_on_close.unsaved_query;
-
- // If there is unsaved data changes in the grid
- if (!ignore_unsaved_data && self.can_edit
- && self.preferences.prompt_save_data_changes &&
- self.data_store &&
- (_.size(self.data_store.added) ||
- _.size(self.data_store.updated) ||
- _.size(self.data_store.deleted))) {
- msg = gettext('The data has changed. Do you want to save changes?');
- self.unsaved_changes_user_confirmation(msg, true);
- } // If there is unsaved query changes in the query editor
- else if (!ignore_unsaved_query && self.is_query_tool
- && self.is_query_changed
- && self.preferences.prompt_save_query_changes) {
- msg = gettext('The query text has changed. Do you want to save changes?');
- self.unsaved_changes_user_confirmation(msg, false);
- } // If a transaction is currently ongoing
- else if (self.preferences.prompt_commit_transaction
- && (self.last_transaction_status === queryTxnStatus.TRANSACTION_STATUS_INTRANS
- || self.last_transaction_status === queryTxnStatus.TRANSACTION_STATUS_INERROR)) {
- var is_commit_disabled = self.last_transaction_status == queryTxnStatus.TRANSACTION_STATUS_INERROR;
- self.uncommitted_transaction_user_confirmation(is_commit_disabled);
- }
- else {
- // No other function should call close() except through this function
- // in order to perform necessary checks
- self.ignore_on_close = undefined;
- self.close();
- }
- // Return false so that the panel does not close unless close()
- // is called explicitly (when all needed prompts are issued).
- return false;
- },
-
- /* To prompt the user for uncommitted transaction */
- uncommitted_transaction_user_confirmation: function(is_commit_disabled = false) {
- var self = this;
-
- alertify.confirmCommit || alertify.dialog('confirmCommit', function() {
- return {
- main: function(title, message, is_commit_disabled_arg) {
- this.is_commit_disabled = is_commit_disabled_arg;
- this.setHeader(title);
- this.setContent(message);
- },
- setup: function() {
- return {
- buttons: [{
- text: gettext('Cancel'),
- key: 27, // ESC
- invokeOnClose: true,
- className: 'btn btn-secondary fa fa-lg fa-times pg-alertify-button',
- }, {
- text: gettext('Rollback'),
- className: 'btn btn-primary fa fa-lg pg-alertify-button',
- }, {
- text: gettext('Commit'),
- className: 'btn btn-primary fa fa-lg pg-alertify-button',
- }],
- focus: {
- element: 0,
- select: false,
- },
- options: {
- maximizable: false,
- resizable: false,
- },
- };
- },
- prepare: function() {
- // Disable commit button if needed
- if(this.is_commit_disabled)
- this.__internal.buttons[2].element.disabled = true;
- else
- this.__internal.buttons[2].element.disabled = false;
- },
- callback: function(closeEvent) {
- switch (closeEvent.index) {
- case 0: // Cancel
- //Do nothing.
- break;
- case 1: // Rollback
- self.close_on_idle_transaction = true;
- queryToolActions.executeRollback(self);
- break;
- case 2: // Commit
- self.close_on_idle_transaction = true;
- queryToolActions.executeCommit(self);
- break;
- }
- },
- };
- });
-
- let msg = gettext('The current transaction is not commited to the database. '
- + 'Do you want to commit or rollback the transaction?');
-
- alertify.confirmCommit(gettext('Commit transaction?'), msg, is_commit_disabled);
- },
-
- /* To prompt user for unsaved changes */
- unsaved_changes_user_confirmation: function(msg, is_unsaved_data) {
- // If there is anything to save then prompt user
- var self = this;
-
- alertify.confirmSave || alertify.dialog('confirmSave', function() {
- return {
- main: function(title, message, is_unsaved_data_arg) {
- this.is_unsaved_data = is_unsaved_data_arg;
- this.setHeader(title);
- this.setContent(message);
- },
- setup: function() {
- return {
- buttons: [{
- text: gettext('Cancel'),
- key: 27, // ESC
- invokeOnClose: true,
- className: 'btn btn-secondary fa fa-lg fa-times pg-alertify-button',
- }, {
- text: gettext('Don\'t save'),
- className: 'btn btn-secondary fa fa-lg fa-trash-alt pg-alertify-button',
- }, {
- text: gettext('Save'),
- className: 'btn btn-primary fa fa-lg fa-save pg-alertify-button',
- }],
- focus: {
- element: 0,
- select: false,
- },
- options: {
- maximizable: false,
- resizable: false,
- },
- };
- },
- callback: function(closeEvent) {
- switch (closeEvent.index) {
- case 0: // Cancel
- //Do nothing.
- break;
- case 1: // Don't Save
- self.close_on_save = false;
- self.is_unsaved_data = this.is_unsaved_data;
- $.ajax({
- url: url_for('sqleditor._check_server_connection_status', {
- 'sid': self.url_params.sid,
- 'sgid': self.url_params.sgid,
- }),
- headers: {
- 'Cache-Control' : 'no-cache',
- },
- }).done(function (res) {
- let response = res.data.result.server;
- if (response) {
- closeEvent.cancel = true;
- if (self.is_unsaved_data)
- self.ignore_on_close.unsaved_data = true;
- else
- self.ignore_on_close.unsaved_query = true;
-
- // Go back to check for any other needed confirmations before closing
- if (!self.check_needed_confirmations_before_closing_panel()) {
- closeEvent.cancel = true;
- }
- } else {
- Notify.confirm(
- gettext('Warning'),
- gettext('The current transaction has been rolled back because the server was disconnected.'),
- function() {
- // Close the query tool if server is disconnected.
- setTimeout(() => { self.close(); }, 200);
- },
- function() {
- return true;
- },
- gettext('OK'),
- gettext('Cancel')
- );
- }
- }).fail(function() {
- /* failure should be ignored */
- });
- break;
- case 2: //Save
- self.close_on_save = true;
- if(this.is_unsaved_data) {
- self.save_data();
- }
- else {
- self._save_file();
- }
- break;
- }
- },
- };
- });
- alertify.confirmSave(gettext('Save changes?'), msg, is_unsaved_data);
- },
-
- close: function() {
- var self = this;
-
- pgBrowser.Events.off('pgadmin:user:logged-in', this.initTransaction);
- window.onbeforeunload = null;
- self.gridView.currentPanel.off(wcDocker.EVENT.CLOSING);
- // remove col_size object on panel close
- if (!_.isUndefined(self.col_size)) {
- delete self.col_size;
- }
- pgWindow.default.pgAdmin.Browser.docker.removePanel(self.gridView.currentPanel);
- },
- /* This function is used to raise notify messages and update
- * the notification grid.
- */
- update_notifications: function (notifications) {
- queryToolNotifications.updateNotifications(notifications);
- },
-
- /* This function is used to set editor title based on title
- * & db_name passed as parameters
- */
- set_title_and_render_connection: function(title, db_name) {
- var self = this;
- self.gridView.set_editor_title(_.unescape(title));
- self.gridView.handler.setTitle(_.unescape(title));
-
- self.gridView.connection_list.forEach(option =>{
- if(db_name == option['database_name']) {
- option.database_name = db_name;
- option.title = title;
- if('is_selected' in option && option['is_selected']) {
- self.gridView.$el.find('ul#connections-list li.selected-connection > a').text(title);
- }
- return true;
- }
- });
- },
-
- /* This function is used to check the synchronous db name change by users.
- * if changed, alert will be generated with message prompting user to
- * click OK for automatic db node refresh.
- */
- check_db_name_change: function(data) {
-
- var self = this;
-
- var selected_item = pgWindow.default.pgAdmin.Browser.tree.selected(),
- tree_data = pgWindow.default.pgAdmin.Browser.tree.translateTreeNodeIdFromReactTree(selected_item),
- server_data = pgWindow.default.pgAdmin.Browser.tree.findNode(tree_data[1]),
- database_data = pgWindow.default.pgAdmin.Browser.tree.findNode(tree_data[3]),
- db_name = database_data.data.label,
- db_did = database_data.data._id;
-
- if(data.data_obj.db_id == db_did && !_.isEqual(db_name, data.data_obj.db_name)) {
-
- var message = `Current database has been moved or renamed to ${data.data_obj.db_name}. Click on the OK button to refresh the database name.`,
- title = '';
-
- if(self.is_query_tool) {// for query tool
-
- var qt_title_placeholder = self.gridView.browser_preferences['qt_tab_title_placeholder'];
- var title_data = {
- 'database': data.data_obj.db_name,
- 'username': server_data.data.user.name,
- 'server': server_data.data.label,
- 'type': 'query_tool'
- };
- title = panelTitleFunc.generateTitle(qt_title_placeholder, title_data);
- }
- else { // for datagrid
- title = generateDatagridTitle(pgWindow.default.pgAdmin.Browser, selected_item, null, data.data_obj);
- }
-
- panelTitleFunc.refresh_db_node(message, database_data.domNode);
- self.set_title_and_render_connection(title, database_data.data.label);
- }
- },
- });
-
- pgAdmin.SqlEditor = {
- // This function is used to create and return the object of grid controller.
- create: function(container) {
- return new SqlEditorController(container);
- },
- jquery: $,
- };
-
- return pgAdmin.SqlEditor;
-});
diff --git a/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js b/web/pgadmin/tools/sqleditor/static/js/sqleditor_title.js
similarity index 58%
rename from web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js
rename to web/pgadmin/tools/sqleditor/static/js/sqleditor_title.js
index 7f5d6fbe2..93bd0d015 100644
--- a/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js
+++ b/web/pgadmin/tools/sqleditor/static/js/sqleditor_title.js
@@ -8,8 +8,9 @@
//////////////////////////////////////////////////////////////
import gettext from 'sources/gettext';
+import Alertify from 'pgadmin.alertifyjs';
import pgWindow from 'sources/window';
-import Notify from '../../../../static/js/helpers/Notifier';
+import { retrieveNameSpaceName, retrieveNodeName } from './show_view_data';
const pgAdmin = pgWindow.pgAdmin;
@@ -22,6 +23,25 @@ function isServerInformationAvailable(parentData) {
return parentData.server === undefined;
}
+export function getTitle(pgAdmin, browserPref, parentData=null, isConnTitle=false, server=null, database=null, username=null, isQueryTool=true) {
+ let titleTemplate = isQueryTool ? pgAdmin['qt_default_placeholder'] : pgAdmin['vw_edt_default_placeholder'];
+ if (!isConnTitle) {
+ if(!isQueryTool) {
+ titleTemplate = browserPref['vw_edt_tab_title_placeholder'] ?? pgAdmin['qt_default_placeholder'];
+ } else {
+ titleTemplate = browserPref['qt_tab_title_placeholder'] ?? pgAdmin['vw_edt_default_placeholder'];
+ }
+ }
+ return generateTitle(titleTemplate, {
+ 'database': database,
+ 'username': username,
+ 'server': server,
+ 'schema': retrieveNameSpaceName(parentData),
+ 'table': retrieveNodeName(parentData),
+ 'type': isQueryTool ? 'query_tool' : 'view_data',
+ });
+}
+
export function getPanelTitle(pgBrowser, selected_item=null, custom_title=null, parentData=null, conn_title=false, db_label=null) {
var preferences = pgBrowser.get_preferences_for_module('browser');
if(selected_item == null && parentData == null) {
@@ -57,6 +77,7 @@ export function getPanelTitle(pgBrowser, selected_item=null, custom_title=null,
'server': parentData.server.label,
'type': 'query_tool',
};
+
return generateTitle(qt_title_placeholder, title_data);
}
@@ -69,7 +90,7 @@ export function setQueryToolDockerTitle(panel, is_query_tool, panel_title, is_fi
panel_tooltip = gettext('File - ') + panel_title;
panel_icon = 'fa fa-file-alt';
}
- else if (is_query_tool == 'false' || is_query_tool == false) {
+ else if (is_query_tool == 'false' || !is_query_tool) {
// Edit grid titles
panel_tooltip = gettext('View/Edit Data - ') + panel_title;
panel_icon = 'pg-font-icon icon-view_data';
@@ -86,33 +107,29 @@ export function setQueryToolDockerTitle(panel, is_query_tool, panel_title, is_fi
export function set_renamable_option(panel, is_file) {
if(is_file || is_file == 'true') {
- panel.renamable(false);
+ panel?.renamable(false);
} else {
- panel.renamable(true);
+ panel?.renamable(true);
}
}
export function generateTitle(title_placeholder, title_data) {
- if(title_data.type == 'query_tool') {
- title_placeholder = title_placeholder.replace(new RegExp('%DATABASE%'), _.unescape(title_data.database));
- title_placeholder = title_placeholder.replace(new RegExp('%USERNAME%'), _.unescape(title_data.username));
- title_placeholder = title_placeholder.replace(new RegExp('%SERVER%'), _.unescape(title_data.server));
- } else if(title_data.type == 'datagrid') {
- title_placeholder = title_placeholder.replace(new RegExp('%DATABASE%'), _.unescape(title_data.database));
- title_placeholder = title_placeholder.replace(new RegExp('%USERNAME%'), _.unescape(title_data.username));
- title_placeholder = title_placeholder.replace(new RegExp('%SERVER%'), _.unescape(title_data.server));
- title_placeholder = title_placeholder.replace(new RegExp('%SCHEMA%'), _.unescape(title_data.schema));
- title_placeholder = title_placeholder.replace(new RegExp('%TABLE%'), _.unescape(title_data.table));
+ if(title_data.type == 'query_tool' || title_data.type == 'psql_tool') {
+ title_placeholder = title_placeholder.replace('%DATABASE%', _.unescape(title_data.database));
+ title_placeholder = title_placeholder.replace('%USERNAME%', _.unescape(title_data.username));
+ title_placeholder = title_placeholder.replace('%SERVER%', _.unescape(title_data.server));
+ } else if(title_data.type == 'view_data') {
+ title_placeholder = title_placeholder.replace('%DATABASE%', _.unescape(title_data.database));
+ title_placeholder = title_placeholder.replace('%USERNAME%', _.unescape(title_data.username));
+ title_placeholder = title_placeholder.replace('%SERVER%', _.unescape(title_data.server));
+ title_placeholder = title_placeholder.replace('%SCHEMA%', _.unescape(title_data.schema));
+ title_placeholder = title_placeholder.replace('%TABLE%', _.unescape(title_data.table));
} else if(title_data.type == 'debugger') {
- title_placeholder = title_placeholder.replace(new RegExp('%FUNCTION%'), _.unescape(title_data.function_name));
- title_placeholder = title_placeholder.replace(new RegExp('%ARGS%'), _.unescape(title_data.args));
- title_placeholder = title_placeholder.replace(new RegExp('%SCHEMA%'), _.unescape(title_data.schema));
- title_placeholder = title_placeholder.replace(new RegExp('%DATABASE%'), _.unescape(title_data.database));
- } else if(title_data.type == 'psql_tool') {
- title_placeholder = title_placeholder.replace(new RegExp('%DATABASE%'), _.unescape(title_data.database));
- title_placeholder = title_placeholder.replace(new RegExp('%USERNAME%'), _.unescape(title_data.username));
- title_placeholder = title_placeholder.replace(new RegExp('%SERVER%'), _.unescape(title_data.server));
+ title_placeholder = title_placeholder.replace('%FUNCTION%', _.unescape(title_data.function_name));
+ title_placeholder = title_placeholder.replace('%ARGS%', _.unescape(title_data.args));
+ title_placeholder = title_placeholder.replace('%SCHEMA%', _.unescape(title_data.schema));
+ title_placeholder = title_placeholder.replace('%DATABASE%', _.unescape(title_data.database));
}
return _.escape(title_placeholder);
@@ -122,7 +139,7 @@ export function generateTitle(title_placeholder, title_data) {
* This function is used refresh the db node after showing alert to the user
*/
export function refresh_db_node(message, dbNode) {
- Notify.alert()
+ Alertify.alert()
.setting({
'title': gettext('Database moved/renamed'),
'label':gettext('OK'),
diff --git a/web/pgadmin/tools/sqleditor/static/scss/_history.scss b/web/pgadmin/tools/sqleditor/static/scss/_history.scss
deleted file mode 100644
index fbb817824..000000000
--- a/web/pgadmin/tools/sqleditor/static/scss/_history.scss
+++ /dev/null
@@ -1,254 +0,0 @@
-.query-history {
- overflow: auto;
-
- .list-item {
- border-bottom: $panel-border;
- background-color: $color-bg;
- }
-
- .entry {
- font-family: $font-family-editor;
- border: $panel-border-width solid transparent;
- margin-left: 1px;
- padding: 0 5px;
-
- .other-info {
- @extend .text-12;
- color: $text-muted;
- font-family: $font-family-editor;
- display: flex;
- flex-direction: row;
- justify-content: space-between;
-
- .timestamp {
- align-self: flex-start;
- }
- }
-
- .query {
- text-overflow: ellipsis;
- overflow: hidden;
- white-space: nowrap;
- user-select: initial;
-
- .query-history-icon {
- width: 18px;
- text-align: center;
- }
- }
- }
-
- .date-label {
- font-family: $font-family-editor;
- background: $color-gray-lighter;
- padding: 2px 9px;
- font-size: 11px;
- font-weight: bold;
- color: $color-gray;
- border-bottom: $panel-border;
- }
-
- .entry.error {
- background: $sql-history-error-bg;
- }
-
- .selected {
- & .entry.error {
- background-color: $sql-history-error-bg;
- }
-
- & .entry {
- color: $sql-history-success-fg;
- border: $table-hover-border;
- background: $sql-history-success-bg;
- font-weight: bold;
-
- .other-info {
- color: $sql-history-success-fg;
- font-weight: bold;
- }
- }
- }
-}
-
-#history-detail-query .CodeMirror {
- border: $panel-border;
- background-color: $sql-history-detail-bg;
- width: 100%;
- padding-left: 5px;
- position: absolute;
-}
-
-.header-label {
- @extend .text-12;
- display: block;
- color: $color-fg;
-}
-
-
-.sql-editor-history-container {
- height: 100%;
- overflow: hidden;
- background-color: $negative-bg;
-}
-
-
-.query-detail {
- height: 100%;
- width: 100%;
- min-height: 19em;
- overflow: auto;
- display: flex;
- flex-direction: column;
- background-color: $color-bg;
- .error-message-block {
- background: $sql-history-error-bg;
- flex: 0.3;
- padding-left: 20px;
-
- .history-error-text {
- @extend .text-12;
- padding: 7px 0;
-
- span {
- color:$sql-history-error-fg;
- font-weight: 500;
- margin-right: 8px;
- }
- }
- }
-
- .info-message-block {
- background: $sql-history-detail-bg;
- flex: 0.3;
- padding-left: 20px;
-
- .history-info-text {
- @extend .text-12;
- padding: 7px 0;
- }
- }
-
- .metadata-block {
- flex: 0.4;
- padding: 10px 20px;
-
- .metadata {
- display: flex;
- flex-wrap: wrap;
-
- .item {
- flex: 1;
- min-width: 130px;
-
- .value {
- @extend .text-14;
- display: block;
- }
-
- .description {
- @extend .header-label;
- }
- }
-
- }
- }
-
- .query-statement-block {
- flex: 5;
- margin-left: 10px;
- margin-right: 10px;
- min-height: 4em;
- position: relative;
-
- .copy-all, .was-copied, .copy-to-editor {
- float: left;
- position: relative;
- z-index: 10;
- border: 1px solid $border-color;
- color: $color-fg;
- font-size: 12px;
- box-shadow: 1px 2px 4px 0px $color-gray-light;
- padding: 3px 12px 3px 10px;
- font-weight: 500;
- min-width: 75px;
- }
-
- .copy-all, .copy-to-editor {
- background-color: $color-bg;
- }
-
- .was-copied {
- background-color: $color-primary-light;
- border-color: $color-primary-light;
- color: $btn-copied-color-fg;
- }
-
- .CodeMirror-scroll {
- padding-top: 25px;
- }
- }
-
- .block-divider {
- margin-top: 11px;
- margin-bottom: 8px;
- }
-
- .message-block {
- flex: 2;
- display: flex;
- padding: 0 20px;
- min-height: 6em;
-
- .message {
- flex: 2 2 0%;
- flex-direction: column;
- display: flex;
-
- .message-header {
- @extend .header-label;
- @extend .not-selectable;
- flex: 0 0 auto;
- }
-
- .content {
- flex: 0 1 auto;
- overflow: auto;
- position: relative;
- height: 100%;
-
- .content-value {
- @extend .bg-white;
- @extend .text-13;
- font-family: $font-family-editor;
- color: $color-fg;
- border: 0;
- padding-left: 0;
- position: absolute;
- }
- }
- }
- }
-}
-
-#history_grid {
- .gutter.gutter-horizontal {
- width: $panel-border-width;
- background: $panel-border-color;
-
- &:hover {
- cursor: ew-resize;
- }
- }
-
- .toggle-and-history-container {
- display: flex;
- flex-direction: column;
- height: 100%;
-
- .query-history-toggle {
- padding-top: 4px;
- padding-bottom: 4px;
- }
- }
-}
diff --git a/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss b/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss
deleted file mode 100644
index ee5aabf8d..000000000
--- a/web/pgadmin/tools/sqleditor/static/scss/_sqleditor.scss
+++ /dev/null
@@ -1,431 +0,0 @@
-.filter-title {
- background-color: $color-primary;
- padding: 2px;
- color: $color-primary-fg;
- font-size: 13px;
-}
-
-.sql-icon-lg {
- font-size: 0.875rem;
- line-height: 1.3;
-}
-
-.sql_textarea {
- height: 100%;
-}
-
-.sql_textarea .CodeMirror-scroll {
- z-index: 0;
-}
-
-.data-output-container {
- position: absolute;
- top: 0;
- bottom: 0;
- right: 0;
- left: 0;
- overflow: hidden;
-}
-
-.sql-editor-busy-text-status {
- position: absolute;
- padding: 1rem 1.5rem;
- bottom: 0;
- right: 0;
- opacity: 0.8;
- background-color: $color-warning-light;
- color: $color-warning-fg;
-}
-
-.connection_status {
- background-color: $sql-title-bg;
- color: $sql-title-fg;
- border-right: $border-width solid $border-color;
-}
-
-.editor-title {
- padding: $sql-title-padding;
- background: $sql-title-bg;
- color: $sql-title-fg;
-}
-
-.connection-info {
- background: $sql-title-bg;
- color: $sql-title-fg;
- width:100%;
- display: inherit;
-}
-
-.conn-info-dd {
- padding-top: 0.3em;
- padding-left: 0.2em;
- cursor: pointer;
-}
-
-.connection-data {
- display: inherit;
- cursor: pointer;
- width: auto;
-}
-
-
-#editor-panel {
- z-index: 0;
- position: absolute;
- top: $sql-editor-panel-top;
- bottom: 0;
- left: 0;
- right: 0;
-}
-
-
-.ajs-body .warn-icon {
- color: $color-warning;
- font-size: 2em;
- margin-right: 20px;
- padding-top: 10px;
-}
-
-.connection_status_wrapper {
- width: 100%;
- border-top: $panel-border;
- border-bottom: $panel-border;
-}
-
-li.CodeMirror-hint-active {
- background: $color-primary-light;
- color: $color-primary-fg;
-}
-
-.sql-editor .CodeMirror-activeline-background {
- background: $color-editor-activeline-light !important;
- border: 1px solid $color-editor-activeline-border-color;
-}
-
-.filter-container {
- position: relative;
- background-color: $color-bg;
- border: 1px solid $border-color;
- padding-bottom: 30px;
- top: 10px;
- z-index: 1;
- margin: auto;
- width: 60%;
-}
-
-.limit-enabled {
- background-color: $color-bg;
-}
-
-
-
-.CodeMirror-hint {
- margin: 0;
- padding: 0 4px;
- border-radius: 2px;
- overflow: hidden;
- white-space: pre;
- color: $color-fg;
- cursor: pointer;
-}
-
-.grid-header .ui-icon.ui-state-hover {
- background-color: $color-bg;
-}
-
-.slick-cell.selected span[data-cell-type="row-header-selector"] {
- color: $color-primary-fg;
-}
-
-.slick-cell.cell-move-handle {
- font-weight: bold;
- text-align: right;
- border-right: solid $border-color;
- background: $color-gray-lighter;
- cursor: move;
-}
-
-.cell-move-handle:hover {
- background: $color-gray-light;
-}
-
-.slick-row.selected .cell-move-handle {
- background: $color-warning-light;
-}
-
-.slick-row.complete {
- background-color: $color-success-light;
- color: $color-gray-dark;
-}
-
-.cell-selection {
- border-right-color: $border-color;
- border-right-style: solid;
- background: $color-gray-lighter;
- color: $color-gray;
- text-align: right;
- font-size: 10px;
-}
-
-#datagrid .slick-header .slick-header-columns {
- background: $sql-grid-title-cell-bg;
- color: $sql-grid-title-cell-fg;
- height: 40px;
- border-bottom: $panel-border;
-}
-
-#datagrid .slick-header .slick-header-column.ui-state-default {
- padding: 4px 0 3px 6px;
- border-bottom: $panel-border;
- border-right: $panel-border;
-}
-
-.slick-row:hover .slick-cell{
- border-top: $table-hover-border;
- border-bottom: $table-hover-border;
- background-color: $table-hover-bg-color;
-}
-
-#datagrid .slick-header .slick-header-column.selected {
- background-color: $color-primary;
-}
-.slick-row .slick-cell {
- border-bottom: $panel-border;
- border-right: $panel-border;
- z-index: 0;
-}
-
-#datagrid {
- background: none;
- background-color: $datagrid-bg;
-}
-
-.ui-widget-content.slick-row {
- &.even, &.odd {
- background: none;
- background-color: $table-bg;
- }
-}
-
-/* Remove active cell border */
-.slick-cell.active {
- border: 1px solid transparent;
- border-right: 1px solid $color-gray-light;
- border-bottom-color: $color-gray-light;
-}
-
-/* To highlight all newly inserted rows */
-.grid-canvas .new_row {
- background: $color-success-light !important;
-}
-
-/* To highlight all the updated rows */
-.grid-canvas .updated_row {
- background: $color-gray-lighter;
-}
-
-/* To highlight row at fault */
-.grid-canvas .new_row.error, .grid-canvas .updated_row.error {
- background: $color-danger-light !important;
-}
-
-/* Disabled row */
-.grid-canvas .disabled_row {
- background: $color-gray-lighter;
-}
-
-/* Disabled cell */
-.grid-canvas .disabled_cell {
- color: $text-muted;
-}
-
-/* Highlighted (modified or new) cell */
-.grid-canvas .highlighted_grid_cells {
- background: $color-gray-lighter;
- font-weight: bold;
-}
-
-
-/* Override selected row color */
-#datagrid .slick-row .slick-cell.selected {
- background-color: $table-bg-selected;
- color: $datagrid-selected-color;
-}
-
-/* color the first column */
-
-#datagrid .slick-row {
- .slick-cell {
- background-color: $sql-grid-data-cell-bg;
- color: $sql-grid-data-cell-fg;
- }
-
- .slick-cell.l0.r0 {
- background-color: $sql-grid-title-cell-bg;
- color: $sql-grid-title-cell-fg;
- }
-}
-
-#datagrid div.slick-header.ui-state-default {
- background-color: $sql-grid-title-cell-bg;
- color: $sql-grid-title-cell-fg;
- border-bottom: none;
- border-right: none;
- border-top: none;
-}
-
-#datagrid .slick-row .slick-cell.l0.r0.selected {
- background-color: $color-primary;
- color: $color-primary-fg;
-}
-
-#datagrid .slick-row > .slick-cell:not(.l0):not(.r0).selected {
- background-color: $table-hover-bg-color;
- border-top: $table-hover-border;
- border-bottom: $table-hover-border;
-}
-
-.pg-text-editor {
- z-index:10000;
- position:absolute;
- background: $color-bg;
- padding: 0.25rem;
- border: $panel-border;
- box-shadow: $dropdown-box-shadow;
-
-
- & .pg-textarea {
- width:250px;
- height:80px;
- border:0;
- outline:0;
- resize: both;
- }
-
- & .pg-text-invalid {
- background: $color-danger-lighter;
- }
-
- & #pg-json-editor {
- min-width:525px;
- min-height:300px;
- height:295px;
- width:550px;
- border: $panel-border;
- outline:0;
- resize: both;
- overflow:auto
- }
-}
-
-.pg_buttons {
- padding-top: 3px;
-}
-.sql-editor-message {
- white-space:pre-wrap;
- font-family: $font-family-editor;
- padding-top: 5px;
- padding-left: 10px;
- overflow: auto;
- height: 100%;
- font-size: 0.925em;
- -webkit-user-select: text;
- -moz-user-select: text;
- -ms-user-select: text;
- user-select: text;
-}
-
-.view-geometry-property-table .td-disabled{
- color: $color-gray-lighter;
-}
-
-/* For leaflet map background */
-.geometry-viewer-container-plain-background {
- background: $color-bg;
-}
-
-
-div.strikeout:before {
- content: " ";
- position: absolute;
- top: 50%;
- left: 0;
- border-top: 1px solid $color-danger;
- width: 100%;
- font-weight: 900;
-}
-
-div.strikeout:after {
- content: "\00B7";
- font-size: 1px;
- font-weight: 900;
-}
-
-.sql-scratch {
- width: 100%;
- height: 100%;
- box-sizing: border-box;
- overflow-y: hidden;
-
- textarea {
- width: 100%;
- height: 100%;
- box-sizing: border-box;
- border: none;
- resize: none;
- }
-}
-
-.connection_status .obtaining-conn {
- background-image: $loader-icon-small !important;
- background-position: center center;
- background-repeat: no-repeat;
- &:before {
- content:'';
- }
- min-width: 50%;
- min-height: 100%;
-}
-
-.sql-editor-grid-container {
- height: 100%;
- overflow: auto;
-
- .ui-widget-content {
- background-color: $input-bg;
- color: $input-color;
- }
-
- .ui-state-default {
- color: $color-fg;
- }
-}
-
-.sql-editor-grid-container.has-no-footer {
- height: 100%;
-}
-
-.selected-connection {
- background-color: $color-primary-light;
-}
-
-/* Setting it to hardcoded white as the SVG generated is having white bg
- * Need to check what can be done.
- */
-
-/* Css for psql */
-.psql_terminal .terminal {
- padding-top: 1%;
- padding-left: 0.5%;
- height: 100%;
-}
-
-.psql-icon-style {
- font-size: inherit;
- padding-left: 0em;
-}
-
-.psql-tab-style {
- font-size: small;
- padding-left: 0em;
-}
diff --git a/web/pgadmin/tools/datagrid/templates/datagrid/filter.html b/web/pgadmin/tools/sqleditor/templates/sqleditor/filter.html
similarity index 100%
rename from web/pgadmin/tools/datagrid/templates/datagrid/filter.html
rename to web/pgadmin/tools/sqleditor/templates/sqleditor/filter.html
diff --git a/web/pgadmin/tools/sqleditor/templates/sqleditor/index.html b/web/pgadmin/tools/sqleditor/templates/sqleditor/index.html
new file mode 100644
index 000000000..bcb6a04ea
--- /dev/null
+++ b/web/pgadmin/tools/sqleditor/templates/sqleditor/index.html
@@ -0,0 +1,70 @@
+{% extends "base.html" %}
+{% block title %}{{title}}{% endblock %}
+
+{% block css_link %}
+
+{% endblock %}
+{% block body %}
+
+
+{% endblock %}
+{% block init_script %}
+ try {
+ require(
+ ['sources/generated/browser_nodes', 'sources/generated/codemirror'],
+ function() {
+ require(['sources/generated/sqleditor'], function(module) {
+ window.pgAdmin.Tools.SQLEditor.loadComponent(
+ document.getElementById('sqleditor-container'), {{ params|safe }});
+
+ if(window.opener) {
+ $(window).on('unload', function(ev) {
+ $.ajax({
+ method: 'DELETE',
+ url: '{{close_url}}'
+ });
+ });
+ } else {
+ $(window).on('beforeunload', function(ev) {
+ $.ajax({
+ method: 'DELETE',
+ url: '{{close_url}}'
+ });
+ });
+ }
+ }, function() {
+ console.log(arguments);
+ });
+ },
+ function() {
+ console.log(arguments);
+ });
+ } catch (err) {
+ console.log(err);
+ }
+{% endblock %}
diff --git a/web/pgadmin/tools/sqleditor/tests/test_download_csv_query_tool.py b/web/pgadmin/tools/sqleditor/tests/test_download_csv_query_tool.py
index f609193ce..bae8fb7e2 100644
--- a/web/pgadmin/tools/sqleditor/tests/test_download_csv_query_tool.py
+++ b/web/pgadmin/tools/sqleditor/tests/test_download_csv_query_tool.py
@@ -27,7 +27,7 @@ class TestDownloadCSV(BaseTestGenerator):
'Download csv URL with valid query',
dict(
sql='SELECT 1 as "A",2 as "B",3 as "C"',
- init_url='/datagrid/initialize/query_tool/{0}/{1}/{2}/{3}',
+ init_url='/sqleditor/initialize/sqleditor/{0}/{1}/{2}/{3}',
donwload_url="/sqleditor/query_tool/download/{0}",
output_columns='"A","B","C"',
output_values='1,2,3',
@@ -41,7 +41,7 @@ class TestDownloadCSV(BaseTestGenerator):
'Download csv URL with wrong TX id',
dict(
sql='SELECT 1 as "A",2 as "B",3 as "C"',
- init_url='/datagrid/initialize/query_tool/{0}/{1}/{2}/{3}',
+ init_url='/sqleditor/initialize/sqleditor/{0}/{1}/{2}/{3}',
donwload_url="/sqleditor/query_tool/download/{0}",
output_columns=None,
output_values=None,
@@ -55,7 +55,7 @@ class TestDownloadCSV(BaseTestGenerator):
'Download csv URL with wrong query',
dict(
sql='SELECT * FROM this_table_does_not_exist',
- init_url='/datagrid/initialize/query_tool/{0}/{1}/{2}/{3}',
+ init_url='/sqleditor/initialize/sqleditor/{0}/{1}/{2}/{3}',
donwload_url="/sqleditor/query_tool/download/{0}",
output_columns=None,
output_values=None,
@@ -69,7 +69,7 @@ class TestDownloadCSV(BaseTestGenerator):
'Download as txt without filename parameter',
dict(
sql='SELECT 1 as "A",2 as "B",3 as "C"',
- init_url='/datagrid/initialize/query_tool/{0}/{1}/{2}/{3}',
+ init_url='/sqleditor/initialize/sqleditor/{0}/{1}/{2}/{3}',
donwload_url="/sqleditor/query_tool/download/{0}",
output_columns='"A";"B";"C"',
output_values='1;2;3',
@@ -83,7 +83,7 @@ class TestDownloadCSV(BaseTestGenerator):
'Download as csv without filename parameter',
dict(
sql='SELECT 1 as "A",2 as "B",3 as "C"',
- init_url='/datagrid/initialize/query_tool/{0}/{1}/{2}/{3}',
+ init_url='/sqleditor/initialize/sqleditor/{0}/{1}/{2}/{3}',
donwload_url="/sqleditor/query_tool/download/{0}",
output_columns='"A","B","C"',
output_values='1,2,3',
@@ -211,7 +211,7 @@ class TestDownloadCSV(BaseTestGenerator):
self.assertEqual(response.status_code, 500)
# Close query tool
- url = '/datagrid/close/{0}'.format(self.trans_id)
+ url = '/sqleditor/close/{0}'.format(self.trans_id)
response = self.tester.delete(url)
self.assertEqual(response.status_code, 200)
diff --git a/web/pgadmin/tools/sqleditor/tests/test_editor_history.py b/web/pgadmin/tools/sqleditor/tests/test_editor_history.py
index 86b5d935b..c7dcbdad0 100644
--- a/web/pgadmin/tools/sqleditor/tests/test_editor_history.py
+++ b/web/pgadmin/tools/sqleditor/tests/test_editor_history.py
@@ -70,7 +70,7 @@ class TestEditorHistory(BaseTestGenerator):
# Initialize query tool
self.trans_id = str(random.randint(1, 9999999))
- url = '/datagrid/initialize/query_tool/{0}/{1}/{2}/{3}'.format(
+ url = '/sqleditor/initialize/sqleditor/{0}/{1}/{2}/{3}'.format(
self.trans_id, utils.SERVER_GROUP, self.server_id, self.db_id)
response = self.tester.post(url)
self.assertEqual(response.status_code, 200)
@@ -101,7 +101,7 @@ class TestEditorHistory(BaseTestGenerator):
def tearDown(self):
# Close query tool
- url = '/datagrid/close/{0}'.format(self.trans_id)
+ url = '/sqleditor/close/{0}'.format(self.trans_id)
response = self.tester.delete(url)
self.assertEqual(response.status_code, 200)
diff --git a/web/pgadmin/tools/sqleditor/tests/test_encoding_charset.py b/web/pgadmin/tools/sqleditor/tests/test_encoding_charset.py
index 99ec32a49..653ddac10 100644
--- a/web/pgadmin/tools/sqleditor/tests/test_encoding_charset.py
+++ b/web/pgadmin/tools/sqleditor/tests/test_encoding_charset.py
@@ -262,7 +262,7 @@ class TestEncodingCharset(BaseTestGenerator):
# Initialize query tool
self.trans_id = str(random.randint(1, 9999999))
- url = '/datagrid/initialize/query_tool/{0}/{1}/{2}/{3}'\
+ url = '/sqleditor/initialize/sqleditor/{0}/{1}/{2}/{3}'\
.format(self.trans_id, test_utils.SERVER_GROUP, self.encode_sid,
self.encode_did)
response = self.tester.post(url)
@@ -283,7 +283,7 @@ class TestEncodingCharset(BaseTestGenerator):
self.assertEqual(result, self.test_str)
# Close query tool
- url = '/datagrid/close/{0}'.format(self.trans_id)
+ url = '/sqleditor/close/{0}'.format(self.trans_id)
response = self.tester.delete(url)
self.assertEqual(response.status_code, 200)
diff --git a/web/pgadmin/tools/sqleditor/tests/test_explain_plan.py b/web/pgadmin/tools/sqleditor/tests/test_explain_plan.py
index 734125399..e2bfc259a 100644
--- a/web/pgadmin/tools/sqleditor/tests/test_explain_plan.py
+++ b/web/pgadmin/tools/sqleditor/tests/test_explain_plan.py
@@ -34,7 +34,7 @@ class TestExplainPlan(BaseTestGenerator):
# Initialize query tool
self.trans_id = str(random.randint(1, 9999999))
- url = '/datagrid/initialize/query_tool/{0}/{1}/{2}/{3}'.format(
+ url = '/sqleditor/initialize/sqleditor/{0}/{1}/{2}/{3}'.format(
self.trans_id, utils.SERVER_GROUP, self.server_id, self.db_id)
response = self.tester.post(url)
self.assertEqual(response.status_code, 200)
@@ -68,7 +68,7 @@ class TestExplainPlan(BaseTestGenerator):
self.assertEqual(len(response_data['data']['result'][0]), 1)
# Close query tool
- url = '/datagrid/close/{0}'.format(self.trans_id)
+ url = '/sqleditor/close/{0}'.format(self.trans_id)
response = self.tester.delete(url)
self.assertEqual(response.status_code, 200)
diff --git a/web/pgadmin/tools/sqleditor/tests/test_macros.py b/web/pgadmin/tools/sqleditor/tests/test_macros.py
index b66678668..95e41ccb8 100644
--- a/web/pgadmin/tools/sqleditor/tests/test_macros.py
+++ b/web/pgadmin/tools/sqleditor/tests/test_macros.py
@@ -106,7 +106,7 @@ class TestMacros(BaseTestGenerator):
# Initialize query tool
self.trans_id = str(random.randint(1, 9999999))
- url = '/datagrid/initialize/query_tool/{0}/{1}/{2}/{3}'.format(
+ url = '/sqleditor/initialize/sqleditor/{0}/{1}/{2}/{3}'.format(
self.trans_id, utils.SERVER_GROUP, self.server_id, self.db_id)
response = self.tester.post(url)
self.assertEqual(response.status_code, 200)
@@ -150,7 +150,7 @@ class TestMacros(BaseTestGenerator):
def tearDown(self):
# Close query tool
- url = '/datagrid/close/{0}'.format(self.trans_id)
+ url = '/sqleditor/close/{0}'.format(self.trans_id)
response = self.tester.delete(url)
self.assertEqual(response.status_code, 200)
diff --git a/web/pgadmin/tools/sqleditor/tests/test_poll_query_tool.py b/web/pgadmin/tools/sqleditor/tests/test_poll_query_tool.py
index 920839e56..d35a2bb73 100644
--- a/web/pgadmin/tools/sqleditor/tests/test_poll_query_tool.py
+++ b/web/pgadmin/tools/sqleditor/tests/test_poll_query_tool.py
@@ -77,7 +77,7 @@ NOTICE: Hello, world!
# Initialize query tool
self.trans_id = str(random.randint(1, 9999999))
- url = '/datagrid/initialize/query_tool/{0}/{1}/{2}/{3}'.format(
+ url = '/sqleditor/initialize/sqleditor/{0}/{1}/{2}/{3}'.format(
self.trans_id, utils.SERVER_GROUP, self.server_id, self.db_id)
response = self.tester.post(url)
self.assertEqual(response.status_code, 200)
@@ -110,7 +110,7 @@ NOTICE: Hello, world!
cnt += 1
# Close query tool
- url = '/datagrid/close/{0}'.format(self.trans_id)
+ url = '/sqleditor/close/{0}'.format(self.trans_id)
response = self.tester.delete(url)
self.assertEqual(response.status_code, 200)
diff --git a/web/pgadmin/tools/sqleditor/tests/test_transaction_status.py b/web/pgadmin/tools/sqleditor/tests/test_transaction_status.py
index 5fbe83734..353820bf0 100644
--- a/web/pgadmin/tools/sqleditor/tests/test_transaction_status.py
+++ b/web/pgadmin/tools/sqleditor/tests/test_transaction_status.py
@@ -304,7 +304,7 @@ class TestTransactionControl(BaseTestGenerator):
def _initialize_query_tool(self):
self.trans_id = str(random.randint(1, 9999999))
- url = '/datagrid/initialize/query_tool/{0}/{1}/{2}/{3}'.format(
+ url = '/sqleditor/initialize/sqleditor/{0}/{1}/{2}/{3}'.format(
self.trans_id, utils.SERVER_GROUP, self.server_id, self.db_id)
response = self.tester.post(url)
self.assertEqual(response.status_code, 200)
@@ -339,6 +339,6 @@ class TestTransactionControl(BaseTestGenerator):
utils.create_table_with_query(self.server, self.db_name, create_sql)
def _close_query_tool(self):
- url = '/datagrid/close/{0}'.format(self.trans_id)
+ url = '/sqleditor/close/{0}'.format(self.trans_id)
response = self.tester.delete(url)
self.assertEqual(response.status_code, 200)
diff --git a/web/pgadmin/tools/sqleditor/tests/test_view_data.py b/web/pgadmin/tools/sqleditor/tests/test_view_data.py
index b87b3604a..5ad75d28f 100644
--- a/web/pgadmin/tools/sqleditor/tests/test_view_data.py
+++ b/web/pgadmin/tools/sqleditor/tests/test_view_data.py
@@ -97,7 +97,7 @@ class TestViewData(BaseTestGenerator):
# Initialize query tool
self.trans_id = str(random.randint(1, 9999999))
- url = '/datagrid/initialize/datagrid/{0}/3/table/{1}/{2}/{3}/{4}' \
+ url = '/sqleditor/initialize/viewdata/{0}/3/table/{1}/{2}/{3}/{4}' \
.format(self.trans_id, test_utils.SERVER_GROUP, self.server_id,
self.db_id, table_id)
diff --git a/web/pgadmin/tools/sqleditor/utils/macros.py b/web/pgadmin/tools/sqleditor/utils/macros.py
index bdf3ec9bd..7e2f8731e 100644
--- a/web/pgadmin/tools/sqleditor/utils/macros.py
+++ b/web/pgadmin/tools/sqleditor/utils/macros.py
@@ -76,7 +76,8 @@ def get_user_macros():
macros = db.session.query(UserMacros.name,
Macros.id,
Macros.alt, Macros.control,
- Macros.key, Macros.key_code
+ Macros.key, Macros.key_code,
+ UserMacros.sql
).outerjoin(
Macros, UserMacros.mid == Macros.id).filter(
UserMacros.uid == current_user.id).order_by(UserMacros.name).all()
@@ -87,7 +88,8 @@ def get_user_macros():
key_label = 'Ctrl + ' + m[4] if m[3] is True else 'Alt + ' + m[4]
data.append({'name': m[0], 'id': m[1], 'key': m[4],
'key_label': key_label, 'alt': 1 if m[2] else 0,
- 'control': 1 if m[3] else 0, 'key_code': m[5]})
+ 'control': 1 if m[3] else 0, 'key_code': m[5],
+ 'sql': m[6]})
return data
@@ -121,7 +123,8 @@ def set_macros():
return make_json_response(
status=410, success=0, errormsg=msg
)
- return ajax_response(status=200)
+
+ return get_macros(None, True)
def create_macro(macro):
diff --git a/web/pgadmin/tools/sqleditor/utils/query_history.py b/web/pgadmin/tools/sqleditor/utils/query_history.py
index cf5e5f0b5..47e35e79a 100644
--- a/web/pgadmin/tools/sqleditor/utils/query_history.py
+++ b/web/pgadmin/tools/sqleditor/utils/query_history.py
@@ -1,6 +1,7 @@
from pgadmin.utils.ajax import make_json_response
from pgadmin.model import db, QueryHistoryModel
from config import MAX_QUERY_HIST_STORED
+import json
class QueryHistory:
@@ -107,30 +108,34 @@ class QueryHistory:
)
@staticmethod
- def clear_history(uid, sid, dbname=None):
+ def clear_history(uid, sid, dbname=None, filter=None):
try:
+ filters = [
+ QueryHistoryModel.uid == uid,
+ QueryHistoryModel.sid == sid
+ ]
if dbname is not None:
- db.session.query(QueryHistoryModel) \
- .filter(QueryHistoryModel.uid == uid,
- QueryHistoryModel.sid == sid,
- QueryHistoryModel.dbname == dbname) \
- .delete()
-
- db.session.commit()
+ filters.append(QueryHistoryModel.dbname == dbname)
+
+ history = db.session.query(QueryHistoryModel) \
+ .filter(*filters)
+ if filter is not None:
+ for row in history:
+ query_info = json.loads(row.query_info.decode())
+ if query_info['query'] == filter['query'] and \
+ query_info['start_time'] == filter['start_time']:
+ db.session.delete(row)
else:
- db.session.query(QueryHistoryModel) \
- .filter(QueryHistoryModel.uid == uid,
- QueryHistoryModel.sid == sid)\
- .delete()
+ history.delete()
- db.session.commit()
+ db.session.commit()
except Exception:
db.session.rollback()
# do not affect query execution if history clear fails
@staticmethod
- def clear(uid, sid, dbname=None):
- QueryHistory.clear_history(uid, sid, dbname)
+ def clear(uid, sid, dbname=None, filter=None):
+ QueryHistory.clear_history(uid, sid, dbname, filter)
return make_json_response(
data={
'status': True,
diff --git a/web/pgadmin/tools/sqleditor/utils/query_tool_preferences.py b/web/pgadmin/tools/sqleditor/utils/query_tool_preferences.py
index b18145e0f..ace48392f 100644
--- a/web/pgadmin/tools/sqleditor/utils/query_tool_preferences.py
+++ b/web/pgadmin/tools/sqleditor/utils/query_tool_preferences.py
@@ -18,22 +18,6 @@ from pgadmin.utils import SHORTCUT_FIELDS as shortcut_fields, \
def register_query_tool_preferences(self):
-
- self.info_notifier_timeout = self.preference.register(
- 'display', 'info_notifier_timeout',
- gettext("Query info notifier timeout"), 'integer', 5,
- category_label=PREF_LABEL_DISPLAY,
- min_val=-1,
- max_val=999999,
- help_str=gettext(
- 'The length of time to display the query info notifier after '
- 'execution has completed. A value of -1 disables the notifier'
- ' and a value of 0 displays it until clicked. Values greater'
- ' than 0 display the notifier for the number of seconds'
- ' specified.'
- )
- )
-
self.explain_verbose = self.preference.register(
'Explain', 'explain_verbose',
gettext("Verbose output?"), 'boolean', False,
@@ -128,7 +112,7 @@ def register_query_tool_preferences(self):
)
)
- self.show_prompt_commit_transaction = self.preference.register(
+ self.copy_sql_to_query_tool = self.preference.register(
'Options', 'copy_sql_to_query_tool',
gettext("Copy SQL from main window to query tool?"), 'boolean',
False,
@@ -411,6 +395,24 @@ def register_query_tool_preferences(self):
fields=shortcut_fields
)
+ self.preference.register(
+ 'keyboard_shortcuts',
+ 'clear_query',
+ gettext('Clear query'),
+ 'keyboardshortcut',
+ {
+ 'alt': True,
+ 'shift': False,
+ 'control': True,
+ 'key': {
+ 'key_code': 76,
+ 'char': 'L'
+ }
+ },
+ category_label=PREF_LABEL_KEYBOARD_SHORTCUTS,
+ fields=shortcut_fields
+ )
+
self.preference.register(
'keyboard_shortcuts',
'download_results',
@@ -614,19 +616,6 @@ def register_query_tool_preferences(self):
fields=accesskey_fields
)
- self.preference.register(
- 'keyboard_shortcuts', 'btn_clear_options',
- gettext('Accesskey (Clear editor options)'), 'keyboardshortcut',
- {
- 'key': {
- 'key_code': 76,
- 'char': 'l'
- }
- },
- category_label=PREF_LABEL_KEYBOARD_SHORTCUTS,
- fields=accesskey_fields
- )
-
self.preference.register(
'keyboard_shortcuts', 'btn_conn_status',
gettext('Accesskey (Connection status)'), 'keyboardshortcut',
diff --git a/web/pgadmin/tools/sqleditor/utils/start_running_query.py b/web/pgadmin/tools/sqleditor/utils/start_running_query.py
index 876c1e8d5..b2a001236 100644
--- a/web/pgadmin/tools/sqleditor/utils/start_running_query.py
+++ b/web/pgadmin/tools/sqleditor/utils/start_running_query.py
@@ -107,8 +107,6 @@ class StartRunningQuery:
data={
'status': status, 'result': result,
'can_edit': can_edit, 'can_filter': can_filter,
- 'info_notifier_timeout':
- self.blueprint_object.info_notifier_timeout.get() * 1000,
'notifies': notifies,
'transaction_status': trans_status,
}
diff --git a/web/pgadmin/tools/sqleditor/utils/tests/test_is_query_resultset_updatable.py b/web/pgadmin/tools/sqleditor/utils/tests/test_is_query_resultset_updatable.py
index c6840df63..9839472ec 100644
--- a/web/pgadmin/tools/sqleditor/utils/tests/test_is_query_resultset_updatable.py
+++ b/web/pgadmin/tools/sqleditor/utils/tests/test_is_query_resultset_updatable.py
@@ -203,7 +203,7 @@ class TestQueryUpdatableResultset(BaseTestGenerator):
def _initialize_query_tool(self):
self.trans_id = str(random.randint(1, 9999999))
- url = '/datagrid/initialize/query_tool/{0}/{1}/{2}/{3}'.format(
+ url = '/sqleditor/initialize/sqleditor/{0}/{1}/{2}/{3}'.format(
self.trans_id, utils.SERVER_GROUP, self.server_id, self.db_id)
response = self.tester.post(url)
self.assertEqual(response.status_code, 200)
@@ -235,7 +235,7 @@ class TestQueryUpdatableResultset(BaseTestGenerator):
utils.create_table_with_query(self.server, self.db_name, create_sql)
def _close_query_tool(self):
- url = '/datagrid/close/{0}'.format(self.trans_id)
+ url = '/sqleditor/close/{0}'.format(self.trans_id)
response = self.tester.delete(url)
self.assertEqual(response.status_code, 200)
diff --git a/web/pgadmin/tools/sqleditor/utils/tests/test_save_changed_data.py b/web/pgadmin/tools/sqleditor/utils/tests/test_save_changed_data.py
index 0bef9b947..1b888d285 100644
--- a/web/pgadmin/tools/sqleditor/utils/tests/test_save_changed_data.py
+++ b/web/pgadmin/tools/sqleditor/utils/tests/test_save_changed_data.py
@@ -921,7 +921,7 @@ class TestSaveChangedData(BaseTestGenerator):
def _initialize_query_tool(self):
self.trans_id = str(random.randint(1, 9999999))
- url = '/datagrid/initialize/query_tool/{0}/{1}/{2}/{3}'.format(
+ url = '/sqleditor/initialize/sqleditor/{0}/{1}/{2}/{3}'.format(
self.trans_id, utils.SERVER_GROUP, self.server_id, self.db_id)
response = self.tester.post(url)
self.assertEqual(response.status_code, 200)
@@ -955,6 +955,6 @@ class TestSaveChangedData(BaseTestGenerator):
utils.create_table_with_query(self.server, self.db_name, create_sql)
def _close_query_tool(self):
- url = '/datagrid/close/{0}'.format(self.trans_id)
+ url = '/sqleditor/close/{0}'.format(self.trans_id)
response = self.tester.delete(url)
self.assertEqual(response.status_code, 200)
diff --git a/web/pgadmin/tools/sqleditor/utils/tests/test_start_running_query.py b/web/pgadmin/tools/sqleditor/utils/tests/test_start_running_query.py
index 9c8e0e470..c884f3f10 100644
--- a/web/pgadmin/tools/sqleditor/utils/tests/test_start_running_query.py
+++ b/web/pgadmin/tools/sqleditor/utils/tests/test_start_running_query.py
@@ -112,7 +112,6 @@ class StartRunningQueryTest(BaseTestGenerator):
'not found.',
can_edit=False,
can_filter=False,
- info_notifier_timeout=5000,
notifies=None,
transaction_status=None
)
@@ -273,7 +272,6 @@ class StartRunningQueryTest(BaseTestGenerator):
result='async function result output',
can_edit=True,
can_filter=True,
- info_notifier_timeout=5000,
notifies=None,
transaction_status=None
)
@@ -318,7 +316,6 @@ class StartRunningQueryTest(BaseTestGenerator):
result='async function result output',
can_edit=True,
can_filter=True,
- info_notifier_timeout=5000,
notifies=None,
transaction_status=None
)
@@ -363,7 +360,6 @@ class StartRunningQueryTest(BaseTestGenerator):
result='async function result output',
can_edit=True,
can_filter=True,
- info_notifier_timeout=5000,
notifies=None,
transaction_status=None
)
@@ -409,7 +405,6 @@ class StartRunningQueryTest(BaseTestGenerator):
result='async function result output',
can_edit=True,
can_filter=True,
- info_notifier_timeout=5000,
notifies=None,
transaction_status=None
)
@@ -444,8 +439,7 @@ class StartRunningQueryTest(BaseTestGenerator):
if self.expect_internal_server_error_called_with is not None:
internal_server_error_mock.return_value = expected_response
pickle_mock.loads.return_value = self.pickle_load_return
- blueprint_mock = MagicMock(
- info_notifier_timeout=MagicMock(get=lambda: 5))
+ blueprint_mock = MagicMock()
# Save value for the later use
self.is_begin_required_for_sql_query = \
diff --git a/web/pgadmin/utils/constants.py b/web/pgadmin/utils/constants.py
index 9873371d2..35a5ed51d 100644
--- a/web/pgadmin/utils/constants.py
+++ b/web/pgadmin/utils/constants.py
@@ -34,6 +34,7 @@ SERVER_CONNECTION_CLOSED = gettext(
# Query tool placeholder
QT_DEFAULT_PLACEHOLDER = '%DATABASE%/%USERNAME%@%SERVER%'
+VW_EDT_DEFAULT_PLACEHOLDER = '%SCHEMA%.%TABLE%/%DATABASE%/%USERNAME%@%SERVER%'
# Data Types
DATATYPE_TIME_WITH_TIMEZONE = 'time with time zone'
diff --git a/web/pgadmin/utils/csrf.py b/web/pgadmin/utils/csrf.py
index f88cbf58e..7ad14eebe 100644
--- a/web/pgadmin/utils/csrf.py
+++ b/web/pgadmin/utils/csrf.py
@@ -31,8 +31,9 @@ class _PGCSRFProtect(CSRFProtect):
'pgadmin.tools.translations',
app.blueprints['redirects'],
'pgadmin.browser.server_groups.servers.supported_servers-js',
- 'pgadmin.tools.datagrid.initialize_query_tool',
+ 'pgadmin.tools.sqleditor.initialize_sqleditor',
'pgadmin.tools.datagrid.panel',
+ 'pgadmin.tools.sqleditor.panel',
'pgadmin.tools.debugger.initialize_target',
'pgadmin.tools.debugger.direct_new',
'pgadmin.tools.schema_diff.panel',
diff --git a/web/regression/javascript/components/CodeMirror.spec.js b/web/regression/javascript/components/CodeMirror.spec.js
index 7e8d8f248..6cec715d4 100644
--- a/web/regression/javascript/components/CodeMirror.spec.js
+++ b/web/regression/javascript/components/CodeMirror.spec.js
@@ -52,9 +52,33 @@ describe('CodeMirror', ()=>{
'setSelection': ()=>{/*This is intentional (SonarQube)*/},
'scrollIntoView': ()=>{/*This is intentional (SonarQube)*/},
'getWrapperElement': document.createElement('div'),
+ 'on': ()=>{/*This is intentional (SonarQube)*/},
});
beforeEach(()=>{
jasmineEnzyme();
+ window.pgAdmin = {
+ Browser: {
+ Events: {
+ on: jasmine.createSpy('on'),
+ },
+ get_preferences_for_module: ()=>({}),
+ docker: {
+ findPanels: function() {
+ return [
+ {
+ isVisible: function() {
+ return true;
+ },
+ },
+ ];
+ },
+ },
+ onPreferencesChange: ()=>{/*This is intentional (SonarQube)*/},
+ utils: {
+ app_version_int: 1234,
+ },
+ },
+ };
spyOn(OrigCodeMirror, 'fromTextArea').and.returnValue(cmObj);
const ThemedCM = withTheme(CodeMirror);
cmInstance = mount(
@@ -65,6 +89,10 @@ describe('CodeMirror', ()=>{
/>);
});
+ afterEach(()=>{
+ window.pgAdmin = undefined;
+ });
+
it('init', ()=>{
/* textarea ref passed to fromTextArea */
expect(OrigCodeMirror.fromTextArea).toHaveBeenCalledWith(cmInstance.find('textarea').getDOMNode(), jasmine.objectContaining(options));
diff --git a/web/regression/javascript/components/ShortcutTitle.spec.js b/web/regression/javascript/components/ShortcutTitle.spec.js
index a88f9d7ad..1508bba07 100644
--- a/web/regression/javascript/components/ShortcutTitle.spec.js
+++ b/web/regression/javascript/components/ShortcutTitle.spec.js
@@ -57,7 +57,6 @@ describe('ShortcutTitle', ()=>{
});
describe('shortcutToString', ()=>{
-
it('shortcut', ()=>{
spyOn(keyShort, 'isMac').and.returnValue(false);
expect(shortcutToString(shortcut)).toBe('Ctrl + Shift + K');
@@ -69,6 +68,7 @@ describe('ShortcutTitle', ()=>{
});
it('accesskey', ()=>{
+ spyOnProperty(window.navigator, 'userAgent').and.returnValue('Unknown');
expect(shortcutToString(null, 'A')).toEqual('Accesskey + A');
});
diff --git a/web/regression/javascript/datagrid/get_panel_title_spec.js b/web/regression/javascript/datagrid/get_panel_title_spec.js
deleted file mode 100644
index 1230eb394..000000000
--- a/web/regression/javascript/datagrid/get_panel_title_spec.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import {getPanelTitle} from '../../../pgadmin/tools/datagrid/static/js/datagrid_panel_title';
-import {TreeFake} from '../tree/tree_fake';
-import {TreeNode} from '../../../pgadmin/static/js/tree/tree_nodes';
-import {pgBrowser} from 'pgadmin.browser.preferences';
-
-const context = describe;
-
-var dummy_cache = [
- {
- id: 1,
- mid: 1,
- module:'browser',
- name:'qt_tab_title_placeholder',
- value: '%DATABASE%/%USERNAME%@%SERVER%',
- },
-];
-
-describe('#getPanelTitle', () => {
- let tree;
- beforeEach(() => {
- pgBrowser.preferences_cache = dummy_cache;
- pgBrowser.Nodes = {
- server: {
- hasId: true,
- _type: 'server',
- },
- database: {
- hasId: true,
- _type: 'database',
- },
- };
- pgBrowser.preferences = {
- 'qt_tab_title_placeholder': '',
- };
- tree = new TreeFake(pgBrowser);
- pgBrowser.tree = tree;
- });
-
- context('selected node does not belong to a server', () => {
- it('returns undefined', () => {
- const root = tree.addNewNode('level1', {_type: 'server_groups'});
- tree.addChild(root, new TreeNode('level1.1', {_type: 'other'}));
- tree.selectNode([{id: 'level1'}]);
- expect(getPanelTitle(pgBrowser)).toBeUndefined();
- });
- });
-
- context('selected node belong to a server', () => {
- context('selected node does not belong to a database', () => {
- it('returns the server label and the username', () => {
- tree.addNewNode('level1', {
- _type: 'server',
- db: 'other db label',
- user: {name: 'some user name'},
- label: 'server label',
- }, []);
-
- tree.selectNode([{id: 'level1'}]);
- expect(getPanelTitle(pgBrowser))
- .toEqual('other db label/some user name@server label');
- });
- });
-
- context('selected node belongs to a database', () => {
- it('returns the database label and the username', () => {
- const root = tree.addNewNode('level1', {
- _type: 'server',
- db: 'other db label',
- user: {name: 'some user name'},
- label: 'server label',
- });
- const level1 = new TreeNode('level1.1', {
- _type: 'database',
- label: 'db label',
- });
- tree.addChild(root, level1);
- tree.addChild(level1,
- new TreeNode('level1.1.1', {_type: 'table'}));
- tree.selectNode([{id: 'level1.1.1'}]);
- expect(getPanelTitle(pgBrowser))
- .toEqual('db label/some user name@server label');
- });
- });
- });
-});
diff --git a/web/regression/javascript/datagrid/show_data_spec.js b/web/regression/javascript/datagrid/show_data_spec.js
deleted file mode 100644
index 79f5696b3..000000000
--- a/web/regression/javascript/datagrid/show_data_spec.js
+++ /dev/null
@@ -1,167 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import {showDataGrid} from '../../../pgadmin/tools/datagrid/static/js/show_data';
-import {TreeFake} from '../tree/tree_fake';
-import {TreeNode} from '../../../pgadmin/static/js/tree/tree_nodes';
-import {pgBrowser} from 'pgadmin.browser.preferences';
-import Notify from '../../../pgadmin/static/js/helpers/Notifier';
-
-const context = describe;
-
-var dummy_cache = [
- {
- id: 1,
- mid: 1,
- module:'browser',
- name:'vw_edt_tab_title_placeholder',
- value: '%SCHEMA%.%TABLE%/%DATABASE%/%USERNAME%@%SERVER%',
- },
-];
-
-describe('#show_data', () => {
- let datagrid;
- let alertify;
- let transId = 98765432;
- beforeEach(() => {
- pgBrowser.preferences_cache = dummy_cache;
- alertify = jasmine.createSpyObj('alertify', ['alert', 'error']);
- spyOn(Notify, 'error');
- spyOn(Notify, 'alert');
- datagrid = {
- launch_grid: jasmine.createSpy('launch_grid'),
- };
- pgBrowser.Nodes = {
- server_group: {
- _type: 'server_group',
- hasId: true,
- },
- server: {
- _type: 'server',
- hasId: true,
- },
- database: {
- _type: 'database',
- hasId: true,
- },
- schema: {
- _type: 'schema',
- hasId: true,
- },
- view: {
- _type: 'view',
- hasId: true,
- },
- catalog: {
- _type: 'catalog',
- hasId: true,
- },
- };
- pgBrowser.tree = new TreeFake(pgBrowser);
- const parent = pgBrowser.tree.addNewNode('parent', {_type: 'parent'}, []);
- const serverGroup1 = new TreeNode('server_group1', {
- _type: 'server_group',
- _id: 1,
- });
- pgBrowser.tree.addChild(parent, serverGroup1);
-
- const server1 = new TreeNode('server1', {
- _type: 'server',
- label: 'server1',
- server_type: 'pg',
- _id: 2,
- user: {name: 'someuser'},
- }, ['parent', 'server_group1']);
- pgBrowser.tree.addChild(serverGroup1, server1);
-
- const database1 = new TreeNode('database1', {
- _type: 'database',
- label: 'database1',
- _id: 3,
- }, ['parent', 'server_group1', 'server1']);
- pgBrowser.tree.addChild(server1, database1);
-
- const schema1 = new TreeNode('schema1', {
- _type: 'schema',
- label: 'schema1',
- _id: 4,
- });
- pgBrowser.tree.addChild(database1, schema1);
-
- const view1 = new TreeNode('view1', {
- _type: 'view',
- label: 'view1',
- _id: 5,
- }, ['parent', 'server_group1', 'server1', 'database1']);
- pgBrowser.tree.addChild(database1, view1);
-
- const catalog1 = new TreeNode('catalog1', {
- _type: 'catalog',
- label: 'catalog1',
- _id: 6,
- }, ['parent', 'server_group1', 'server1', 'database1']);
- pgBrowser.tree.addChild(database1, catalog1);
- });
-
- context('cannot find the tree node', () => {
- it('does not create a transaction', () => {
- showDataGrid(datagrid, pgBrowser, alertify, {}, [{id: '10'}], transId);
- expect(datagrid.launch_grid).not.toHaveBeenCalled();
- });
-
- it('display alert', () => {
- showDataGrid(datagrid, pgBrowser, alertify, {}, [{id: '10'}], transId);
- expect(Notify.alert).toHaveBeenCalledWith(
- 'Data Grid Error',
- 'No object selected.'
- );
- });
- });
-
- context('current node is not underneath a server', () => {
- it('does not create a transaction', () => {
- showDataGrid(datagrid, pgBrowser, alertify, {}, [{id: 'parent'}], transId);
- expect(datagrid.launch_grid).not.toHaveBeenCalled();
- });
- });
-
- context('current node is not underneath a schema or view or catalog', () => {
- it('does not create a transaction', () => {
- showDataGrid(datagrid, pgBrowser, alertify, {}, [{id: 'database1'}], transId);
- expect(datagrid.launch_grid).not.toHaveBeenCalled();
- });
- });
-
- context('current node is underneath a schema', () => {
- it('does not create a transaction', () => {
- showDataGrid(datagrid, pgBrowser, alertify, {mnuid: 11}, [{id: 'schema1'}], transId);
- expect(datagrid.launch_grid).not.toHaveBeenCalled();
- });
- });
-
- context('current node is underneath a view', () => {
- it('does not create a transaction', () => {
- showDataGrid(datagrid, pgBrowser, alertify, {mnuid: 11}, [{id: 'view1'}], transId);
-
- expect(datagrid.launch_grid).toHaveBeenCalledWith(
- 98765432,
- '/panel/98765432?is_query_tool=false&cmd_type=11&obj_type=view&obj_id=5&sgid=1&sid=2&did=3&server_type=pg',
- false,
- 'view1.view1/database1/someuser@server1'
- );
- });
- });
-
- context('current node is underneath a catalog', () => {
- it('does not create a transaction', () => {
- showDataGrid(datagrid, pgBrowser, alertify, {mnuid: 11}, [{id: 'catalog1'}], transId);
- expect(datagrid.launch_grid).not.toHaveBeenCalled();
- });
- });
-});
diff --git a/web/regression/javascript/datagrid/show_query_tool_spec.js b/web/regression/javascript/datagrid/show_query_tool_spec.js
deleted file mode 100644
index 5cb677d1f..000000000
--- a/web/regression/javascript/datagrid/show_query_tool_spec.js
+++ /dev/null
@@ -1,132 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import {TreeFake} from '../tree/tree_fake';
-import {showQueryTool} from '../../../pgadmin/tools/datagrid/static/js/show_query_tool';
-import {TreeNode} from '../../../pgadmin/static/js/tree/tree_nodes';
-import {pgBrowser} from 'pgadmin.browser.preferences';
-import Notify from '../../../pgadmin/static/js/helpers/Notifier';
-
-const context = describe;
-
-var dummy_cache = [
- {
- id: 1,
- mid: 1,
- module:'browser',
- name:'qt_tab_title_placeholder',
- value: '%DATABASE%/%USERNAME%@%SERVER%',
- },
-];
-
-describe('#showQueryTool', () => {
- let queryTool;
- let transId = 98765432;
- beforeEach(() => {
- pgBrowser.preferences_cache = dummy_cache;
- spyOn(Notify, 'alert');
- queryTool = {
- launch_grid: jasmine.createSpy('launch_grid'),
- };
- pgBrowser.Nodes = {
- server_group: {
- _type: 'server_group',
- hasId: true,
- },
- server: {
- _type: 'server',
- hasId: true,
- },
- database: {
- _type: 'database',
- hasId: true,
- },
- };
- pgBrowser.tree = new TreeFake(pgBrowser);
-
- const parent = pgBrowser.tree.addNewNode('parent', {_type: 'parent'});
- const serverGroup1 = new TreeNode('server_group1', {
- _type: 'server_group',
- _id: 1,
- }, ['parent']);
- pgBrowser.tree.addChild(parent, serverGroup1);
-
- const server1 = new TreeNode('server1', {
- _type: 'server',
- label: 'server1',
- server_type: 'pg',
- _id: 2,
- user: {name: 'someuser'},
- db: 'otherdblabel',
- });
- pgBrowser.tree.addChild(serverGroup1, server1);
-
- const database1 = new TreeNode('database1', {
- _type: 'database',
- label: 'database1',
- _id: 3,
- });
- pgBrowser.tree.addChild(server1, database1);
- });
-
- context('cannot find the tree node', () => {
- beforeEach(() => {
- showQueryTool(queryTool, pgBrowser, '', [{id: '10'}], transId);
- });
- it('does not create a transaction', () => {
- expect(queryTool.launch_grid).not.toHaveBeenCalled();
- });
-
- it('display alert', () => {
- expect(Notify.alert).toHaveBeenCalledWith(
- 'Query Tool Error',
- 'No object selected.'
- );
- });
- });
-
- context('current node is not underneath a server', () => {
- it('does not create a transaction', () => {
- showQueryTool(queryTool, pgBrowser, '', [{id: 'parent'}], transId);
- expect(queryTool.launch_grid).not.toHaveBeenCalled();
- });
-
- it('no alert is displayed', () => {
- expect(Notify.alert).not.toHaveBeenCalled();
- });
- });
-
- context('current node is underneath a server', () => {
- context('current node is not underneath a database', () => {
- it('creates a transaction', () => {
- showQueryTool(queryTool, pgBrowser, 'http://someurl', [{id: 'server1'}], transId);
- expect(queryTool.launch_grid).toHaveBeenCalledWith(
- 98765432,
- '/panel/98765432?is_query_tool=true&sgid=1&sid=2&server_type=pg',
- true,
- 'otherdblabel/someuser@server1',
- 'http://someurl'
- );
- });
- });
-
- context('current node is underneath a database', () => {
- it('creates a transaction', () => {
- showQueryTool(queryTool, pgBrowser, 'http://someurl', [{id: 'database1'}], transId);
- expect(queryTool.launch_grid).toHaveBeenCalledWith(
- 98765432,
- '/panel/98765432?is_query_tool=true&sgid=1&sid=2&server_type=pg&did=3',
- true,
- 'database1/someuser@server1',
- 'http://someurl'
- );
- });
- });
- });
-});
diff --git a/web/regression/javascript/erd/ui_components/body_widget_spec.js b/web/regression/javascript/erd/ui_components/body_widget_spec.js
index 19eb0d34f..74afced32 100644
--- a/web/regression/javascript/erd/ui_components/body_widget_spec.js
+++ b/web/regression/javascript/erd/ui_components/body_widget_spec.js
@@ -9,7 +9,7 @@ import ERDCore from 'pgadmin.tools.erd/erd_tool/ERDCore';
import * as erdModule from 'pgadmin.tools.erd/erd_module';
import erdPref from './erd_preferences';
import BodyWidget from 'pgadmin.tools.erd/erd_tool/ui_components/BodyWidget';
-import * as ERDSqlTool from 'tools/datagrid/static/js/show_query_tool';
+import * as ERDSqlTool from 'tools/sqleditor/static/js/show_query_tool';
import { FakeLink, FakeNode, FakePort } from '../fake_item';
import Notify from '../../../../pgadmin/static/js/helpers/Notifier';
@@ -42,6 +42,9 @@ let pgAdmin = {
init: jasmine.createSpy(),
show_dialog: jasmine.createSpy(),
},
+ Tools: {
+ SQLEditor: {},
+ }
};
let pgWindow = {
diff --git a/web/regression/javascript/fake_endpoints.js b/web/regression/javascript/fake_endpoints.js
index ddd50fb8b..fd5ec175f 100644
--- a/web/regression/javascript/fake_endpoints.js
+++ b/web/regression/javascript/fake_endpoints.js
@@ -14,11 +14,11 @@ define(function () {
'sqleditor.query_tool_start': '/sqleditor/query_tool/start/',
'backup.create_server_job': '/backup/job/',
'backup.create_object_job': '/backup/job//object',
- 'datagrid.initialize_datagrid': '/initialize/datagrid//////',
- 'datagrid.initialize_query_tool': '/initialize/query_tool//',
- 'datagrid.initialize_query_tool_with_did': '/initialize/query_tool///',
+ 'sqleditor.initialize_viewdata': '/initialize/sqleditor//////',
+ 'sqleditor.initialize_sqleditor': '/initialize/sqleditor//',
+ 'sqleditor.initialize_sqleditor_with_did': '/initialize/sqleditor///',
'restore.create_job': '/restore/job/',
- 'datagrid.panel': '/panel/',
+ 'sqleditor.panel': '/panel/',
'search_objects.types': '/search_objects/types//',
'search_objects.search': '/search_objects/search//',
'dashboard.dashboard_stats': '/dashboard/dashboard_stats',
diff --git a/web/regression/javascript/geometry_viewer/geometry_viewer_spec.js b/web/regression/javascript/geometry_viewer/geometry_viewer_spec.js
deleted file mode 100644
index 2710eb1e0..000000000
--- a/web/regression/javascript/geometry_viewer/geometry_viewer_spec.js
+++ /dev/null
@@ -1,232 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import GeometryViewer from 'sources/sqleditor/geometry_viewer';
-import {Geometry} from 'wkx';
-
-describe('geometry viewer test', function () {
-
- describe('geometry viewer add header button test', function () {
- let add_button = GeometryViewer.add_header_button;
- it('should add button for geography type', function () {
- let columnDef = {
- column_type_internal: 'geography',
- };
- add_button(columnDef);
- expect(columnDef.header).toBeDefined();
- });
-
- it('should add button for geometry type', function () {
- let columnDef = {
- column_type_internal: 'geometry',
- };
- add_button(columnDef);
- expect(columnDef.header).toBeDefined();
- });
- });
-
- describe('geometry viewer rener geometry test', function () {
-
- it('should group geometry by srid', function () {
- // POINT(0 0)
- let ewkb = '010100000000000000000000000000000000000000';
- // SRID=32632;POINT(0 0)
- let ewkb1 = '0101000020787F000000000000000000000000000000000000';
- let items = [{
- id: 1,
- geom: ewkb,
- }, {
- id: 1,
- geom: ewkb,
- }, {
- id: 1,
- geom: ewkb1,
- }];
- let columns = [
- {
- column_type_internal: 'geometry',
- field: 'geom',
- },
- ];
- let columnIndex = 0;
- let result = GeometryViewer.parse_data(items, columns, columnIndex, Geometry);
- expect(result.geoJSONs.length).toEqual(2);
- });
-
-
- it('should support geometry collection', function () {
- // GEOMETRYCOLLECTION(POINT(2 3),LINESTRING(2 3,3 4))
- let ewkb = '01070000000200000001010000000000000000000040000000000000084001' +
- '02000000020000000000000000000040000000000000084000000000000008400000000' +
- '000001040';
- let items = [{
- id: 1,
- geom: ewkb,
- }];
- let columns = [
- {
- column_type_internal: 'geometry',
- field: 'geom',
- },
- ];
- let columnIndex = 0;
- let result = GeometryViewer.parse_data(items, columns, columnIndex, Geometry);
- expect(result.geoJSONs.length).toEqual(1);
- });
-
- it('should support geometry M', function () {
- // SRID=4326;MULTIPOINTM(0 0 0,1 2 1)
- let ewkb = '0104000060E610000002000000010100004000000000000000000000000000' +
- '00000000000000000000000101000040000000000000F03F00000000000000400000000' +
- '00000F03F';
- let items = [{
- id: 1,
- geom: ewkb,
- }];
- let columns = [
- {
- column_type_internal: 'geometry',
- field: 'geom',
- },
- ];
- let columnIndex = 0;
- let result = GeometryViewer.parse_data(items, columns, columnIndex, Geometry);
- expect(result.geoJSONs.length).toEqual(1);
- });
-
- it('should support empty geometry', function () {
- // GEOMETRYCOLLECTION EMPTY
- let ewkb = '010700000000000000';
- let items = [{
- id: 1,
- geom: ewkb,
- }];
- let columns = [
- {
- column_type_internal: 'geometry',
- field: 'geom',
- },
- ];
- let columnIndex = 0;
- let result = GeometryViewer.parse_data(items, columns, columnIndex, Geometry);
- expect(result.geoJSONs.length).toEqual(1);
- });
-
-
- it('should support mixed geometry type', function () {
- // GEOMETRYCOLLECTION EMPTY
- let ewkb = '010700000000000000';
- // POINT(0 0)
- let ewkb1 = '010100000000000000000000000000000000000000';
- // SRID=4326;MULTIPOINTM(0 0 0,1 2 1)
- let ewkb2 = '0104000060E610000002000000010100004000000000000000000000000000' +
- '00000000000000000000000101000040000000000000F03F00000000000000400000000' +
- '00000F03F';
- let items = [{
- id: 1,
- geom: ewkb,
- }, {
- id: 1,
- geom: ewkb1,
- }, {
- id: 1,
- geom: ewkb2,
- }];
- let columns = [
- {
- column_type_internal: 'geometry',
- field: 'geom',
- },
- ];
- let columnIndex = 0;
- let result = GeometryViewer.parse_data(items, columns, columnIndex, Geometry);
- expect(result.geoJSONs.length).toEqual(2);
- });
-
-
- it('should not support 3D geometry', function () {
- // POINT(0 0 0)
- let ewkb = '0101000080000000000000F03F000000000000F03F000000000000F03F';
- let items = [{
- id: 1,
- geom: ewkb,
- }];
- let columns = [
- {
- column_type_internal: 'geometry',
- field: 'geom',
- },
- ];
- let columnIndex = 0;
- let result = GeometryViewer.parse_data(items, columns, columnIndex, Geometry);
- expect(result.geoJSONs.length).toEqual(0);
- });
-
- it('should not support 3DM geometry', function () {
- // POINT(0 0 0 0)
- let ewkb = '01010000C00000000000000000000000000000000000000000000000000000' +
- '000000000000';
- let items = [{
- id: 1,
- geom: ewkb,
- }];
- let columns = [
- {
- column_type_internal: 'geometry',
- field: 'geom',
- },
- ];
- let columnIndex = 0;
- let result = GeometryViewer.parse_data(items, columns, columnIndex, Geometry);
- expect(result.geoJSONs.length).toEqual(0);
- });
-
- it('should not support TRIANGLE geometry', function () {
- // TRIANGLE ((0 0, 0 9, 9 0, 0 0))
- let ewkb = '01110000000100000004000000000000000000000000000000000000000000' +
- '00000000000000000000000022400000000000002240000000000000000000000000000' +
- '000000000000000000000';
- let items = [{
- id: 1,
- geom: ewkb,
- }];
- let columns = [
- {
- column_type_internal: 'geometry',
- field: 'geom',
- },
- ];
- let columnIndex = 0;
- let result = GeometryViewer.parse_data(items, columns, columnIndex, Geometry);
- expect(result.geoJSONs.length).toEqual(0);
- });
-
- it('should limit data size', function () {
- // POINT(0 0)
- let ewkb = '010100000000000000000000000000000000000000';
- let items = [];
- for (let i = 0; i < 600000; i++) {
- items.push({
- id: i,
- geom: ewkb,
- });
- }
-
- let columns = [
- {
- column_type_internal: 'geometry',
- field: 'geom',
- },
- ];
- let columnIndex = 0;
- let result = GeometryViewer.parse_data(items, columns, columnIndex, Geometry);
- expect(result.geoJSONs.length).toBeLessThan(600000);
- });
- });
-});
diff --git a/web/regression/javascript/history/history_collection_spec.js b/web/regression/javascript/history/history_collection_spec.js
deleted file mode 100644
index fef3e674b..000000000
--- a/web/regression/javascript/history/history_collection_spec.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import HistoryCollection from 'sources/sqleditor/history/history_collection';
-
-describe('historyCollection', function () {
- let historyCollection, historyModel, onAddSpy, onResetSpy;
- beforeEach(() => {
- historyModel = [{some: 'thing', someOther: ['array element']}];
- historyCollection = new HistoryCollection(historyModel);
- onAddSpy = jasmine.createSpy('onAddHandler');
- onResetSpy = jasmine.createSpy('onResetHandler');
-
- historyCollection.onAdd(onAddSpy);
- historyCollection.onReset(onResetSpy);
- });
-
- describe('length', function () {
- it('returns 0 when underlying history model has no elements', function () {
- historyCollection = new HistoryCollection([]);
-
- expect(historyCollection.length()).toEqual(0);
- });
-
- it('returns the length of the underlying history model', function () {
- expect(historyCollection.length()).toEqual(1);
- });
- });
-
- describe('add', function () {
- let expectedHistory;
- let newEntry = {some: 'new thing', someOther: ['value1', 'value2']};
- beforeEach(() => {
- historyCollection.add(newEntry);
-
- expectedHistory = [
- {some: 'new thing', someOther: ['value1', 'value2']},
- {some: 'thing', someOther: ['array element']},
- ];
- });
-
- it('adds a passed entry', function () {
- expect(historyCollection.historyList).toEqual(expectedHistory);
- });
-
- it('calls the onChange function', function () {
- expect(onAddSpy).toHaveBeenCalledWith(newEntry);
- });
- });
-
- describe('reset', function () {
- beforeEach(() => {
- historyCollection.reset();
- });
-
- it('drops the history', function () {
- expect(historyCollection.historyList).toEqual([]);
- expect(historyCollection.length()).toEqual(0);
- });
-
- it('calls the onReset function', function () {
- expect(onResetSpy).toHaveBeenCalledWith([]);
- });
- });
-
- describe('when instantiated', function () {
- describe('from a history model', function () {
- it('has the historyModel', () => {
- let content = historyCollection.historyList;
-
- expect(content).toEqual(historyModel);
- });
-
- });
- });
-});
diff --git a/web/regression/javascript/history/query_history_spec.js b/web/regression/javascript/history/query_history_spec.js
deleted file mode 100644
index 34a0a1247..000000000
--- a/web/regression/javascript/history/query_history_spec.js
+++ /dev/null
@@ -1,405 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-/* eslint-disable react/no-find-dom-node */
-
-import QueryHistory from 'sources/sqleditor/history/query_history';
-import HistoryCollection from 'sources/sqleditor/history/history_collection';
-import clipboard from 'sources/selection/clipboard';
-import $ from 'jquery';
-import moment from 'moment';
-
-describe('QueryHistory', () => {
- let historyCollection;
- let historyWrapper;
- let historyComponent;
-
- beforeEach(() => {
- historyWrapper = $('
').appendTo('body');
- });
-
- describe('when there is no history', () => {
- beforeEach(() => {
- historyCollection = new HistoryCollection([]);
-
- historyComponent = new QueryHistory(historyWrapper, historyCollection);
- historyComponent.render();
- });
-
- it('has no entries', (done) => {
- let foundChildren = historyWrapper.find('#query_list');
- expect(foundChildren.length).toBe(0);
- done();
- });
-
- it('No history found is displayed', (done) => {
- expect(historyWrapper.find('.pg-panel-message').html()).toBe('No history found');
- done();
- });
- });
-
- describe('when there is history', () => {
- let queryEntries;
- let queryDetail;
-
- describe('when two SQL queries were executed', () => {
-
- beforeEach(() => {
- const historyObjects = [{
- query: 'first sql statement',
- start_time: new Date(2017, 5, 3, 14, 3, 15, 150),
- status: true,
- row_affected: 12345,
- total_time: '14 msec',
- message: 'something important ERROR: message from first sql query',
- }, {
- query: 'second sql statement',
- start_time: new Date(2016, 11, 11, 1, 33, 5, 99),
- status: false,
- row_affected: 1,
- total_time: '234 msec',
- message: 'something important ERROR: message from second sql query',
- }];
-
- historyCollection = new HistoryCollection(historyObjects);
- historyComponent = new QueryHistory(historyWrapper, historyCollection);
- historyComponent.onCopyToEditorClick(()=>{/*This is intentional (SonarQube)*/});
- historyComponent.render();
-
- queryEntries = historyWrapper.find('#query_list .list-item');
- queryDetail = historyWrapper.find('#query_detail');
- });
-
- describe('the history entries panel', () => {
- it('has two query history entries', (done) => {
- expect(queryEntries.length).toBe(2);
- done();
- });
-
- it('displays the query history entries in order', () => {
- expect($(queryEntries[0]).text()).toContain('first sql statement');
- expect($(queryEntries[1]).text()).toContain('second sql statement');
- });
-
- it('displays the formatted timestamp of the queries in chronological order by most recent first', () => {
- expect($(queryEntries[0]).find('.timestamp').text()).toBe('14:03:15');
- expect($(queryEntries[1]).find('.timestamp').text()).toBe('01:33:05');
- });
-
- it('renders the most recent query as selected', (done) => {
- expect($(queryEntries[0]).hasClass('selected')).toBeTruthy();
- done();
- });
-
- it('renders the older query as not selected', () => {
- expect($(queryEntries[1]).hasClass('selected')).toBeFalsy();
- expect($(queryEntries[1]).find('.entry').hasClass('error')).toBeTruthy();
- });
- });
-
- describe('the historydetails panel', () => {
- let copyAllButton, copyEditorButton;
-
- beforeEach(() => {
- copyAllButton = () => queryDetail.find('#history-detail-query .btn-copy');
- copyEditorButton = () => queryDetail.find('#history-detail-query .btn-copy-editor');
- });
-
- it('should change preference font size', ()=>{
- historyComponent.setEditorPref({sql_font_size: '1.5em'});
- expect(queryDetail.find('#history-detail-query .CodeMirror').attr('style')).toBe('font-size: 1.5em;');
- });
-
- it('should change preference copy to editor false', ()=>{
- historyComponent.setEditorPref({copy_to_editor: false});
- expect($(queryDetail.find('#history-detail-query .btn-copy-editor')).hasClass('d-none')).toBe(true);
- });
-
- it('displays the formatted timestamp', () => {
- let firstDate = new Date(2017, 5, 3, 14, 3, 15, 150);
- expect(queryDetail.text()).toContain(firstDate.toLocaleDateString() + ' ' + firstDate.toLocaleTimeString());
- });
-
- it('displays the number of rows affected', () => {
- if (/PhantomJS/.test(window.navigator.userAgent)) {
- expect(queryDetail.text()).toContain('12345');
- } else {
- expect(queryDetail.text()).toContain('12,345');
- }
- });
-
- it('displays the total time', () => {
- expect(queryDetail.text()).toContain('14 msec');
- });
-
- it('displays the full message', () => {
- expect(queryDetail.text()).toContain('message from first sql query');
- });
-
- it('displays first query SQL', (done) => {
- setTimeout(() => {
- expect(queryDetail.text()).toContain('first sql statement');
- done();
- }, 1000);
- });
-
- describe('when the "Copy" button is clicked', () => {
- beforeEach(() => {
- spyOn(clipboard, 'copyTextToClipboard');
- copyAllButton().trigger('click');
- });
-
- it('copies the query to the clipboard', () => {
- expect(clipboard.copyTextToClipboard).toHaveBeenCalledWith('first sql statement');
- });
- });
-
- describe('Copy button', () => {
- beforeEach(() => {
- jasmine.clock().install();
- });
-
- afterEach(() => {
- jasmine.clock().uninstall();
- });
-
- it('should have text \'Copy\'', () => {
- expect(copyAllButton().text()).toBe('Copy');
- });
-
- it('should not have the class \'was-copied\'', () => {
- expect(copyAllButton().hasClass('was-copied')).toBe(false);
- });
-
- describe('when the copy button is clicked', () => {
- beforeEach(() => {
- copyAllButton().trigger('click');
- });
-
- describe('before 1.5 seconds', () => {
- beforeEach(() => {
- jasmine.clock().tick(1499);
- });
-
- it('1.5 seconds should change the button text to \'Copied!\'', () => {
- expect(copyAllButton().text()).toBe('Copied!');
- });
-
- it('should have the class \'was-copied\'', () => {
- expect(copyAllButton().hasClass('was-copied')).toBe(true);
- });
- });
-
- describe('after 1.5 seconds', () => {
- beforeEach(() => {
- jasmine.clock().tick(1501);
- });
-
- it('1.5 seconds should change the button text back to \'Copy\'', () => {
- expect(copyAllButton().text()).toBe('Copy');
- });
- });
-
- describe('when is clicked again after 1s', () => {
- beforeEach(() => {
- jasmine.clock().tick(1000);
- copyAllButton().trigger('click');
-
- });
-
- describe('before 2.5 seconds', () => {
- beforeEach(() => {
- jasmine.clock().tick(1499);
- });
-
- it('should change the button text to \'Copied!\'', () => {
- expect(copyAllButton().text()).toBe('Copied!');
- });
-
- it('should have the class \'was-copied\'', () => {
- expect(copyAllButton().hasClass('was-copied')).toBe(true);
- });
- });
-
- describe('after 2.5 seconds', () => {
- beforeEach(() => {
- jasmine.clock().tick(1501);
- });
-
- it('should change the button text back to \'Copy\'', () => {
- expect(copyAllButton().text()).toBe('Copy');
- });
- });
- });
- });
- });
-
- describe('when the "Copy to query editor" button is clicked', () => {
- beforeEach(() => {
- spyOn(historyComponent.queryHistDetails, 'onCopyToEditorHandler').and.callThrough();
- copyEditorButton().trigger('click');
- });
-
- it('sends the query to the onCopyToEditorHandler', () => {
- expect(historyComponent.queryHistDetails.onCopyToEditorHandler).toHaveBeenCalledWith('first sql statement');
- });
- });
-
- describe('when the query failed', () => {
- let failedEntry;
-
- beforeEach(() => {
- failedEntry = $(queryEntries[1]);
- failedEntry.trigger('click');
- });
-
- it('displays the error message on top of the details pane', () => {
- expect(queryDetail.text()).toContain('Error Message message from second sql query');
- });
- });
- });
-
-
- describe('when the older query is clicked on', () => {
- let firstEntry, secondEntry;
-
- beforeEach(() => {
- firstEntry = $(queryEntries[0]);
- secondEntry = $(queryEntries[1]);
- secondEntry.trigger('click');
- });
-
- it('displays the query in the right pane', () => {
- expect(queryDetail.text()).toContain('second sql statement');
- });
-
- it('deselects the first history entry', () => {
- expect(firstEntry.hasClass('selected')).toBeFalsy();
- });
-
- it('selects the second history entry', () => {
- expect(secondEntry.hasClass('selected')).toBeTruthy();
- });
- });
-
- describe('when a third SQL query is executed', () => {
- beforeEach(() => {
- historyCollection.add({
- query: 'third sql statement',
- start_time: new Date(2017, 11, 11, 1, 33, 5, 99),
- status: false,
- row_affected: 5,
- total_time: '26 msec',
- message: 'pretext ERROR: third sql message',
- });
-
- queryEntries = historyWrapper.find('#query_list .list-item');
- });
-
- it('displays third query SQL in the right pane', () => {
- expect(queryDetail.text()).toContain('third sql statement');
- });
- });
-
- describe('when a fourth SQL query is executed', () => {
- beforeEach(() => {
- historyCollection.add({
- query: 'fourth sql statement',
- start_time: new Date(2017, 12, 12, 1, 33, 5, 99),
- status: false,
- row_affected: 0,
- total_time: '26 msec',
- message: 'ERROR: unexpected error from fourth sql message',
- });
-
- queryEntries = historyWrapper.find('#query_list .list-item');
- });
-
- it('displays fourth query SQL in the right pane', () => {
- expect(queryDetail.text()).toContain('Error Message unexpected error from fourth sql message');
- });
- });
- });
-
- describe('when several days of queries were executed', () => {
- let queryEntryDateGroups;
- let dateToday, dateYest, dateBeforeYest;
-
- beforeEach(() => {
- jasmine.clock().install();
- const mockedCurrentDate = moment('2017-07-01 13:30:00');
- jasmine.clock().mockDate(mockedCurrentDate.toDate());
-
- dateToday = mockedCurrentDate.toDate();
- dateYest = mockedCurrentDate.clone().subtract(1, 'days').toDate();
- dateBeforeYest = mockedCurrentDate.clone().subtract(3, 'days').toDate();
-
- const historyObjects = [{
- query: 'first today sql statement',
- start_time: mockedCurrentDate.toDate(),
- status: true,
- row_affected: 12345,
- total_time: '14 msec',
- message: 'message from first today sql query',
- }, {
- query: 'second today sql statement',
- start_time: mockedCurrentDate.clone().subtract(1, 'hours').toDate(),
- status: false,
- row_affected: 1,
- total_time: '234 msec',
- message: 'message from second today sql query',
- }, {
- query: 'first yesterday sql statement',
- start_time: mockedCurrentDate.clone().subtract(1, 'days').toDate(),
- status: true,
- row_affected: 12345,
- total_time: '14 msec',
- message: 'message from first yesterday sql query',
- }, {
- query: 'second yesterday sql statement',
- start_time: mockedCurrentDate.clone().subtract(1, 'days').subtract(1, 'hours').toDate(),
- status: false,
- row_affected: 1,
- total_time: '234 msec',
- message: 'message from second yesterday sql query',
- }, {
- query: 'older than yesterday sql statement',
- start_time: mockedCurrentDate.clone().subtract(3, 'days').toDate(),
- status: true,
- row_affected: 12345,
- total_time: '14 msec',
- message: 'message from older than yesterday sql query',
- }];
- historyCollection = new HistoryCollection(historyObjects);
-
- historyComponent = new QueryHistory(historyWrapper, historyCollection);
- historyComponent.render();
-
- queryEntries = historyWrapper.find('#query_list .list-item');
- queryEntryDateGroups = historyWrapper.find('#query_list .query-group');
- });
-
- afterEach(() => {
- jasmine.clock().uninstall();
- });
-
- describe('the history entries panel', () => {
- it('has three query history entry data groups', () => {
- expect(queryEntryDateGroups.length).toBe(3);
- });
-
- it('has title above', () => {
- expect($(queryEntryDateGroups[0]).find('.date-label').text()).toBe('Today - ' + dateToday.toLocaleDateString());
- expect($(queryEntryDateGroups[1]).find('.date-label').text()).toBe('Yesterday - ' + dateYest.toLocaleDateString());
- expect($(queryEntryDateGroups[2]).find('.date-label').text()).toBe(dateBeforeYest.toLocaleDateString());
- });
- });
- });
- });
-});
diff --git a/web/regression/javascript/sqleditor/calculate_query_run_time_spec.js b/web/regression/javascript/sqleditor/calculate_query_run_time_spec.js
deleted file mode 100644
index e0e81d0d2..000000000
--- a/web/regression/javascript/sqleditor/calculate_query_run_time_spec.js
+++ /dev/null
@@ -1,105 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import moment from 'moment';
-import {calculateQueryRunTime} from '../../../pgadmin/static/js/sqleditor/calculate_query_run_time';
-
-describe('#calculateQueryRunTime', () => {
- describe('time difference is smaller then 1 second', () => {
- it('displays milliseconds', () => {
- let startDate = moment({
- years:2018,
- months:4,
- date:2,
- hours:10,
- minutes:30,
- seconds:20,
- milliseconds:123}).toDate();
- let endDate = moment({
- years:2018,
- months:4,
- date:2,
- hours:10,
- minutes:30,
- seconds:21,
- milliseconds:70}).toDate();
- expect(calculateQueryRunTime(startDate, endDate))
- .toEqual('947 msec');
- });
- });
-
- describe('time difference is smaller then 1 minute', () => {
- it('displays milliseconds', () => {
- let startDate = moment({
- years:2018,
- months:4,
- date:2,
- hours:10,
- minutes:30,
- seconds:20,
- milliseconds:123}).toDate();
- let endDate = moment({
- years:2018,
- months:4,
- date:2,
- hours:10,
- minutes:31,
- seconds:15,
- milliseconds:70}).toDate();
- expect(calculateQueryRunTime(startDate, endDate))
- .toEqual('54 secs 947 msec');
- });
- });
-
- describe('time difference is bigger then 1 minute', () => {
- it('displays milliseconds', () => {
- let startDate = moment({
- years:2018,
- months:4,
- date:2,
- hours:10,
- minutes:30,
- seconds:20,
- milliseconds:123}).toDate();
- let endDate = moment({
- years:2018,
- months:4,
- date:2,
- hours:10,
- minutes:40,
- seconds:15,
- milliseconds:70}).toDate();
- expect(calculateQueryRunTime(startDate, endDate))
- .toEqual('9 min 54 secs');
- });
- });
-
- describe('time difference is bigger then 1 hour', () => {
- it('displays seconds, milliseconds', () => {
- let startDate = moment({
- years:2018,
- months:4,
- date:2,
- hours:10,
- minutes:30,
- seconds:20,
- milliseconds:123}).toDate();
- let endDate = moment({
- years:2018,
- months:4,
- date:2,
- hours:11,
- minutes:40,
- seconds:15,
- milliseconds:70}).toDate();
- expect(calculateQueryRunTime(startDate, endDate))
- .toEqual('1 hr 9 min');
- });
- });
-});
diff --git a/web/regression/javascript/sqleditor/call_render_after_poll_spec.js b/web/regression/javascript/sqleditor/call_render_after_poll_spec.js
deleted file mode 100644
index 9035f1612..000000000
--- a/web/regression/javascript/sqleditor/call_render_after_poll_spec.js
+++ /dev/null
@@ -1,202 +0,0 @@
-/////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////
-
-import {callRenderAfterPoll} from '../../../pgadmin/static/js/sqleditor/call_render_after_poll';
-import moment from 'moment';
-
-describe('#callRenderAfterPoll', () => {
- let sqlEditorSpy, queryResult, Notify;
- beforeEach(() => {
- let today = moment('2018-01-01 10:12:31').toDate();
- jasmine.clock().install();
- jasmine.clock().mockDate(today);
- sqlEditorSpy = {
- _render: jasmine.createSpy('SQLEditor._render'),
- setIsQueryRunning: jasmine.createSpy('SQLEditor.setIsQueryRunning'),
- trigger: jasmine.createSpy('SQLEditor.trigger'),
- update_msg_history: jasmine.createSpy('SQLEditor.update_msg_history'),
- disable_tool_buttons: jasmine.createSpy('SQLEditor.disable_tool_buttons'),
- disable_transaction_buttons: jasmine.createSpy('SQLEditor.disable_transaction_buttons'),
- reset_data_store: jasmine.createSpy('SQLEditor.reset_data_store'),
- enable_disable_download_btn: jasmine.createSpy('SQLEditor.enable_disable_download_btn'),
- check_db_name_change: jasmine.createSpy('SQLEditor.check_db_name_change'),
- query_start_time: new Date(),
- };
- Notify = jasmine.createSpyObj('Notify', ['success']);
- });
-
- afterEach(function () {
- jasmine.clock().uninstall();
- });
-
- let expectAction = (expectObj, callWithValue=null)=> {
- callRenderAfterPoll(sqlEditorSpy, Notify, queryResult);
- if (callWithValue !== null) {
- expect(expectObj).toHaveBeenCalledWith(callWithValue);
- } else {
- expect(expectObj).toHaveBeenCalledWith();
- }
- };
-
- let queryResult1 = ()=>{
- queryResult = {
- rows_affected: 10,
- has_more_rows: false,
- colinfo: {},
- };
- };
-
- let queryResult2 = ()=>{
- queryResult = {
- rows_affected: 10,
- has_more_rows: false,
- colinfo: undefined,
- result: 'Some result',
- };
- };
-
- let displayNotificationAction = ()=> {
- sqlEditorSpy.info_notifier_timeout = 10;
- callRenderAfterPoll(sqlEditorSpy, Notify, queryResult);
-
- expect(Notify.success).toHaveBeenCalledWith(
- 'Query returned successfully in 0 msec.',
- 10
- );
- };
-
- let saveAction = ()=> {
- callRenderAfterPoll(sqlEditorSpy, Notify, queryResult);
-
- expect(sqlEditorSpy.update_msg_history).toHaveBeenCalledWith(
- true,
- 'Some result\n\nQuery returned successfully in 0 msec.',
- false
- );
- };
-
- describe('it is not a query tool', () => {
- beforeEach(() => {
- sqlEditorSpy.is_query_tool = false;
- });
-
- describe('query was successful and have results', () => {
- beforeEach(queryResult1);
-
- it('renders the editor', () => {
- expectAction(sqlEditorSpy._render, queryResult);
- });
-
- it('inform sqleditor that the query stopped running', () => {
- expectAction(sqlEditorSpy.setIsQueryRunning, false);
- });
-
- it('hides the loading icon', () => {
- expectAction(sqlEditorSpy.trigger, 'pgadmin-sqleditor:loading-icon:hide');
- });
- });
-
- describe('query was successful but had no result to display', () => {
- beforeEach(queryResult2);
-
- it('saves execution information in the history', () => {
- saveAction();
- });
-
- it('resets the changed data store', () => {
- expectAction(sqlEditorSpy.reset_data_store);
- });
-
- it('inform sqleditor that the query stopped running', () => {
- expectAction(sqlEditorSpy.setIsQueryRunning, false);
- });
-
- it('hides the loading icon', () => {
- expectAction(sqlEditorSpy.trigger, 'pgadmin-sqleditor:loading-icon:hide');
- });
-
- describe('notifications are enabled', () => {
- it('display notification', displayNotificationAction);
- });
-
- it('disables the save results button', () => {
- expectAction(sqlEditorSpy.enable_disable_download_btn, true);
- expect(sqlEditorSpy.trigger).toHaveBeenCalledWith('pgadmin-sqleditor:loading-icon:hide');
- });
- });
- });
-
- describe('it is a query tool', () => {
- beforeEach(() => {
- sqlEditorSpy.is_query_tool = true;
- });
-
- describe('query was successful and have results', () => {
- beforeEach(queryResult1);
-
- it('renders the editor', () => {
- expectAction(sqlEditorSpy._render, queryResult);
- });
-
- it('inform sqleditor that the query stopped running', () => {
- expectAction(sqlEditorSpy.setIsQueryRunning, false);
- });
-
- it('hides the loading icon', () => {
- expectAction(sqlEditorSpy.trigger, 'pgadmin-sqleditor:loading-icon:hide');
- });
-
- it('enables sqleditor tools buttons', () => {
- expectAction(sqlEditorSpy.disable_tool_buttons, false);
- });
- });
-
- describe('query was successful but had no result to display', () => {
- beforeEach(queryResult2);
-
- it('saves execution information in the history', () => {
- saveAction();
- });
-
- it('resets the changed data store', () => {
- expectAction(sqlEditorSpy.reset_data_store);
- });
-
- it('inform sqleditor that the query stopped running', () => {
- expectAction(sqlEditorSpy.setIsQueryRunning, false);
- });
-
- it('hides the loading icon', () => {
- expectAction(sqlEditorSpy.trigger, 'pgadmin-sqleditor:loading-icon:hide');
- });
-
- it('enables sqleditor tools buttons', () => {
- expectAction(sqlEditorSpy.disable_tool_buttons, false);
- });
-
- describe('notifications are enabled', () => {
- it('display notification', displayNotificationAction);
- });
-
- it('disables the save results button', () => {
- expectAction(sqlEditorSpy.enable_disable_download_btn, true);
-
- expect(sqlEditorSpy.trigger).toHaveBeenCalledWith('pgadmin-sqleditor:loading-icon:hide');
- });
-
- it('check whether database has been moved/renamed', () => {
- callRenderAfterPoll(sqlEditorSpy, Notify, queryResult);
-
- expect(sqlEditorSpy.trigger).toHaveBeenCalledWith('pgadmin-sqleditor:check_synchronous_db_name_change', queryResult);
-
- expect(sqlEditorSpy.trigger).toHaveBeenCalledWith('pgadmin-sqleditor:loading-icon:hide');
- });
- });
- });
-});
diff --git a/web/regression/javascript/sqleditor/execute_query_spec.js b/web/regression/javascript/sqleditor/execute_query_spec.js
deleted file mode 100644
index 9a13401e2..000000000
--- a/web/regression/javascript/sqleditor/execute_query_spec.js
+++ /dev/null
@@ -1,1044 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////////////////
-
-import * as subject from 'sources/sqleditor/execute_query';
-import * as httpErrorHandler from 'sources/sqleditor/query_tool_http_error_handler';
-import axios from 'axios';
-import MockAdapter from 'axios-mock-adapter';
-import $ from 'jquery';
-
-const context = describe;
-
-describe('ExecuteQuery', () => {
- let sqlEditorMock;
- let networkMock;
- let executeQuery;
- let userManagementMock;
- let isNewTransactionRequiredMock;
-
- const startTime = new Date(2018, 1, 29, 12, 15, 52);
- beforeEach(() => {
- networkMock = new MockAdapter(axios);
- userManagementMock = jasmine.createSpyObj('UserManagement', [
- 'isPgaLoginRequired',
- 'pgaLogin',
- ]);
-
- sqlEditorMock = jasmine.createSpyObj('SqlEditor', [
- 'call_render_after_poll',
- 'disable_tool_buttons',
- 'resetQueryHistoryObject',
- 'setIsQueryRunning',
- 'trigger',
- 'update_msg_history',
- '_highlight_error',
- '_init_polling_flags',
- 'saveState',
- 'initTransaction',
- 'handle_connection_lost',
- 'update_notifications',
- 'disable_transaction_buttons',
- 'enable_disable_download_btn',
- ]);
- sqlEditorMock.transId = 123;
- sqlEditorMock.rows_affected = 1000;
- executeQuery = new subject.ExecuteQuery(sqlEditorMock, userManagementMock);
- isNewTransactionRequiredMock = spyOn(httpErrorHandler, 'httpResponseRequiresNewTransaction');
- });
-
- afterEach(() => {
- networkMock.restore();
- });
-
- let updateHistoryNotCalled = (done)=> {
- setTimeout(() => {
- expect(sqlEditorMock.update_msg_history).not.toHaveBeenCalled();
- done();
- }, 0);
- };
-
- let pgaLoginNotCalled = (done)=> {
- setTimeout(() => {
- expect(userManagementMock.pgaLogin).not.toHaveBeenCalled();
- done();
- }, 0);
- };
-
- let disableToolButtonsNotCalled = (done)=> {
- setTimeout(() => {
- expect(sqlEditorMock.disable_tool_buttons).not.toHaveBeenCalled();
- done();
- }, 0);
- };
-
- let cancelButtonNotCalled = (done)=> {
- let cancelButtonSpy = spyOn($.fn, 'prop');
- setTimeout(() => {
- expect(cancelButtonSpy).not.toHaveBeenCalled();
- done();
- }, 0);
- };
-
- let beforeEachNotConnected = ()=> {
- let response = {
- data: {
- status: 'NotConnected',
- result: 'Some interesting result',
- },
- };
- networkMock.onGet('/sqleditor/query_tool/poll/123').reply(200, response);
-
- executeQuery.poll();
- };
-
- let beforeEachPythonServer = ()=> {
- networkMock.onGet('/sqleditor/query_tool/poll/123').reply(404, undefined);
- executeQuery.poll();
- };
-
- let setFlagQueryIsRunningTestCase = ()=> {
- it('should set the flag to inform SQLEditor a query is running', (done) => {
- setTimeout(() => {
- expect(sqlEditorMock.setIsQueryRunning)
- .toHaveBeenCalledWith(true);
- done();
- }, 0);
- });
- };
-
- let updateHistoryMessageTestCase = ()=> {
- it('should update history message', (done) => {
- setTimeout(() => {
- expect(sqlEditorMock.update_msg_history)
- .toHaveBeenCalledWith('Busy', 'Some important result', false);
- done();
- }, 0);
- });
- };
-
- let callPoolingTestCase = ()=> {
- it('should recursively call polling', (done) => {
- setTimeout(() => {
- expect(executeQuery.delayedPoll)
- .toHaveBeenCalled();
- done();
- }, 0);
- });
- };
-
- let shouldNotUpdateHistoryMessageTestCase = ()=> {
- it('should does not update history', (done) => {
- updateHistoryNotCalled(done);
- });
- };
-
- let shouldHideLoadingIconTestCase = ()=> {
- it('should hide the loading icon', (done) => {
- setTimeout(() => {
- expect(sqlEditorMock.trigger)
- .toHaveBeenCalledWith('pgadmin-sqleditor:loading-icon:hide');
- done();
- }, 0);
- });
- };
-
- let shouldUpdateLoadingIconMessageTestCase = ()=>{
- it('should update the loading icon message', (done) => {
- setTimeout(() => {
- expect(sqlEditorMock.trigger)
- .toHaveBeenCalledWith(
- 'pgadmin-sqleditor:loading-icon:message',
- 'Loading data from the database server and rendering...'
- );
- done();
- }, 0);
- });
- };
-
- let addNewEntryToHistoryTestCase = ()=>{
- it('should add new entry to history and update the Messages tab and clear the result grid', (done) => {
- setTimeout(() => {
- expect(sqlEditorMock.update_msg_history)
- .toHaveBeenCalledWith(
- false,
- 'Some interesting result',
- true
- );
- done();
- }, 0);
- });
- };
-
- let shouldEnableToolsButtonTestCase = ()=>{
- it('should enable the tool buttons', (done) => {
- setTimeout(
- () => {
- expect(sqlEditorMock.disable_tool_buttons).toHaveBeenCalledWith(false);
- done();
- }, 0);
- });
- };
-
- let addNewEntryToHistoryExecutionCancelTestCase = ()=> {
- it('should add new entry to history, add cancellation message to Messages tab and clear the result grid', (done) => {
- setTimeout(() => {
- expect(sqlEditorMock.update_msg_history)
- .toHaveBeenCalledWith(
- false,
- 'Execution Cancelled!',
- true
- );
- done();
- }, 0);
- });
- };
-
- let shouldResetLastQueryInformationTestCase = ()=> {
- it('should reset last query information', (done) => {
- setTimeout(
- () => {
- expect(sqlEditorMock.resetQueryHistoryObject)
- .toHaveBeenCalledWith(sqlEditorMock);
- done();
- }, 0);
- });
- };
-
- let shouldNotAddNewEntryTestCase = ()=> {
- it('should not add new entry to history and update the Messages tab', (done) => {
- updateHistoryNotCalled(done);
- });
- };
-
- let shouldNotHighlightErrorTestCase = ()=>{
- it('should not highlight the error in the SQL panel', (done) => {
- setTimeout(
- () => {
- expect(sqlEditorMock._highlight_error).not
- .toHaveBeenCalled();
- done();
- }, 0);
- });
- };
-
- let shouldHighlightErrorTestCase = (msg)=>{
- it('should highlight the error in the SQL panel', (done) => {
- setTimeout(
- () => {
- expect(sqlEditorMock._highlight_error)
- .toHaveBeenCalledWith(msg);
- done();
- }, 0);
- });
- };
-
- let shouldLoginNotDisplayedTestCase = ()=>{
- it('should login is not displayed', (done) => {
- pgaLoginNotCalled(done);
- });
- };
-
- let shouldNotDisplayPGALoginTestCase = ()=>{
- it('should not display pga login', (done) => {
- pgaLoginNotCalled(done);
- });
- };
-
- let shouldLoginDisplayedTestCase = ()=>{
- it('should login is displayed', (done) => {
- setTimeout(
- () => {
- expect(userManagementMock.pgaLogin)
- .toHaveBeenCalled();
- done();
- }, 0);
- });
- };
-
- let addNewEntryToHistoryUpdateMsgTestCase = (msg)=> {
- it('should add new entry to history and update the Messages tab', (done) => {
- setTimeout(
- () => {
- expect(sqlEditorMock.update_msg_history)
- .toHaveBeenCalledWith(false, msg);
- done();
- }, 0);
- });
- };
-
- let shouldNotSaveStateTestCase = ()=>{
- it('should not save the state', (done) => {
- setTimeout(() => {
- expect(sqlEditorMock.saveState).not.toHaveBeenCalled();
- done();
- }, 0);
- });
- };
-
- let shouldSaveStateTestCase = ()=> {
- it('should save the state', (done) => {
- setTimeout(() => {
- expect(sqlEditorMock.saveState).toHaveBeenCalledWith(
- 'check_data_changes_to_execute_query',
- ['']
- );
- done();
- }, 0);
- });
- };
-
- let shouldDisableCancelButtonTestCase = ()=> {
- it('should disable the cancel button', (done) => {
- cancelButtonNotCalled(done);
- });
- };
-
- let whenQueryIsStillRunningTestCases = ()=> {
- describe('when query is still running', () => {
- context('when no additional information is returned', () => {
- beforeEach(() => {
- let response = {
- data: {status: 'Busy'},
- };
-
- networkMock.onGet('/sqleditor/query_tool/poll/123').reply(200, response);
- executeQuery.poll();
- });
-
- setFlagQueryIsRunningTestCase();
- shouldNotUpdateHistoryMessageTestCase();
- callPoolingTestCase();
- });
-
- context('when additional information is returned', () => {
- beforeEach(() => {
- let response = {
- data: {
- status: 'Busy',
- result: 'Some important result',
- },
- };
-
- networkMock.onGet('/sqleditor/query_tool/poll/123').reply(200, response);
- executeQuery.poll();
- });
-
- setFlagQueryIsRunningTestCase();
- updateHistoryMessageTestCase();
- callPoolingTestCase();
- });
- });
- };
-
- let whenQueryWasCancelledTestCases = ()=> {
- describe('when query was cancelled', () => {
- beforeEach(() => {
- let response = {
- data: {status: 'Cancel'},
- };
- networkMock.onGet('/sqleditor/query_tool/poll/123').reply(200, response);
-
- executeQuery.poll();
- });
-
- shouldHideLoadingIconTestCase();
- addNewEntryToHistoryExecutionCancelTestCase();
- });
- };
-
- describe('#poll', () => {
- let response;
-
- beforeEach(() => {
- sqlEditorMock.POLL_FALLBACK_TIME = () => {
- return 0;
- };
-
- executeQuery.delayedPoll = jasmine.createSpy('ExecuteQuery.delayedPoll');
- });
-
- context('when SQLEditor is the query tool', () => {
- beforeEach(() => {
- sqlEditorMock.is_query_tool = true;
- });
-
- describe('when server answer with success', () => {
- describe('when query was successful', () => {
- beforeEach(() => {
- response = {
- data: {status: 'Success', notifies: [{'pid': 100}]},
- };
- networkMock.onGet('/sqleditor/query_tool/poll/123').reply(200, response);
-
- executeQuery.poll();
- });
-
- shouldUpdateLoadingIconMessageTestCase();
-
- it('should render the results', (done) => {
- setTimeout(() => {
- expect(sqlEditorMock.call_render_after_poll)
- .toHaveBeenCalledWith({status: 'Success', notifies: [{'pid': 100}]});
- done();
- }, 0);
- });
-
- it('should update the notification panel', (done) => {
- setTimeout(() => {
- expect(sqlEditorMock.update_notifications)
- .toHaveBeenCalledWith([{'pid': 100}]);
- done();
- }, 0);
- });
- });
-
- describe('when query was successful but in transaction block', () => {
- beforeEach(() => {
- response = {
- data: {status: 'Success', notifies: [{'pid': 100}], transaction_status: 2},
- };
- networkMock.onGet('/sqleditor/query_tool/poll/123').reply(200, response);
-
- executeQuery.poll();
- });
-
- it('enable the transaction buttons', (done) => {
- setTimeout(
- () => {
- expect(sqlEditorMock.disable_transaction_buttons)
- .toHaveBeenCalledWith(false);
- done();
- }, 0);
- });
- });
-
- describe('when query was successful but not in transaction block', () => {
- beforeEach(() => {
- response = {
- data: {status: 'Success', notifies: [{'pid': 100}], transaction_status: 0},
- };
- networkMock.onGet('/sqleditor/query_tool/poll/123').reply(200, response);
-
- executeQuery.poll();
- });
-
- it('disable the transaction buttons', (done) => {
- setTimeout(
- () => {
- expect(sqlEditorMock.disable_transaction_buttons)
- .toHaveBeenCalledWith(true);
- done();
- }, 0);
- });
- });
-
- whenQueryIsStillRunningTestCases();
-
- describe('when the application lost connection with the database', () => {
- beforeEach(beforeEachNotConnected);
-
- shouldHideLoadingIconTestCase();
- addNewEntryToHistoryTestCase();
- shouldEnableToolsButtonTestCase();
- });
-
- whenQueryWasCancelledTestCases();
- });
-
- describe('when an error occur', () => {
- let errorMessageJson = {
- errormsg: 'Some error in JSON',
- };
- let errorMessageText = 'Some plain text error';
-
- describe('when the connection to the server was lost', () => {
- describe('when JSON response is available', () => {
- describe('when login is not required', () => {
- beforeEach(() => {
- userManagementMock.isPgaLoginRequired.and.returnValue(false);
- response = {responseJSON: errorMessageJson};
- networkMock.onGet('/sqleditor/query_tool/poll/123').reply(401, response);
-
- executeQuery.poll();
- });
-
- shouldHideLoadingIconTestCase();
- shouldResetLastQueryInformationTestCase();
- shouldHighlightErrorTestCase('Some error in JSON');
- addNewEntryToHistoryUpdateMsgTestCase('Some error in JSON');
- shouldEnableToolsButtonTestCase();
- shouldLoginNotDisplayedTestCase();
- });
-
- describe('when login is required', () => {
- beforeEach(() => {
- userManagementMock.isPgaLoginRequired.and.returnValue(true);
- response = {responseJSON: errorMessageJson};
- networkMock.onGet('/sqleditor/query_tool/poll/123').reply(401, response);
-
- executeQuery.poll();
- });
-
- shouldHideLoadingIconTestCase();
- shouldResetLastQueryInformationTestCase();
- shouldNotHighlightErrorTestCase();
- shouldNotAddNewEntryTestCase();
- shouldEnableToolsButtonTestCase();
- shouldLoginDisplayedTestCase();
- });
- });
-
- describe('when no JSON response is available', () => {
- describe('when login is not required', () => {
- beforeEach(() => {
- userManagementMock.isPgaLoginRequired.and.returnValue(false);
- response = {
- errormsg: errorMessageText,
- };
- networkMock.onGet('/sqleditor/query_tool/poll/123').reply(401, response);
-
- executeQuery.poll();
- });
-
- shouldHideLoadingIconTestCase();
- shouldResetLastQueryInformationTestCase();
- shouldHighlightErrorTestCase('Some plain text error');
- addNewEntryToHistoryUpdateMsgTestCase('Some plain text error');
- shouldEnableToolsButtonTestCase();
- shouldLoginNotDisplayedTestCase();
- });
-
- describe('when login is required', () => {
- beforeEach(() => {
- userManagementMock.isPgaLoginRequired.and.returnValue(true);
- response = {
- errormsg: errorMessageText,
- };
- networkMock.onGet('/sqleditor/query_tool/poll/123').reply(401, response);
-
- executeQuery.poll();
- });
-
- shouldHideLoadingIconTestCase();
- shouldResetLastQueryInformationTestCase();
- shouldNotHighlightErrorTestCase();
- shouldNotAddNewEntryTestCase();
- shouldEnableToolsButtonTestCase();
- shouldLoginDisplayedTestCase();
-
- });
- });
-
- describe('when cannot reach the Python Server', () => {
- beforeEach(beforeEachPythonServer);
-
- shouldHideLoadingIconTestCase();
- shouldResetLastQueryInformationTestCase();
- shouldNotHighlightErrorTestCase();
- addNewEntryToHistoryUpdateMsgTestCase('Not connected to the server or the connection to the server has been closed.');
- shouldEnableToolsButtonTestCase();
- shouldLoginNotDisplayedTestCase();
- });
- });
- });
- });
-
- context('when SQLEditor is NOT the query tool', () => {
- beforeEach(() => {
- sqlEditorMock.is_query_tool = false;
- });
-
- describe('when server answer with success', () => {
- describe('when query was successful', () => {
- beforeEach(() => {
- response = {
- data: {status: 'Success'},
- };
- networkMock.onGet('/sqleditor/query_tool/poll/123').reply(200, response);
-
- executeQuery.poll();
- });
-
- shouldUpdateLoadingIconMessageTestCase();
-
- it('should render the results', (done) => {
- setTimeout(() => {
- expect(sqlEditorMock.call_render_after_poll)
- .toHaveBeenCalledWith({status: 'Success'});
- done();
- }, 0);
- });
- });
-
- whenQueryIsStillRunningTestCases();
-
- describe('when the application lost connection with the database', () => {
- beforeEach(beforeEachNotConnected);
-
- shouldHideLoadingIconTestCase();
- addNewEntryToHistoryTestCase();
-
- it('should NOT enable the tool buttons', (done) => {
- disableToolButtonsNotCalled(done);
- });
-
- it('should NOT disable the cancel button', (done) => {
- cancelButtonNotCalled(done);
- });
- });
-
- whenQueryWasCancelledTestCases();
- });
-
- describe('when an error occur', () => {
- let errorMessageJson = {
- errormsg: 'Some error in JSON',
- };
- let errorMessageText = 'Some plain text error';
- let res;
-
- describe('when the connection to the server was lost', () => {
- describe('when JSON response is available', () => {
- beforeEach(() => {
- res = {responseJSON: errorMessageJson};
- networkMock.onGet('/sqleditor/query_tool/poll/123').reply(401, res);
-
- executeQuery.poll();
- });
-
- shouldHideLoadingIconTestCase();
- shouldResetLastQueryInformationTestCase();
- shouldHighlightErrorTestCase('Some error in JSON');
- addNewEntryToHistoryUpdateMsgTestCase('Some error in JSON');
-
- it('should enable the tool buttons', (done) => {
- disableToolButtonsNotCalled(done);
- });
-
- shouldDisableCancelButtonTestCase();
- });
- describe('when no JSON response is available', () => {
- beforeEach(() => {
- res = {errormsg: errorMessageText};
- networkMock.onGet('/sqleditor/query_tool/poll/123').reply(401, res);
-
- executeQuery.poll();
- });
-
- shouldHideLoadingIconTestCase();
- shouldResetLastQueryInformationTestCase();
- shouldHighlightErrorTestCase('Some plain text error');
- addNewEntryToHistoryUpdateMsgTestCase('Some plain text error');
-
- it('should not enable the tool buttons', (done) => {
- disableToolButtonsNotCalled(done);
- });
-
- });
-
- describe('when cannot reach the Python Server', () => {
- beforeEach(beforeEachPythonServer);
-
- shouldHideLoadingIconTestCase();
- shouldResetLastQueryInformationTestCase();
- shouldNotHighlightErrorTestCase();
- addNewEntryToHistoryUpdateMsgTestCase('Not connected to the server or the connection to the server has been closed.');
-
- it('should enable the tool buttons', (done) => {
- disableToolButtonsNotCalled(done);
- });
-
- shouldDisableCancelButtonTestCase();
- });
- });
- });
- });
- });
-
- describe('#execute', () => {
- let response;
-
- beforeEach(() => {
- response = {
- 'info': '',
- 'errormsg': '',
- 'data': {
- 'status': true,
- 'can_edit': false,
- 'info_notifier_timeout': 5,
- 'result': '2',
- 'can_filter': false,
- },
- 'result': null,
- 'success': 1,
- };
- });
-
- context('when the SQL statement is empty', () => {
- it('should return without executing', (done) => {
- let wasNetworkCalled = false;
- networkMock.onAny('/sqleditor/query_tool/start/123').reply(() => {
- wasNetworkCalled = true;
- });
-
- executeQuery.execute('', {});
-
- setTimeout(() => {
- expect(wasNetworkCalled).toEqual(false);
- done();
- }, 0);
- });
- });
-
- context('when the SQL statement is not empty', () => {
- let pollSpy;
-
- beforeEach(() => {
- sqlEditorMock.gridView = {};
- sqlEditorMock.gridView.query_tool_obj = jasmine.createSpyObj(
- 'QueryToolObject',
- ['removeLineClass']
- );
-
- $('body').append(
- '' +
- ' ' +
- ' ' +
- '
'
- );
- });
-
- afterEach(function () {
- $('body').remove('#test-id');
- });
-
- describe('before the backend request', () => {
- beforeEach(() => {
- jasmine.clock().install();
- jasmine.clock().mockDate(startTime);
- jasmine.clock().tick(50);
- networkMock.onAny('/sqleditor/query_tool/start/123').reply(200, response);
- pollSpy = spyOn(executeQuery, 'poll');
- executeQuery.execute('some sql query', '');
- });
-
- afterEach(function () {
- jasmine.clock().uninstall();
- });
-
- it('should update loading text to "Running query"', () => {
- expect(sqlEditorMock.trigger)
- .toHaveBeenCalledWith(
- 'pgadmin-sqleditor:loading-icon:show',
- 'Running query...'
- );
- });
-
- it('disables the run query button', () => {
- let buttonFlash = $('#btn-flash');
-
- expect(buttonFlash.prop('disabled')).toEqual(true);
- });
-
- it('enable the cancel query button', () => {
- let buttonFlash = $('#btn-cancel-query');
-
- expect(buttonFlash.prop('disabled')).toEqual(false);
- });
-
- it('disable the query tool buttons', () => {
- expect(sqlEditorMock.disable_tool_buttons).toHaveBeenCalledWith(true);
- });
-
- it('initializes the polling flags', () => {
- expect(sqlEditorMock._init_polling_flags).toHaveBeenCalled();
- });
-
- it('save the query', () => {
- expect(sqlEditorMock.query).toEqual('some sql query');
- });
-
- it('reset the number of rows that were affected', () => {
- expect(sqlEditorMock.rows_affected).toEqual(0);
- });
-
- it('reset query start time', () => {
- expect(sqlEditorMock.query_start_time.getTime()).toEqual(startTime.getTime() + 50);
- });
- });
-
- describe('when HTTP return 200', () => {
- describe('when backend informs that query started successfully', () => {
- beforeEach(() => {
- networkMock.onPost('/sqleditor/query_tool/start/123?connect=1').reply(200, response);
- pollSpy = spyOn(executeQuery, 'delayedPoll');
- executeQuery.execute('some sql query', '', true);
- });
-
- it('should changes the loading message to "Waiting for the query to complete"', (done) => {
- setTimeout(() => {
- expect(sqlEditorMock.trigger).toHaveBeenCalledWith(
- 'pgadmin-sqleditor:loading-icon:message',
- 'Waiting for the query to complete...'
- );
- done();
- }, 0);
- });
-
- it('should update the can edit flag', (done) => {
- setTimeout(() => {
- expect(sqlEditorMock.can_edit).toEqual(false);
- done();
- }, 0);
- });
-
- it('should update the can filter flag', (done) => {
- setTimeout(() => {
- expect(sqlEditorMock.can_filter).toEqual(false);
- done();
- }, 0);
- });
-
- it('should update information notifier timeout', (done) => {
- setTimeout(() => {
- expect(sqlEditorMock.info_notifier_timeout).toEqual(5);
- done();
- }, 0);
- });
-
- it('should start polling', (done) => {
- setTimeout(() => {
- expect(pollSpy).toHaveBeenCalled();
- done();
- }, 0);
- });
- });
-
- describe('when explain plan is not empty', () => {
- it('should send the explain plan informatioon through the wire', (done) => {
- networkMock.onAny('/sqleditor/query_tool/start/123').reply((config) => {
- setTimeout(() => {
- expect(config.data).toEqual(JSON.stringify({
- sql: 'some sql query',
- explain_plan: {
- buffers: true,
- analyze: false,
- timing: true,
- summary: false,
- },
- }));
-
- done();
- }, 0);
- return [200, ''];
- });
- pollSpy = spyOn(executeQuery, 'delayedPoll');
- executeQuery.execute('some sql query', {
- buffers: true,
- analyze: false,
- timing: true,
- summary: false,
- });
- });
-
-
- });
-
- describe('when backend informs that there was a problem with the query', () => {
- beforeEach(() => {
- response.data.status = false;
- response.data.result = 'something went wrong';
- networkMock.onAny('/sqleditor/query_tool/start/123').reply(200, response);
- pollSpy = spyOn(executeQuery, 'poll');
- executeQuery.execute('some sql query', '');
- });
-
- shouldHideLoadingIconTestCase();
- shouldEnableToolsButtonTestCase();
-
- it('update the history tab with the result message', (done) => {
- setTimeout(() => {
- expect(sqlEditorMock.update_msg_history).toHaveBeenCalledWith(false, 'something went wrong');
- done();
- }, 0);
- });
-
- it('highlight the error in the editor', (done) => {
- setTimeout(() => {
- expect(sqlEditorMock._highlight_error).toHaveBeenCalledWith('something went wrong');
- done();
- }, 0);
- });
-
- it('should not start polling', (done) => {
- setTimeout(() => {
- expect(pollSpy).not.toHaveBeenCalled();
- done();
- }, 0);
- });
- });
-
- describe('when there is a marker set in the grid', () => {
- let markerClearSpy;
- beforeEach(() => {
- sqlEditorMock.gridView.marker = jasmine.createSpyObj(
- 'GridViewMarker',
- ['clear']
- );
- markerClearSpy = sqlEditorMock.gridView.marker.clear;
- networkMock.onAny('/sqleditor/query_tool/start/123').reply(200, response);
- pollSpy = spyOn(executeQuery, 'poll');
- executeQuery.execute('some sql query', '');
- });
-
- it('should call clear function on marker', (done) => {
- setTimeout(() => {
- expect(markerClearSpy).toHaveBeenCalled();
- done();
- }, 0);
- });
-
- it('should removes the marker', (done) => {
- setTimeout(() => {
- expect(sqlEditorMock.gridView.marker).toEqual(null);
- done();
- }, 0);
- });
-
- it('should remove CSS classes from the editor', (done) => {
- setTimeout(() => {
- expect(sqlEditorMock.gridView.query_tool_obj.removeLineClass)
- .toHaveBeenCalledWith(sqlEditorMock.marked_line_no, 'wrap', 'CodeMirror-activeline-background');
- done();
- }, 0);
- });
- });
- });
-
- describe('when cannot reach the Python Server', () => {
- beforeEach(() => {
- networkMock.onAny('/sqleditor/query_tool/start/123').reply(500, undefined);
-
-
- executeQuery.execute('some sql query', '');
- });
-
- shouldHideLoadingIconTestCase();
- shouldNotHighlightErrorTestCase();
- addNewEntryToHistoryUpdateMsgTestCase('Not connected to the server or the connection to the server has been closed.');
- shouldEnableToolsButtonTestCase();
- });
-
- describe('when error is returned by the server', () => {
- describe('when login is not required', () => {
- beforeEach(() => {
- userManagementMock.isPgaLoginRequired.and.returnValue(false);
- response.errormsg = 'some error message';
- networkMock.onAny('/sqleditor/query_tool/start/123').reply(500, response);
-
-
- executeQuery.execute('some sql query', '');
- });
-
- shouldHideLoadingIconTestCase();
- shouldNotHighlightErrorTestCase();
- addNewEntryToHistoryUpdateMsgTestCase('some error message');
- shouldEnableToolsButtonTestCase();
- shouldNotSaveStateTestCase();
- shouldNotDisplayPGALoginTestCase();
- });
- describe('when login is required', () => {
- beforeEach(() => {
- userManagementMock.isPgaLoginRequired.and.returnValue(true);
- response.errormsg = 'some error message';
- networkMock.onAny('/sqleditor/query_tool/start/123').reply(500, response);
-
-
- executeQuery.execute('some sql query', '');
- });
-
- shouldHideLoadingIconTestCase();
- shouldNotHighlightErrorTestCase();
- addNewEntryToHistoryUpdateMsgTestCase('some error message');
- shouldEnableToolsButtonTestCase();
- shouldSaveStateTestCase();
- shouldLoginDisplayedTestCase();
- });
- describe('when a new transaction is not required', () => {
- beforeEach(() => {
- isNewTransactionRequiredMock.and.returnValue(false);
- response.errormsg = 'some error message';
- networkMock.onAny('/sqleditor/query_tool/start/123').reply(500, response);
-
-
- executeQuery.execute('some sql query', '');
- });
-
- shouldHideLoadingIconTestCase();
- shouldNotHighlightErrorTestCase();
- addNewEntryToHistoryUpdateMsgTestCase('some error message');
- shouldEnableToolsButtonTestCase();
- shouldNotSaveStateTestCase();
- shouldNotDisplayPGALoginTestCase();
-
- it('should not initialize a new transaction', (done) => {
- setTimeout(() => {
- expect(sqlEditorMock.initTransaction).not.toHaveBeenCalled();
- done();
- }, 0);
- });
- });
-
- describe('when a new transaction is required', () => {
- beforeEach(() => {
- isNewTransactionRequiredMock.and.returnValue(true);
- response.errormsg = 'some error message';
- networkMock.onAny('/sqleditor/query_tool/start/123').reply(500, response);
-
- executeQuery.execute('some sql query', '');
- });
-
- shouldHideLoadingIconTestCase();
- shouldNotHighlightErrorTestCase();
- addNewEntryToHistoryUpdateMsgTestCase('some error message');
- shouldEnableToolsButtonTestCase();
- shouldSaveStateTestCase();
- shouldNotDisplayPGALoginTestCase();
-
- it('should initialize a new transaction', (done) => {
- setTimeout(() => {
- expect(sqlEditorMock.initTransaction).toHaveBeenCalled();
- done();
- }, 0);
- });
- });
- describe('when connection to database is lost', () => {
- beforeEach(() => {
- isNewTransactionRequiredMock.and.returnValue(false);
- response.info = 'CONNECTION_LOST';
- networkMock.onAny('/sqleditor/query_tool/start/123').reply(503, response);
-
- executeQuery.execute('some sql query', '');
- });
-
- shouldSaveStateTestCase();
-
- it('calls handle_connection_lost', (done) => {
- setTimeout(() => {
- expect(sqlEditorMock.handle_connection_lost).toHaveBeenCalled();
- done();
- }, 0);
- });
- });
- });
-
- });
- });
-});
-
diff --git a/web/regression/javascript/sqleditor/filter_dialog_specs.js b/web/regression/javascript/sqleditor/filter_dialog_specs.js
deleted file mode 100644
index 95abd8837..000000000
--- a/web/regression/javascript/sqleditor/filter_dialog_specs.js
+++ /dev/null
@@ -1,28 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////////////////
-import filterDialog from 'sources/sqleditor/filter_dialog';
-
-describe('filterDialog', () => {
- describe('filterDialog', () => {
- describe('when using filter dialog', () => {
- beforeEach(() => {
- spyOn(filterDialog, 'dialog');
- });
-
- it('it should be defined as function', function() {
- expect(filterDialog.dialog).toBeDefined();
- });
-
- it('it should call without proper handler', () => {
- expect(filterDialog.dialog).not.toHaveBeenCalledWith({});
- });
-
- });
- });
-});
diff --git a/web/regression/javascript/sqleditor/keyboard_shortcuts_spec.js b/web/regression/javascript/sqleditor/keyboard_shortcuts_spec.js
deleted file mode 100644
index 67595f215..000000000
--- a/web/regression/javascript/sqleditor/keyboard_shortcuts_spec.js
+++ /dev/null
@@ -1,733 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////////////////
-
-import * as keyboardShortcuts from 'sources/keyboard_shortcuts';
-import {queryToolActions} from 'sources/sqleditor/query_tool_actions';
-import gettext from 'sources/gettext';
-
-describe('the keyboard shortcuts', () => {
- const F1_KEY = 112,
- F5_KEY = 116,
- F6_KEY = 117,
- F7_KEY = 118,
- F8_KEY = 119,
- PERIOD_KEY = 190,
- FWD_SLASH_KEY = 191,
- C1_KEY = 49;
-
- let sqlEditorControllerSpy, event, queryToolActionsSpy;
- beforeEach(() => {
- event = {
- shift: false,
- which: undefined,
- preventDefault: jasmine.createSpy('preventDefault'),
- cancelBubble: false,
- stopPropagation: jasmine.createSpy('stopPropagation'),
- stopImmediatePropagation: jasmine.createSpy('stopImmediatePropagation'),
- };
-
- let gridView = {
- query_tool_obj: {
- getSelection: jasmine.createSpy('getSelection'),
- getValue: jasmine.createSpy('getValue'),
- },
- };
-
- sqlEditorControllerSpy = jasmine.createSpyObj('SqlEditorController', [
- 'isQueryRunning',
- 'execute',
- ]);
-
- sqlEditorControllerSpy.gridView = gridView;
-
- sqlEditorControllerSpy.preferences = {
- execute_query: {
- alt: false,
- shift: false,
- control: false,
- key: {
- key_code: F5_KEY,
- },
- },
- explain_query: {
- alt: false,
- shift: false,
- control: false,
- key: {
- key_code: F7_KEY,
- },
- },
- explain_analyze_query: {
- alt: false,
- shift: true,
- control: false,
- key: {
- key_code: F7_KEY,
- },
- },
- download_results: {
- alt: false,
- shift: false,
- control: false,
- key: {
- key_code: F8_KEY,
- },
- },
- move_next: {
- alt: false,
- shift: false,
- control: false,
- key: {
- key_code: null,
- },
- },
- move_previous: {
- alt: false,
- shift: false,
- control: false,
- key: {
- key_code: null,
- },
- },
- commit_transaction: {
- alt: false,
- shift: true,
- control: true,
- key: {
- key_code: 'm',
- },
- },
- rollback_transaction: {
- alt: false,
- shift: true,
- control: true,
- key: {
- key_code: 'r',
- },
- },
- save_data: {
- alt : false,
- shift: false,
- control: false,
- key: {
- key_code: F6_KEY,
- },
- },
- };
-
- sqlEditorControllerSpy.macros = [
- {
- alt: false,
- control: true,
- id: 1,
- key: '1',
- key_code: C1_KEY,
- key_label: 'Ctrl + 1',
- name: 'C1',
- sql: 'Select 1;',
- },
- ];
-
- queryToolActionsSpy = jasmine.createSpyObj(queryToolActions, [
- 'explainAnalyze',
- 'explain',
- 'download',
- 'commentBlockCode',
- 'commentLineCode',
- 'uncommentLineCode',
- 'executeQuery',
- 'executeCommit',
- 'executeRollback',
- 'saveDataChanges',
- 'executeMacro',
- ]);
- });
-
- let doesNothingTestCase = ()=> {
- it('does nothing', () => {
- keyboardShortcuts.processEventQueryTool(
- sqlEditorControllerSpy, queryToolActionsSpy, event
- );
-
- expect(queryToolActionsSpy.commentLineCode).not.toHaveBeenCalled();
- });
- };
-
- let beforeEachWindows = ()=> {
- windowsKeysSetup();
- event.which = FWD_SLASH_KEY;
- event.shiftKey = true;
- keyboardShortcuts.processEventQueryTool(
- sqlEditorControllerSpy, queryToolActionsSpy, event
- );
- };
-
- let beforeEachMAC = ()=> {
- macKeysSetup();
- event.which = FWD_SLASH_KEY;
- event.shiftKey = true;
- keyboardShortcuts.processEventQueryTool(
- sqlEditorControllerSpy, queryToolActionsSpy, event
- );
- };
-
-
- describe('when the key is not handled by the function', function () {
-
- beforeEach(() => {
- event.which = F1_KEY;
- keyboardShortcuts.processEventQueryTool(
- sqlEditorControllerSpy, queryToolActionsSpy, event
- );
- });
-
- it('should allow event to propagate', () => {
- expect(event.preventDefault).not.toHaveBeenCalled();
- });
- });
-
- describe('F5', () => {
- describe('when there is no query already running', () => {
- beforeEach(() => {
- event.keyCode = F5_KEY;
- event.altKey = false;
- event.shiftKey = false;
- event.ctrlKey = false;
- keyboardShortcuts.processEventQueryTool(
- sqlEditorControllerSpy, queryToolActionsSpy, event
- );
- });
-
- it('should execute the query', () => {
- expect(queryToolActionsSpy.executeQuery).toHaveBeenCalledWith(sqlEditorControllerSpy);
- });
-
- it('should stop event propagation', () => {
- expect(event.preventDefault).toHaveBeenCalled();
- });
- });
-
- describe('when the query is already running', () => {
- it('does nothing', () => {
- event.keyCode = F5_KEY;
- event.altKey = false;
- event.shiftKey = false;
- event.ctrlKey = false;
- sqlEditorControllerSpy.isQueryRunning.and.returnValue(true);
-
- keyboardShortcuts.processEventQueryTool(
- sqlEditorControllerSpy, queryToolActionsSpy, event
- );
-
- expect(queryToolActionsSpy.executeQuery).not.toHaveBeenCalled();
- });
- });
- });
-
- describe('F6', () => {
- describe('when there is not a query already running', () => {
- beforeEach(() => {
- event.which = F6_KEY;
- event.altKey = false;
- event.shiftKey = false;
- event.ctrlKey = false;
- keyboardShortcuts.processEventQueryTool(
- sqlEditorControllerSpy, queryToolActionsSpy, event
- );
- });
-
- it('should save the changed data', () => {
- expect(queryToolActionsSpy.saveDataChanges).toHaveBeenCalledWith(sqlEditorControllerSpy);
- });
-
- expectEventPropagationToStop();
- });
-
- describe('when the query is already running', () => {
- it('does nothing', () => {
- event.keyCode = F6_KEY;
- event.altKey = false;
- event.shiftKey = false;
- event.ctrlKey = false;
- sqlEditorControllerSpy.isQueryRunning.and.returnValue(true);
-
- keyboardShortcuts.processEventQueryTool(
- sqlEditorControllerSpy, queryToolActionsSpy, event
- );
-
- expect(queryToolActionsSpy.saveDataChanges).not.toHaveBeenCalled();
- });
- });
- });
-
- describe('F7', () => {
- describe('when there is not a query already running', () => {
- beforeEach(() => {
- event.which = F7_KEY;
- event.altKey = false;
- event.shiftKey = false;
- event.ctrlKey = false;
- keyboardShortcuts.processEventQueryTool(
- sqlEditorControllerSpy, queryToolActionsSpy, event
- );
- });
-
- it('should explain the query plan', () => {
- expect(queryToolActionsSpy.explain).toHaveBeenCalledWith(sqlEditorControllerSpy);
- });
-
- expectEventPropagationToStop();
- });
-
- describe('when the query is already running', () => {
- it('does nothing', () => {
- event.keyCode = F7_KEY;
- event.altKey = false;
- event.shiftKey = false;
- event.ctrlKey = false;
- sqlEditorControllerSpy.isQueryRunning.and.returnValue(true);
-
- keyboardShortcuts.processEventQueryTool(
- sqlEditorControllerSpy, queryToolActionsSpy, event
- );
-
- expect(queryToolActionsSpy.explain).not.toHaveBeenCalled();
- });
- });
- });
-
- describe('Shift+F7', () => {
- describe('when there is not a query already running', () => {
- beforeEach(() => {
- event.shiftKey = true;
- event.which = F7_KEY;
- event.altKey = false;
- event.ctrlKey = false;
- keyboardShortcuts.processEventQueryTool(
- sqlEditorControllerSpy, queryToolActionsSpy, event
- );
- });
-
- it('should analyze explain the query plan', () => {
- expect(queryToolActionsSpy.explainAnalyze).toHaveBeenCalledWith(sqlEditorControllerSpy);
- });
-
- expectEventPropagationToStop();
- });
-
- describe('when the query is already running', () => {
- it('does nothing', () => {
- event.shiftKey = true;
- event.which = F7_KEY;
- event.altKey = false;
- event.ctrlKey = false;
-
- sqlEditorControllerSpy.isQueryRunning.and.returnValue(true);
-
- keyboardShortcuts.processEventQueryTool(
- sqlEditorControllerSpy, queryToolActionsSpy, event
- );
-
- expect(queryToolActionsSpy.explainAnalyze).not.toHaveBeenCalled();
- });
- });
- });
-
- describe('F8', () => {
- describe('when there is not a query already running', () => {
- beforeEach(() => {
- event.which = F8_KEY;
- event.altKey = false;
- event.shiftKey = false;
- event.ctrlKey = false;
-
- keyboardShortcuts.processEventQueryTool(
- sqlEditorControllerSpy, queryToolActionsSpy, event
- );
- });
-
- it('should download the query results as a CSV', () => {
- expect(queryToolActionsSpy.download).toHaveBeenCalled();
- });
-
- it('should stop event propagation', () => {
- expect(event.preventDefault).toHaveBeenCalled();
- });
- });
-
- describe('when the query is already running', () => {
- it('does nothing', () => {
- event.keyCode = F8_KEY;
- event.altKey = false;
- event.shiftKey = false;
- event.ctrlKey = false;
-
- sqlEditorControllerSpy.isQueryRunning.and.returnValue(true);
-
- keyboardShortcuts.processEventQueryTool(
- sqlEditorControllerSpy, queryToolActionsSpy, event
- );
-
- expect(queryToolActionsSpy.download).not.toHaveBeenCalled();
- });
- });
- });
-
- describe('inlineComment', () => {
- describe('when there is not a query already running', () => {
- describe('and the system is a Mac', () => {
- beforeEach(() => {
- macKeysSetup();
- event.which = FWD_SLASH_KEY;
- keyboardShortcuts.processEventQueryTool(
- sqlEditorControllerSpy, queryToolActionsSpy, event
- );
- });
-
- it('should comment the line', () => {
- expect(queryToolActionsSpy.commentLineCode).toHaveBeenCalledWith(sqlEditorControllerSpy);
- });
-
- expectEventPropagationToStop();
- });
-
- describe('and the system is Windows', () => {
- beforeEach(() => {
- windowsKeysSetup();
- event.which = FWD_SLASH_KEY;
- keyboardShortcuts.processEventQueryTool(
- sqlEditorControllerSpy, queryToolActionsSpy, event
- );
- });
-
- it('should comment the line', () => {
- expect(queryToolActionsSpy.commentLineCode).toHaveBeenCalledWith(sqlEditorControllerSpy);
- });
-
- expectEventPropagationToStop();
- });
- });
-
- describe('when the query is already running', () => {
- beforeEach(() => {
- sqlEditorControllerSpy.isQueryRunning.and.returnValue(true);
- });
- describe('and the system is a Mac', () => {
- beforeEach(() => {
- macKeysSetup();
- event.which = FWD_SLASH_KEY;
- });
-
- doesNothingTestCase();
- });
-
- describe('and the system is a Windows', () => {
- beforeEach(() => {
- windowsKeysSetup();
- event.which = FWD_SLASH_KEY;
- });
-
- doesNothingTestCase();
- });
- });
- });
-
- describe('inlineUncomment', () => {
- describe('when there is not a query already running', () => {
- describe('and the system is a mac', () => {
- beforeEach(() => {
- macKeysSetup();
- event.which = PERIOD_KEY;
- keyboardShortcuts.processEventQueryTool(
- sqlEditorControllerSpy, queryToolActionsSpy, event
- );
- });
-
- it('should uncomment the line', () => {
- expect(queryToolActionsSpy.uncommentLineCode).toHaveBeenCalledWith(sqlEditorControllerSpy);
- });
-
- expectEventPropagationToStop();
- });
- describe('and the system is a windows', () => {
- beforeEach(() => {
- windowsKeysSetup();
- event.which = PERIOD_KEY;
- keyboardShortcuts.processEventQueryTool(
- sqlEditorControllerSpy, queryToolActionsSpy, event
- );
- });
-
- it('should uncomment the line', () => {
- expect(queryToolActionsSpy.uncommentLineCode).toHaveBeenCalledWith(sqlEditorControllerSpy);
- });
-
- expectEventPropagationToStop();
- });
- });
-
- describe('when the query is already running', () => {
- beforeEach(() => {
- sqlEditorControllerSpy.isQueryRunning.and.returnValue(true);
- });
- describe('and the system is a Mac', () => {
- beforeEach(() => {
- macKeysSetup();
- event.which = PERIOD_KEY;
- });
-
- doesNothingTestCase();
- });
- describe('and the system is a Windows', () => {
- beforeEach(() => {
- windowsKeysSetup();
- event.which = PERIOD_KEY;
- });
-
- doesNothingTestCase();
- });
- });
- });
-
- describe('blockComment', () => {
- describe('when there is not a query already running', () => {
- describe('and the system is a Mac', () => {
- beforeEach(beforeEachMAC);
-
- it('should comment out the block selection', () => {
- expect(queryToolActionsSpy.commentBlockCode).toHaveBeenCalledWith(sqlEditorControllerSpy);
- });
-
- expectEventPropagationToStop();
- });
- });
-
- describe('when there is not a query already running', () => {
- describe('and the system is a Windows', () => {
- beforeEach(beforeEachWindows);
-
- it('should comment out the block selection', () => {
- expect(queryToolActionsSpy.commentBlockCode).toHaveBeenCalledWith(sqlEditorControllerSpy);
- });
-
- expectEventPropagationToStop();
- });
- });
-
- describe('when there is a query already running', () => {
- beforeEach(() => {
- sqlEditorControllerSpy.isQueryRunning.and.returnValue(true);
- });
- describe('and the system is a Mac', () => {
- beforeEach(beforeEachMAC);
- it('does nothing', () => {
- expect(queryToolActionsSpy.commentBlockCode).not.toHaveBeenCalled();
- });
- });
- describe('and the system is a Windows', () => {
- beforeEach(beforeEachWindows);
- it('does nothing', () => {
- expect(queryToolActionsSpy.commentBlockCode).not.toHaveBeenCalled();
- });
- });
- });
- });
-
- describe('shortcut to text converters', ()=> {
- var shortcut = {
- alt: false,
- shift: false,
- control: false,
- key: {
- char: 'a',
- key_code: 65,
- },
- };
-
- it('shortcut_key',()=>{
- expect(keyboardShortcuts.shortcut_key(shortcut)).toEqual('A');
- });
-
- it('shortcut_accesskey_title',()=>{
- expect(keyboardShortcuts.shortcut_accesskey_title(
- 'Title', shortcut)).toEqual(gettext('Title (accesskey + A)'));
- });
-
- it('shortcut_title',()=>{
- shortcut.alt = true;
- shortcut.shift = false;
- shortcut.control = false;
- expect(keyboardShortcuts.shortcut_title(
- 'Title', shortcut)).toEqual(gettext('Title (Alt+A)'));
-
- shortcut.alt = false;
- shortcut.shift = true;
- shortcut.control = false;
- expect(keyboardShortcuts.shortcut_title(
- 'Title', shortcut)).toEqual(gettext('Title (Shift+A)'));
-
- shortcut.alt = false;
- shortcut.shift = false;
- shortcut.control = true;
- expect(keyboardShortcuts.shortcut_title(
- 'Title', shortcut)).toEqual(gettext('Title (Ctrl+A)'));
-
- shortcut.alt = true;
- shortcut.shift = true;
- shortcut.control = true;
- expect(keyboardShortcuts.shortcut_title(
- 'Title', shortcut)).toEqual(gettext('Title (Alt+Shift+Ctrl+A)'));
- });
- });
-
- describe('Shift+Ctrl+C', () => {
- describe('when there is not a query already running', () => {
- beforeEach(() => {
- event.shiftKey = true;
- event.which = 'm';
- event.altKey = false;
- event.ctrlKey = true;
- keyboardShortcuts.processEventQueryTool(
- sqlEditorControllerSpy, queryToolActionsSpy, event
- );
- });
-
- it('should commit the transaction', () => {
- expect(queryToolActionsSpy.executeCommit).toHaveBeenCalledWith(sqlEditorControllerSpy);
- });
-
- expectEventPropagationToStop();
- });
-
- describe('when the query is already running', () => {
- it('does nothing', () => {
- event.shiftKey = true;
- event.which = 'm';
- event.altKey = false;
- event.ctrlKey = true;
-
- sqlEditorControllerSpy.isQueryRunning.and.returnValue(true);
-
- keyboardShortcuts.processEventQueryTool(
- sqlEditorControllerSpy, queryToolActionsSpy, event
- );
-
- expect(queryToolActionsSpy.executeCommit).not.toHaveBeenCalled();
- });
- });
- });
-
- describe('Shift+Ctrl+R', () => {
- describe('when there is not a query already running', () => {
- beforeEach(() => {
- event.shiftKey = true;
- event.which = 'r';
- event.altKey = false;
- event.ctrlKey = true;
- keyboardShortcuts.processEventQueryTool(
- sqlEditorControllerSpy, queryToolActionsSpy, event
- );
- });
-
- it('should rollback the transaction', () => {
- expect(queryToolActionsSpy.executeRollback).toHaveBeenCalledWith(sqlEditorControllerSpy);
- });
-
- expectEventPropagationToStop();
- });
-
- describe('when the query is already running', () => {
- it('does nothing', () => {
- event.shiftKey = true;
- event.which = 'r';
- event.altKey = false;
- event.ctrlKey = true;
-
- sqlEditorControllerSpy.isQueryRunning.and.returnValue(true);
-
- keyboardShortcuts.processEventQueryTool(
- sqlEditorControllerSpy, queryToolActionsSpy, event
- );
-
- expect(queryToolActionsSpy.executeRollback).not.toHaveBeenCalled();
- });
- });
- });
-
- describe('Macro Ctrl + 1', () => {
- describe('when there is not a query already running', () => {
- beforeEach(() => {
- event.which = C1_KEY;
- event.altKey = false;
- event.shiftKey = false;
- event.ctrlKey = true;
-
- keyboardShortcuts.processEventQueryTool(
- sqlEditorControllerSpy, queryToolActionsSpy, event
- );
- });
-
- it('should execute the macro', () => {
- expect(queryToolActionsSpy.executeMacro).toHaveBeenCalledWith(sqlEditorControllerSpy,
- sqlEditorControllerSpy.macros[0].id);
- });
-
- it('should stop event propagation', () => {
- expect(event.preventDefault).toHaveBeenCalled();
- });
- });
-
- describe('when the query is already running', () => {
- it('does nothing', () => {
- event.keyCode = C1_KEY;
- event.altKey = false;
- event.shiftKey = false;
- event.ctrlKey = true;
-
- sqlEditorControllerSpy.isQueryRunning.and.returnValue(true);
-
- keyboardShortcuts.processEventQueryTool(
- sqlEditorControllerSpy, queryToolActionsSpy, event
- );
-
- expect(queryToolActionsSpy.executeMacro).not.toHaveBeenCalled();
- });
- });
- });
-
- function expectEventPropagationToStop() {
- describe('stops all event propogation', () => {
-
- it('should cancel the bubble', () => {
- expect(event.cancelBubble).toEqual(true);
- });
-
- it('should prevent the default behavior', () => {
- expect(event.preventDefault).toHaveBeenCalled();
- });
-
- it('should stop event propagation', () => {
- expect(event.stopPropagation).toHaveBeenCalled();
- expect(event.stopImmediatePropagation).toHaveBeenCalled();
- });
- });
- }
-
- function windowsKeysSetup() {
- spyOn(keyboardShortcuts, 'isMac').and.returnValue(false);
- event.ctrlKey = true;
- event.metaKey = false;
- }
-
- function macKeysSetup() {
- spyOn(keyboardShortcuts, 'isMac').and.returnValue(true);
- event.ctrlKey = false;
- event.metaKey = true;
- }
-});
diff --git a/web/regression/javascript/sqleditor/query_tool_actions_spec.js b/web/regression/javascript/sqleditor/query_tool_actions_spec.js
deleted file mode 100644
index 74b82d05d..000000000
--- a/web/regression/javascript/sqleditor/query_tool_actions_spec.js
+++ /dev/null
@@ -1,608 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////////////////
-import queryToolActions from 'sources/sqleditor/query_tool_actions';
-
-describe('queryToolActions', () => {
- let sqlEditorController,
- getSelectionSpy, getValueSpy,
- selectedQueryString, entireQueryString,
- replaceSelectionSpy;
-
- let executeFunctionCall = ()=>{
- queryToolActions.executeQuery(sqlEditorController);
- expect(sqlEditorController.check_data_changes_to_execute_query).toHaveBeenCalled();
- };
-
- let toggleSelectionStringUpperCase = ()=> {
- it('toggle the selection and string should be in upper case', () => {
- queryToolActions.toggleCaseOfSelectedText(sqlEditorController);
- expect(replaceSelectionSpy
- ).toHaveBeenCalledWith('STRING');
- });
- };
-
- let beforeEachEmptySelection = ()=> {
- setUpSpies('', 'a string\nddd\nsss');
-
- sqlEditorController.gridView.query_tool_obj.getCursor = () => {
- return 3;
- };
- };
-
- describe('executeQuery', () => {
- describe('when the command is being run from the query tool', () => {
- beforeEach(() => {
- setUpSpies('', '');
- spyOn(queryToolActions, '_clearMessageTab');
- });
-
- it('clears the html in the message tab', () => {
- queryToolActions.executeQuery(sqlEditorController);
-
- expect(queryToolActions._clearMessageTab).toHaveBeenCalled();
- });
-
- it('calls the execute function on the sqlEditorController', executeFunctionCall);
- });
- describe('when the command is being run from the view data view', () => {
- beforeEach(() => {
- setUpSpies('', '');
- sqlEditorController.is_query_tool = false;
- });
-
- it('it calls the check_data_changes_to_execute_query function on the sqlEditorController', executeFunctionCall);
- });
- });
-
- describe('explainAnalyze', () => {
- describe('when verbose and costs are not selected and buffers and timing are not selected', () => {
- beforeEach(() => {
- setUpSpies('', '');
- spyOn(queryToolActions, '_verbose').and.returnValue(false);
- spyOn(queryToolActions, '_costsEnabled').and.returnValue(false);
- spyOn(queryToolActions, '_buffers').and.returnValue(false);
- spyOn(queryToolActions, '_timing').and.returnValue(false);
- spyOn(queryToolActions, '_summary').and.returnValue(false);
- spyOn(queryToolActions, '_settings').and.returnValue(false);
- });
-
- it('calls the execute function', () => {
- queryToolActions.explainAnalyze(sqlEditorController);
-
- const explainObject = {
- format: 'json',
- analyze: true,
- verbose: false,
- costs: false,
- buffers: false,
- timing: false,
- summary: false,
- settings: false,
- };
-
- expect(sqlEditorController.check_data_changes_to_execute_query).toHaveBeenCalledWith(explainObject);
- });
- });
-
- describe('when all options are selected', () => {
- beforeEach(() => {
- setUpSpies('', '');
- spyOn(queryToolActions, '_verbose').and.returnValue(true);
- spyOn(queryToolActions, '_costsEnabled').and.returnValue(true);
- spyOn(queryToolActions, '_buffers').and.returnValue(true);
- spyOn(queryToolActions, '_timing').and.returnValue(true);
- spyOn(queryToolActions, '_summary').and.returnValue(true);
- spyOn(queryToolActions, '_settings').and.returnValue(true);
- });
- it('calls the execute function', () => {
- queryToolActions.explainAnalyze(sqlEditorController);
- const explainObject = {
- format: 'json',
- analyze: true,
- verbose: true,
- costs: true,
- buffers: true,
- timing: true,
- summary: true,
- settings: true,
- };
- expect(sqlEditorController.check_data_changes_to_execute_query).toHaveBeenCalledWith(explainObject);
- });
- });
-
- describe('when verbose is selected and costs is not selected and buffer is selected and timing is not selected', () => {
- beforeEach(() => {
- setUpSpies('', '');
- spyOn(queryToolActions, '_verbose').and.returnValue(true);
- spyOn(queryToolActions, '_costsEnabled').and.returnValue(false);
- spyOn(queryToolActions, '_buffers').and.returnValue(true);
- spyOn(queryToolActions, '_timing').and.returnValue(false);
- spyOn(queryToolActions, '_summary').and.returnValue(false);
- spyOn(queryToolActions, '_settings').and.returnValue(false);
- });
- it('calls the execute function', () => {
- queryToolActions.explainAnalyze(sqlEditorController);
-
- const explainObject = {
- format: 'json',
- analyze: true,
- verbose: true,
- costs: false,
- buffers: true,
- timing: false,
- summary: false,
- settings: false,
- };
-
- expect(sqlEditorController.check_data_changes_to_execute_query).toHaveBeenCalledWith(explainObject);
- });
- });
-
- describe('when verbose is not selected and costs is selected and buffer is not selected and timing is selected', () => {
- beforeEach(() => {
- setUpSpies('', '');
- spyOn(queryToolActions, '_verbose').and.returnValue(false);
- spyOn(queryToolActions, '_costsEnabled').and.returnValue(true);
- spyOn(queryToolActions, '_buffers').and.returnValue(false);
- spyOn(queryToolActions, '_timing').and.returnValue(true);
- spyOn(queryToolActions, '_summary').and.returnValue(false);
- spyOn(queryToolActions, '_settings').and.returnValue(false);
- });
- it('calls the execute function', () => {
- queryToolActions.explainAnalyze(sqlEditorController);
-
- const explainObject = {
- format: 'json',
- analyze: true,
- verbose: false,
- costs: true,
- buffers: false,
- timing: true,
- summary: false,
- settings: false,
- };
-
- expect(sqlEditorController.check_data_changes_to_execute_query).toHaveBeenCalledWith(explainObject);
- });
- });
-
- describe('when all are not selected except summary and settings', () => {
- beforeEach(() => {
- setUpSpies('', '');
- spyOn(queryToolActions, '_verbose').and.returnValue(false);
- spyOn(queryToolActions, '_costsEnabled').and.returnValue(false);
- spyOn(queryToolActions, '_buffers').and.returnValue(false);
- spyOn(queryToolActions, '_timing').and.returnValue(false);
- spyOn(queryToolActions, '_summary').and.returnValue(true);
- spyOn(queryToolActions, '_settings').and.returnValue(true);
- });
- it('calls the execute function', () => {
- queryToolActions.explainAnalyze(sqlEditorController);
-
- const explainObject = {
- format: 'json',
- analyze: true,
- verbose: false,
- costs: false,
- buffers: false,
- timing: false,
- summary: true,
- settings: true,
- };
-
- expect(sqlEditorController.check_data_changes_to_execute_query).toHaveBeenCalledWith(explainObject);
- });
- });
- });
-
- describe('explain', () => {
- describe('when verbose and costs are selected', () => {
- beforeEach(() => {
- setUpSpies('', '');
- spyOn(queryToolActions, '_verbose').and.returnValue(true);
- spyOn(queryToolActions, '_costsEnabled').and.returnValue(true);
- spyOn(queryToolActions, '_summary').and.returnValue(false);
- spyOn(queryToolActions, '_settings').and.returnValue(false);
- });
-
- it('calls the execute function', () => {
- queryToolActions.explain(sqlEditorController);
- const explainObject = {
- format: 'json',
- analyze: false,
- verbose: true,
- costs: true,
- buffers: false,
- timing: false,
- summary: false,
- settings: false,
- };
- expect(sqlEditorController.check_data_changes_to_execute_query).toHaveBeenCalledWith(explainObject);
- });
- });
-
- describe('when verbose and costs are not selected', () => {
- beforeEach(() => {
- setUpSpies('', '');
- spyOn(queryToolActions, '_verbose').and.returnValue(false);
- spyOn(queryToolActions, '_costsEnabled').and.returnValue(false);
- spyOn(queryToolActions, '_summary').and.returnValue(false);
- spyOn(queryToolActions, '_settings').and.returnValue(false);
- });
-
- it('calls the execute function', () => {
- queryToolActions.explain(sqlEditorController);
- const explainObject = {
- format: 'json',
- analyze: false,
- verbose: false,
- costs: false,
- buffers: false,
- timing: false,
- summary: false,
- settings: false,
- };
-
- expect(sqlEditorController.check_data_changes_to_execute_query).toHaveBeenCalledWith(explainObject);
- });
- });
-
- describe('when verbose is selected and costs is not selected', () => {
- beforeEach(() => {
- setUpSpies('', '');
- spyOn(queryToolActions, '_verbose').and.returnValue(true);
- spyOn(queryToolActions, '_costsEnabled').and.returnValue(false);
- spyOn(queryToolActions, '_summary').and.returnValue(false);
- spyOn(queryToolActions, '_settings').and.returnValue(false);
- });
-
- it('calls the execute function', () => {
- queryToolActions.explain(sqlEditorController);
- const explainObject = {
- format: 'json',
- analyze: false,
- verbose: true,
- costs: false,
- buffers: false,
- timing: false,
- summary: false,
- settings: false,
- };
- expect(sqlEditorController.check_data_changes_to_execute_query).toHaveBeenCalledWith(explainObject);
- });
- });
- });
-
- describe('download', () => {
- describe('when the query is empty', () => {
- beforeEach(() => {
- setUpSpies('', '');
- });
- it('does nothing', () => {
- queryToolActions.download(sqlEditorController);
-
- expect(sqlEditorController.trigger_csv_download).toHaveBeenCalled();
- });
- });
-
- describe('when the table was opened through the queryTool', () => {
- let time;
- let spyCall = ()=> {
- time = 'rightNow';
- spyOn(window, 'Date').and.callFake(() => ({
- getTime: () => {
- return time;
- },
- }));
- };
-
- let callCSVDownload = ()=> {
- let filename = 'data-' + time + '.csv';
-
- queryToolActions.download(sqlEditorController);
-
- expect(sqlEditorController.trigger_csv_download).toHaveBeenCalledWith(filename);
- };
-
- describe('when the query tool object has a selection', () => {
- beforeEach(() => {
- entireQueryString = 'include some more of that yummy string cheese;';
- selectedQueryString = 'some silly string cheese';
- setUpSpies(selectedQueryString, entireQueryString);
-
- spyCall();
- });
-
- it('calls trigger_csv_download with filename having .csv extension', callCSVDownload);
-
- it('calls trigger_csv_download filename having .txt extension', () => {
- sqlEditorController.preferences.csv_field_separator = ';';
- let filename = 'data-' + time + '.txt';
-
- queryToolActions.download(sqlEditorController);
-
- expect(sqlEditorController.trigger_csv_download).toHaveBeenCalledWith(filename);
- });
- });
-
- describe('when there is no selection', () => {
- beforeEach(() => {
- selectedQueryString = '';
- entireQueryString = 'include some more of that yummy string cheese;';
- setUpSpies(selectedQueryString, entireQueryString);
- spyCall();
- });
-
- it('calls trigger_csv_download with filename', callCSVDownload);
- });
- });
-
- describe('when the table was opened through tables, view all data', () => {
- it('calls trigger_csv_download with the sqlQuery and the table name', () => {
- let query = 'a very long query';
- setUpSpies('', query);
- sqlEditorController.is_query_tool = false;
-
- queryToolActions.download(sqlEditorController);
-
- expect(sqlEditorController.trigger_csv_download).toHaveBeenCalledWith('iAmATable' + '.csv');
- });
- });
-
- });
-
- describe('commentBlockCode', () => {
- describe('when there is no query text', () => {
- beforeEach(() => {
- setUpSpies('', '');
- });
- it('does nothing', () => {
- let codeMirrorObj = sqlEditorController.gridView.query_tool_obj;
-
- queryToolActions.commentBlockCode(sqlEditorController);
-
- expect(codeMirrorObj.toggleComment).not.toHaveBeenCalled();
- });
- });
-
- describe('when there is empty selection', () => {
- beforeEach(beforeEachEmptySelection);
-
- it('comments the current line', () => {
- let codeMirrorObj = sqlEditorController.gridView.query_tool_obj;
-
- queryToolActions.commentBlockCode(sqlEditorController);
-
- expect(codeMirrorObj.toggleComment).toHaveBeenCalledWith(3, 3);
- });
- });
-
- describe('when some part of the query is selected', () => {
- beforeEach(() => {
- setUpSpies('a string\nddd', 'a string\nddd\nsss');
- });
-
- it('comments the selection', () => {
- let codeMirrorObj = sqlEditorController.gridView.query_tool_obj;
-
- queryToolActions.commentBlockCode(sqlEditorController);
-
- expect(codeMirrorObj.toggleComment).toHaveBeenCalledWith(0, 12);
- });
- });
- });
-
- describe('commentLineCode', () => {
- describe('when there is no query text', () => {
- beforeEach(() => {
- setUpSpies('', '');
- });
- it('does nothing', () => {
- let codeMirrorObj = sqlEditorController.gridView.query_tool_obj;
-
- queryToolActions.commentLineCode(sqlEditorController);
-
- expect(codeMirrorObj.lineComment).not.toHaveBeenCalled();
- });
- });
-
- describe('when there is empty selection', () => {
- beforeEach(beforeEachEmptySelection);
-
- it('comments the current line', () => {
- let codeMirrorObj = sqlEditorController.gridView.query_tool_obj;
-
- queryToolActions.commentLineCode(sqlEditorController);
-
- expect(codeMirrorObj.lineComment).toHaveBeenCalledWith(3, 3, {lineComment: '--'});
- });
- });
-
- describe('when some part of the query is selected', () => {
- beforeEach(() => {
- setUpSpies('tring\nddd', 'a string\nddd\nsss');
- });
-
- it('comments the selection', () => {
- let codeMirrorObj = sqlEditorController.gridView.query_tool_obj;
-
- queryToolActions.commentLineCode(sqlEditorController);
-
- expect(codeMirrorObj.lineComment).toHaveBeenCalledWith(3, 12, {lineComment: '--'});
- });
- });
- });
-
- describe('uncommentLineCode', () => {
- describe('when there is no query text', () => {
- beforeEach(() => {
- setUpSpies('', '');
- });
- it('does nothing', () => {
- let codeMirrorObj = sqlEditorController.gridView.query_tool_obj;
-
- queryToolActions.uncommentLineCode(sqlEditorController);
-
- expect(codeMirrorObj.uncomment).not.toHaveBeenCalled();
- });
- });
-
- describe('when there is empty selection', () => {
- beforeEach(beforeEachEmptySelection);
-
- it('uncomments the current line', () => {
- let codeMirrorObj = sqlEditorController.gridView.query_tool_obj;
-
- queryToolActions.uncommentLineCode(sqlEditorController);
-
- expect(codeMirrorObj.uncomment).toHaveBeenCalledWith(3, 3, {lineComment: '--'});
- });
- });
-
- describe('when some part of the query is selected', () => {
- beforeEach(() => {
- setUpSpies('tring\nddd', 'a string\nddd\nsss');
- });
-
- it('uncomments the selection', () => {
- let codeMirrorObj = sqlEditorController.gridView.query_tool_obj;
-
- queryToolActions.uncommentLineCode(sqlEditorController);
-
- expect(codeMirrorObj.uncomment).toHaveBeenCalledWith(3, 12, {lineComment: '--'});
- });
- });
- });
-
- describe('toggleCaseOfSelectedText', () => {
-
- let doesNothingTestCase = ()=> {
- it('does nothing', () => {
- expect(
- queryToolActions.toggleCaseOfSelectedText(sqlEditorController)
- ).not.toBeDefined();
- });
- };
-
- describe('when there is no query text', () => {
- beforeEach(() => {
- setUpSpies('', '');
- });
- doesNothingTestCase();
- });
-
- describe('when there is empty selection', () => {
- beforeEach(beforeEachEmptySelection);
-
- doesNothingTestCase();
- });
-
- describe('when selected query is in lower case', () => {
- beforeEach(() => {
- setUpSpies('string', 'a string\nddd\nsss');
- });
-
- toggleSelectionStringUpperCase();
-
- it('(negative scenario toggle the selection and string should be in upper case', () => {
- queryToolActions.toggleCaseOfSelectedText(sqlEditorController);
- expect(replaceSelectionSpy
- ).not.toHaveBeenCalledWith('string');
- });
- });
-
- describe('when selected query is in upper case', () => {
- beforeEach(() => {
- setUpSpies('STRING', 'a string\nddd\nsss');
- });
-
- it('toggle the selection and string should be in lower case', () => {
- queryToolActions.toggleCaseOfSelectedText(sqlEditorController);
- expect(replaceSelectionSpy
- ).toHaveBeenCalledWith('string');
- });
-
- it('(negative scenario toggle the selection and string should be in lower case', () => {
- queryToolActions.toggleCaseOfSelectedText(sqlEditorController);
- expect(replaceSelectionSpy
- ).not.toHaveBeenCalledWith('STRING');
- });
- });
-
- describe('when selected query is in mixed case', () => {
- beforeEach(() => {
- setUpSpies('sTRIng', 'a string\nddd\nsss');
- });
-
- toggleSelectionStringUpperCase();
-
- it('(negative scenario toggle the selection and string should be in upper case', () => {
- queryToolActions.toggleCaseOfSelectedText(sqlEditorController);
- expect(replaceSelectionSpy
- ).not.toHaveBeenCalledWith('sTRIng');
- });
- });
- });
-
- describe('executeCommit', () => {
- describe('when commit action is being run from the query tool', () => {
- beforeEach(() => {
- setUpSpies('', '');
- });
-
- it('calls the execute commit function', () => {
- queryToolActions.executeCommit(sqlEditorController);
- expect(sqlEditorController.special_sql).toEqual('COMMIT;');
- });
- });
- });
-
- describe('executeRollback', () => {
- describe('when rollback action is being run from the query tool', () => {
- beforeEach(() => {
- setUpSpies('', '');
- });
-
- it('calls the execute rollback function', () => {
- queryToolActions.executeRollback(sqlEditorController);
- expect(sqlEditorController.special_sql).toEqual('ROLLBACK;');
- });
- });
- });
-
- function setUpSpies(selectedQueryStringArg, entireQueryStringArg) {
- getValueSpy = jasmine.createSpy('getValueSpy').and.returnValue(entireQueryStringArg);
- getSelectionSpy = jasmine.createSpy('getSelectionSpy').and.returnValue(selectedQueryStringArg);
- replaceSelectionSpy = jasmine.createSpy('replaceSelectionSpy');
-
- sqlEditorController = {
- gridView: {
- query_tool_obj: {
- getSelection: getSelectionSpy,
- getValue: getValueSpy,
- toggleComment: jasmine.createSpy('toggleCommentSpy'),
- lineComment: jasmine.createSpy('lineCommentSpy'),
- uncomment: jasmine.createSpy('uncommentSpy'),
- replaceSelection: replaceSelectionSpy,
- getCursor: (isFrom) => {
- return entireQueryStringArg.indexOf(selectedQueryStringArg) + (isFrom ? 0 : selectedQueryStringArg.length);
- },
- },
- },
- trigger_csv_download: jasmine.createSpy('trigger_csv_download'),
- trigger: jasmine.createSpy('trigger'),
- table_name: 'iAmATable',
- is_query_tool: true,
- check_data_changes_to_execute_query: jasmine.createSpy('check_data_changes_to_execute_query'),
- preferences: {
- csv_field_separator: ',',
- },
- };
- }
-});
diff --git a/web/regression/javascript/sqleditor/query_tool_http_error_handler_spec.js b/web/regression/javascript/sqleditor/query_tool_http_error_handler_spec.js
deleted file mode 100644
index ea15efaed..000000000
--- a/web/regression/javascript/sqleditor/query_tool_http_error_handler_spec.js
+++ /dev/null
@@ -1,191 +0,0 @@
-//////////////////////////////////////////////////////////////////////////
-//
-// pgAdmin 4 - PostgreSQL Tools
-//
-// Copyright (C) 2013 - 2022, The pgAdmin Development Team
-// This software is released under the PostgreSQL Licence
-//
-//////////////////////////////////////////////////////////////////////////
-
-import {
- httpResponseRequiresNewTransaction,
- handleQueryToolAjaxError,
-} from '../../../pgadmin/static/js/sqleditor/query_tool_http_error_handler';
-
-describe('#httpResponseRequiresNewTransaction', () => {
- describe('when status is not 404', () => {
- it('should return false', () => {
- expect(httpResponseRequiresNewTransaction({
- status: 300,
- })).toEqual(false);
- });
- });
-
- describe('when status is 404', () => {
- describe('when data is not present', () => {
- it('should return false', () => {
- expect(httpResponseRequiresNewTransaction({
- status: 404,
- })).toBeFalsy();
- });
- });
-
- describe('when data is present', () => {
- describe('when info is not present inside data', () => {
- it('should return false', () => {
- expect(httpResponseRequiresNewTransaction({
- status: 404,
- data: {},
- })).toBeFalsy();
- });
- });
-
- describe('when info is present inside data', () => {
- describe('when info value is not "DATAGRID_TRANSACTION_REQUIRED"', () => {
- it('should return false', () => {
- expect(httpResponseRequiresNewTransaction({
- status: 404,
- data: {
- info: 'some information',
- },
- })).toEqual(false);
- });
- });
-
- describe('when info value is "DATAGRID_TRANSACTION_REQUIRED"', () => {
- it('should return false', () => {
- expect(httpResponseRequiresNewTransaction({
- status: 404,
- data: {
- info: 'DATAGRID_TRANSACTION_REQUIRED',
- },
- })).toEqual(true);
- });
- });
- });
- });
- });
-});
-
-
-describe('#handleQueryToolAjaxError', () => {
- let sqlEditorHandler,
- exceptionSpy, stateToSave,
- stateParameters, checkTransaction,
- pgBrowserMock;
-
- beforeEach(() => {
- stateToSave = 'testState';
- stateParameters = [];
- checkTransaction = false;
- sqlEditorHandler = jasmine.createSpyObj(
- 'handler', ['initTransaction', 'saveState', 'handle_connection_lost']
- );
- exceptionSpy = {
- readyState: 0,
- status: 404,
- data: {
- info: 'CONNECTION_LOST',
- },
- };
- pgBrowserMock = {
- 'Browser': {
- 'UserManagement': jasmine.createSpyObj('UserManagement', ['isPgaLoginRequired', 'pgaLogin']),
- },
- };
- });
-
- describe('when ready state is 0', () => {
- it('should return connection', () => {
- expect(
- handleQueryToolAjaxError(
- pgBrowserMock, sqlEditorHandler, exceptionSpy, stateToSave,
- stateParameters, checkTransaction
- )
- ).toEqual('Not connected to the server or the connection to the server has been closed.');
- });
- });
-
- describe('when there is an ajax error due to login is required', () => {
- beforeEach(() => {
- exceptionSpy.readyState = 1;
- exceptionSpy.status = 401;
- exceptionSpy.data.info = 'PGADMIN_LOGIN_REQUIRED';
- pgBrowserMock.Browser.UserManagement.isPgaLoginRequired.and.returnValue(true);
- });
-
- it('should save the current state and call login handler', () => {
- handleQueryToolAjaxError(
- pgBrowserMock, sqlEditorHandler, exceptionSpy, stateToSave,
- stateParameters, checkTransaction
- );
- expect(sqlEditorHandler.saveState).toHaveBeenCalledWith(stateToSave, stateParameters);
- expect(pgBrowserMock.Browser.UserManagement.pgaLogin).toHaveBeenCalled();
- });
- });
-
- describe('when there is an ajax error and new transaction initialization required', () => {
- beforeEach(() => {
- exceptionSpy.readyState = 1;
- exceptionSpy.status = 404;
- exceptionSpy.data.info = 'DATAGRID_TRANSACTION_REQUIRED';
- pgBrowserMock.Browser.UserManagement.isPgaLoginRequired.and.returnValue(false);
- checkTransaction = true;
- });
-
- it('should save the current state and call login handler', () => {
- handleQueryToolAjaxError(
- pgBrowserMock, sqlEditorHandler, exceptionSpy, stateToSave,
- stateParameters, checkTransaction
- );
- expect(pgBrowserMock.Browser.UserManagement.pgaLogin).not.toHaveBeenCalled();
- expect(sqlEditorHandler.saveState).toHaveBeenCalledWith(stateToSave, stateParameters);
- expect(sqlEditorHandler.initTransaction).toHaveBeenCalled();
- });
- });
-
- describe('when there is an ajax error due to database connection has been lost', () => {
- beforeEach(() => {
- exceptionSpy.readyState = 1;
- exceptionSpy.status = 503;
- exceptionSpy.responseJSON = {
- 'info': 'CONNECTION_LOST',
- };
- pgBrowserMock.Browser.UserManagement.isPgaLoginRequired.and.returnValue(false);
- checkTransaction = false;
- });
-
- it('should save the current state and call connection lost handler', (done) => {
- handleQueryToolAjaxError(
- pgBrowserMock, sqlEditorHandler, exceptionSpy, stateToSave,
- stateParameters, checkTransaction
- );
- expect(pgBrowserMock.Browser.UserManagement.pgaLogin).not.toHaveBeenCalled();
- setTimeout(() => {
- expect(sqlEditorHandler.saveState).toHaveBeenCalledWith(stateToSave, stateParameters);
- expect(sqlEditorHandler.handle_connection_lost).toHaveBeenCalledWith(false, exceptionSpy);
- done();
- }, 0);
- });
- });
-
- describe('when there is an ajax error due to unknown reason', () => {
- beforeEach(() => {
- exceptionSpy.readyState = 1;
- exceptionSpy.status = 803;
- exceptionSpy.responseText = 'ajax failed with unknown reason';
- pgBrowserMock.Browser.UserManagement.isPgaLoginRequired.and.returnValue(false);
- checkTransaction = false;
- });
-
- it('should return proper error message from ajax exception', () => {
- expect(
- handleQueryToolAjaxError(
- pgBrowserMock, sqlEditorHandler, exceptionSpy, stateToSave,
- stateParameters, checkTransaction
- )
- ).toEqual('ajax failed with unknown reason');
- });
- });
-
-});
diff --git a/web/regression/javascript/sqleditor_utils_spec.js b/web/regression/javascript/sqleditor_utils_spec.js
index 29e9855ea..886625769 100644
--- a/web/regression/javascript/sqleditor_utils_spec.js
+++ b/web/regression/javascript/sqleditor_utils_spec.js
@@ -10,25 +10,6 @@
define(['sources/sqleditor_utils'],
function (SqlEditorUtils) {
describe('SqlEditorUtils', function () {
-
- describe('Generate a random string of size 10', function () {
- it('returns string of length 10', function () {
- expect(SqlEditorUtils.epicRandomString(10).length).toEqual(10);
- });
- });
-
- describe('Generate a unique hash for given string', function () {
- it('returns unique hash', function () {
- expect(SqlEditorUtils.getHash('select * from test')).toEqual(403379630);
- });
- });
-
- describe('Capitalize the first letter of given string', function () {
- it('returns string with First letter Capital', function () {
- expect(SqlEditorUtils.capitalizeFirstLetter('create script')).toEqual('Create script');
- });
- });
-
describe('Calculate font size of input number passed', function () {
it('calcFontSize', function () {
expect(SqlEditorUtils.calcFontSize(1.456)).toEqual('1.46em');
diff --git a/web/webpack.config.js b/web/webpack.config.js
index ed9ad4472..66e39f500 100644
--- a/web/webpack.config.js
+++ b/web/webpack.config.js
@@ -374,7 +374,7 @@ module.exports = [{
'app.bundle': sourceDir + '/bundle/app.js',
codemirror: sourceDir + '/bundle/codemirror.js',
slickgrid: sourceDir + '/bundle/slickgrid.js',
- sqleditor: './pgadmin/tools/sqleditor/static/js/sqleditor.js',
+ sqleditor: './pgadmin/tools/sqleditor/static/js/index.js',
debugger_direct: './pgadmin/tools/debugger/static/js/direct.js',
schema_diff: './pgadmin/tools/schema_diff/static/js/schema_diff_hook.js',
erd_tool: './pgadmin/tools/erd/static/js/erd_tool_hook.js',
@@ -463,7 +463,7 @@ module.exports = [{
// var jQuery = require('jquery'); var browser = require('pgadmin.browser')
// It solves number of problems
// Ref: http:/github.com/webpack-contrib/imports-loader/
- test: require.resolve('./pgadmin/tools/datagrid/static/js/datagrid'),
+ test: require.resolve('./pgadmin/tools/sqleditor/static/js/index'),
use: {
loader: 'imports-loader',
options: {
@@ -564,6 +564,7 @@ module.exports = [{
'pure|pgadmin.tools.search_objects',
'pure|pgadmin.tools.erd_module',
'pure|pgadmin.tools.psql_module',
+ 'pure|pgadmin.tools.sqleditor',
'pure|pgadmin.misc.cloud',
],
},
diff --git a/web/webpack.shim.js b/web/webpack.shim.js
index f9af1531f..27096081a 100644
--- a/web/webpack.shim.js
+++ b/web/webpack.shim.js
@@ -215,7 +215,6 @@ var webpackShimConfig = {
'pgadmin.browser.utils': '/browser/js/utils',
'pgadmin.browser.wizard': path.join(__dirname, './pgadmin/browser/static/js/wizard'),
'pgadmin.dashboard': path.join(__dirname, './pgadmin/dashboard/static/js/Dashboard'),
- 'pgadmin.datagrid': path.join(__dirname, './pgadmin/tools/datagrid/static/js/datagrid'),
'pgadmin.file_manager': path.join(__dirname, './pgadmin/misc/file_manager/static/js/file_manager'),
'pgadmin.file_utility': path.join(__dirname, './pgadmin/misc/file_manager/static/js/utility'),
'pgadmin.help': path.join(__dirname, './pgadmin/help/static/js/help'),
@@ -284,7 +283,6 @@ var webpackShimConfig = {
'pgadmin.preferences': path.join(__dirname, './pgadmin/preferences/static/js/'),
'pgadmin.settings': path.join(__dirname, './pgadmin/settings/static/js/settings'),
'pgadmin.server.supported_servers': '/browser/server/supported_servers',
- 'pgadmin.sqleditor': path.join(__dirname, './pgadmin/tools/sqleditor/static/js/sqleditor'),
'pgadmin.tables.js': path.join(__dirname, './pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/'),
'pgadmin.tools.backup': path.join(__dirname, './pgadmin/tools/backup/static/js/backup'),
'pgadmin.tools.debugger.controller': path.join(__dirname, './pgadmin/tools/debugger/static/js/debugger'),
@@ -304,7 +302,7 @@ var webpackShimConfig = {
'pgadmin.tools.erd': path.join(__dirname, './pgadmin/tools/erd/static/js'),
'pgadmin.tools.psql_module': path.join(__dirname, './pgadmin/tools/psql/static/js/psql_module'),
'pgadmin.tools.psql': path.join(__dirname, './pgadmin/tools/psql/static/js'),
- 'pgadmin.tools.query_tool': path.join(__dirname, './pgadmin/tools/query_tool/static/js'),
+ 'pgadmin.tools.sqleditor': path.join(__dirname, './pgadmin/tools/sqleditor/static/js'),
'pgadmin.search_objects': path.join(__dirname, './pgadmin/tools/search_objects/static/js'),
'pgadmin.tools.user_management': path.join(__dirname, './pgadmin/tools/user_management/static/js/user_management'),
'pgadmin.user_management.current_user': '/user_management/current_user',
diff --git a/web/webpack.test.config.js b/web/webpack.test.config.js
index c36d463b9..197395d99 100644
--- a/web/webpack.test.config.js
+++ b/web/webpack.test.config.js
@@ -185,6 +185,8 @@ module.exports = {
'backform': path.join(__dirname, './node_modules/backform/src/backform'),
'backgrid': path.join(__dirname, './pgadmin/static/vendor/backgrid/backgrid'),
'backgrid.filter': path.join(__dirname, './node_modules/backgrid-filter/backgrid-filter'),
+ 'react': path.join(__dirname, 'node_modules/react'),
+ 'react-dom': path.join(__dirname, 'node_modules/react-dom'),
'sources': sourcesDir + '/js',
'translations': regressionDir + '/javascript/fake_translations',
'pgadmin.browser.messages': regressionDir + '/javascript/fake_messages',
@@ -194,6 +196,7 @@ module.exports = {
'slickgrid.plugins': nodeModulesDir + '/slickgrid/plugins/',
'slickgrid.grid': nodeModulesDir + '/slickgrid/slick.grid',
'moment': path.join(__dirname, './node_modules/moment/moment'),
+ 'jsoneditor.min': path.join(__dirname, './node_modules/jsoneditor/dist/jsoneditor.min'),
'browser': path.resolve(__dirname, 'pgadmin/browser/static/js'),
'pgadmin': sourcesDir + '/js/pgadmin',
'pgadmin.sqlfoldcode': sourcesDir + '/js/codemirror/addon/fold/pgadmin-sqlfoldcode',
@@ -208,6 +211,8 @@ module.exports = {
'pgadmin.browser.activity': path.join(__dirname, './pgadmin/browser/static/js/activity'),
'pgadmin.tools.erd': path.join(__dirname, './pgadmin/tools/erd/static/js'),
'pgadmin.tools.psql': path.join(__dirname, './pgadmin/tools/psql/static/js'),
+ 'pgadmin.tools.sqleditor': path.join(__dirname, './pgadmin/tools/sqleditor/static/js'),
+ 'pgadmin.authenticate.kerberos': path.join(__dirname, './pgadmin/authenticate/static/js/kerberos'),
'bundled_codemirror': path.join(__dirname, './pgadmin/static/bundle/codemirror'),
'tools': path.join(__dirname, './pgadmin/tools/'),
'pgadmin.user_management.current_user': regressionDir + '/javascript/fake_current_user',
diff --git a/web/yarn.lock b/web/yarn.lock
index bfb47913f..3868618e6 100644
--- a/web/yarn.lock
+++ b/web/yarn.lock
@@ -31,6 +31,13 @@
dependencies:
"@babel/highlight" "^7.14.5"
+"@babel/code-frame@^7.16.0":
+ version "7.16.0"
+ resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.0.tgz#0dfc80309beec8411e65e706461c408b0bb9b431"
+ integrity sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA==
+ dependencies:
+ "@babel/highlight" "^7.16.0"
+
"@babel/code-frame@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789"
@@ -38,12 +45,7 @@
dependencies:
"@babel/highlight" "^7.16.7"
-"@babel/compat-data@^7.13.0", "@babel/compat-data@^7.13.8", "@babel/compat-data@^7.14.5", "@babel/compat-data@^7.14.7":
- version "7.14.7"
- resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.14.7.tgz#7b047d7a3a89a67d2258dc61f604f098f1bc7e08"
- integrity sha512-nS6dZaISCXJ3+518CWiBfEr//gHyMO02uDxBkXTKZDN5POruCnOZ1N4YBRZDCabwF8nZMWBpRxIicmXtBs+fvw==
-
-"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.16.4", "@babel/compat-data@^7.16.8":
+"@babel/compat-data@^7.13.0", "@babel/compat-data@^7.13.11", "@babel/compat-data@^7.13.8", "@babel/compat-data@^7.14.5", "@babel/compat-data@^7.14.7", "@babel/compat-data@^7.16.4", "@babel/compat-data@^7.16.8":
version "7.17.0"
resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.0.tgz#86850b8597ea6962089770952075dcaabb8dba34"
integrity sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng==
@@ -107,16 +109,7 @@
dependencies:
eslint-rule-composer "^0.3.0"
-"@babel/generator@^7.13.0", "@babel/generator@^7.14.5":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.5.tgz#848d7b9f031caca9d0cd0af01b063f226f52d785"
- integrity sha512-y3rlP+/G25OIX3mYKKIOlQRcqj7YgrvHxOLbVmyLJ9bPmi5ttvUmpydVjcFjZphOktWuA7ovbx91ECloWTfjIA==
- dependencies:
- "@babel/types" "^7.14.5"
- jsesc "^2.5.1"
- source-map "^0.5.0"
-
-"@babel/generator@^7.17.0":
+"@babel/generator@^7.13.0", "@babel/generator@^7.14.5", "@babel/generator@^7.17.0":
version "7.17.0"
resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.0.tgz#7bd890ba706cd86d3e2f727322346ffdbf98f65e"
integrity sha512-I3Omiv6FGOC29dtlZhkfXO6pgkmukJSlT26QjVvS1DGZe/NzSVCPG41X0tS21oZkJYlovfj9qDWgKP+Cn4bXxw==
@@ -125,12 +118,21 @@
jsesc "^2.5.1"
source-map "^0.5.0"
-"@babel/helper-annotate-as-pure@^7.0.0", "@babel/helper-annotate-as-pure@^7.10.4", "@babel/helper-annotate-as-pure@^7.12.13", "@babel/helper-annotate-as-pure@^7.14.5":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz#7bf478ec3b71726d56a8ca5775b046fc29879e61"
- integrity sha512-EivH9EgBIb+G8ij1B2jAwSH36WnGvkQSEC6CkX/6v6ZFlw5fVOHvsgGF4uiEHO2GzMvunZb6tDLQEQSdrdocrA==
+"@babel/generator@^7.16.0":
+ version "7.16.0"
+ resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.0.tgz#d40f3d1d5075e62d3500bccb67f3daa8a95265b2"
+ integrity sha512-RR8hUCfRQn9j9RPKEVXo9LiwoxLPYn6hNZlvUOR8tSnaxlD0p0+la00ZP9/SnRt6HchKr+X0fO2r8vrETiJGew==
dependencies:
- "@babel/types" "^7.14.5"
+ "@babel/types" "^7.16.0"
+ jsesc "^2.5.1"
+ source-map "^0.5.0"
+
+"@babel/helper-annotate-as-pure@^7.15.4", "@babel/helper-annotate-as-pure@^7.16.0":
+ version "7.16.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.0.tgz#9a1f0ebcda53d9a2d00108c4ceace6a5d5f1f08d"
+ integrity sha512-ItmYF9vR4zA8cByDocY05o0LGUkp1zhbTQOH1NFyl5xXEqlTJQCEJjieriw+aFpxo16swMxUnUiKS7a/r4vtHg==
+ dependencies:
+ "@babel/types" "^7.16.0"
"@babel/helper-annotate-as-pure@^7.16.7":
version "7.16.7"
@@ -139,14 +141,6 @@
dependencies:
"@babel/types" "^7.16.7"
-"@babel/helper-builder-binary-assignment-operator-visitor@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.12.13.tgz#6bc20361c88b0a74d05137a65cac8d3cbf6f61fc"
- integrity sha512-CZOv9tGphhDRlVjVkAgm8Nhklm9RzSmWpX2my+t7Ua/KT616pEzXsQCjinzvkRvHWJ9itO4f296efroX23XCMA==
- dependencies:
- "@babel/helper-explode-assignable-expression" "^7.12.13"
- "@babel/types" "^7.12.13"
-
"@babel/helper-builder-binary-assignment-operator-visitor@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz#38d138561ea207f0f69eb1626a418e4f7e6a580b"
@@ -155,7 +149,7 @@
"@babel/helper-explode-assignable-expression" "^7.16.7"
"@babel/types" "^7.16.7"
-"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.13.8", "@babel/helper-compilation-targets@^7.14.5":
+"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.13.8":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.14.5.tgz#7a99c5d0967911e972fe2c3411f7d5b498498ecf"
integrity sha512-v+QtZqXEiOnpO6EYvlImB6zCD2Lel06RzOPzmkz/D/XgQiUu3C/Jb1LOqSt/AIA34TYi/Q+KlT8vTQrgdxkbLw==
@@ -165,7 +159,7 @@
browserslist "^4.16.6"
semver "^6.3.0"
-"@babel/helper-compilation-targets@^7.16.7":
+"@babel/helper-compilation-targets@^7.14.5", "@babel/helper-compilation-targets@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz#06e66c5f299601e6c7da350049315e83209d551b"
integrity sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA==
@@ -175,17 +169,30 @@
browserslist "^4.17.5"
semver "^6.3.0"
-"@babel/helper-create-class-features-plugin@^7.13.0", "@babel/helper-create-class-features-plugin@^7.14.6":
- version "7.14.6"
- resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.14.6.tgz#f114469b6c06f8b5c59c6c4e74621f5085362542"
- integrity sha512-Z6gsfGofTxH/+LQXqYEK45kxmcensbzmk/oi8DmaQytlQCgqNZt9XQF8iqlI/SeXWVjaMNxvYvzaYw+kh42mDg==
+"@babel/helper-create-class-features-plugin@^7.13.0":
+ version "7.17.1"
+ resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.1.tgz#9699f14a88833a7e055ce57dcd3ffdcd25186b21"
+ integrity sha512-JBdSr/LtyYIno/pNnJ75lBcqc3Z1XXujzPanHqjvvrhOA+DTceTFuJi8XjmWTZh4r3fsdfqaCMN0iZemdkxZHQ==
dependencies:
- "@babel/helper-annotate-as-pure" "^7.14.5"
- "@babel/helper-function-name" "^7.14.5"
- "@babel/helper-member-expression-to-functions" "^7.14.5"
- "@babel/helper-optimise-call-expression" "^7.14.5"
- "@babel/helper-replace-supers" "^7.14.5"
- "@babel/helper-split-export-declaration" "^7.14.5"
+ "@babel/helper-annotate-as-pure" "^7.16.7"
+ "@babel/helper-environment-visitor" "^7.16.7"
+ "@babel/helper-function-name" "^7.16.7"
+ "@babel/helper-member-expression-to-functions" "^7.16.7"
+ "@babel/helper-optimise-call-expression" "^7.16.7"
+ "@babel/helper-replace-supers" "^7.16.7"
+ "@babel/helper-split-export-declaration" "^7.16.7"
+
+"@babel/helper-create-class-features-plugin@^7.16.0":
+ version "7.16.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.0.tgz#090d4d166b342a03a9fec37ef4fd5aeb9c7c6a4b"
+ integrity sha512-XLwWvqEaq19zFlF5PTgOod4bUA+XbkR4WLQBct1bkzmxJGB0ZEJaoKF4c8cgH9oBtCDuYJ8BP5NB9uFiEgO5QA==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.16.0"
+ "@babel/helper-function-name" "^7.16.0"
+ "@babel/helper-member-expression-to-functions" "^7.16.0"
+ "@babel/helper-optimise-call-expression" "^7.16.0"
+ "@babel/helper-replace-supers" "^7.16.0"
+ "@babel/helper-split-export-declaration" "^7.16.0"
"@babel/helper-create-class-features-plugin@^7.16.10", "@babel/helper-create-class-features-plugin@^7.16.7":
version "7.17.0"
@@ -200,15 +207,7 @@
"@babel/helper-replace-supers" "^7.16.7"
"@babel/helper-split-export-declaration" "^7.16.7"
-"@babel/helper-create-regexp-features-plugin@^7.12.13":
- version "7.14.3"
- resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.14.3.tgz#149aa6d78c016e318c43e2409a0ae9c136a86688"
- integrity sha512-JIB2+XJrb7v3zceV2XzDhGIB902CmKGSpSl4q2C6agU9SNLG/2V1RtFRGPG1Ajh9STj3+q6zJMOC+N/pp2P9DA==
- dependencies:
- "@babel/helper-annotate-as-pure" "^7.12.13"
- regexpu-core "^4.7.1"
-
-"@babel/helper-create-regexp-features-plugin@^7.16.7":
+"@babel/helper-create-regexp-features-plugin@^7.12.13", "@babel/helper-create-regexp-features-plugin@^7.16.7":
version "7.17.0"
resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.0.tgz#1dcc7d40ba0c6b6b25618997c5dbfd310f186fe1"
integrity sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA==
@@ -216,6 +215,14 @@
"@babel/helper-annotate-as-pure" "^7.16.7"
regexpu-core "^5.0.1"
+"@babel/helper-create-regexp-features-plugin@^7.16.0":
+ version "7.16.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.0.tgz#06b2348ce37fccc4f5e18dcd8d75053f2a7c44ff"
+ integrity sha512-3DyG0zAFAZKcOp7aVr33ddwkxJ0Z0Jr5V99y3I690eYLpukJsJvAbzTy1ewoCqsML8SbIrjH14Jc/nSQ4TvNPA==
+ dependencies:
+ "@babel/helper-annotate-as-pure" "^7.16.0"
+ regexpu-core "^4.7.1"
+
"@babel/helper-define-polyfill-provider@^0.1.5":
version "0.1.5"
resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.1.5.tgz#3c2f91b7971b9fc11fe779c945c014065dea340e"
@@ -251,13 +258,6 @@
dependencies:
"@babel/types" "^7.16.7"
-"@babel/helper-explode-assignable-expression@^7.12.13":
- version "7.13.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.13.0.tgz#17b5c59ff473d9f956f40ef570cf3a76ca12657f"
- integrity sha512-qS0peLTDP8kOisG1blKbaoBg/o9OSa1qoumMjTK5pM+KDTtpxpsiubnCGP34vK8BXGcb2M9eigwgvoJryrzwWA==
- dependencies:
- "@babel/types" "^7.13.0"
-
"@babel/helper-explode-assignable-expression@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz#12a6d8522fdd834f194e868af6354e8650242b7a"
@@ -265,7 +265,7 @@
dependencies:
"@babel/types" "^7.16.7"
-"@babel/helper-function-name@^7.12.13", "@babel/helper-function-name@^7.14.5":
+"@babel/helper-function-name@^7.14.5":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.14.5.tgz#89e2c474972f15d8e233b52ee8c480e2cfcd50c4"
integrity sha512-Gjna0AsXWfFvrAuX+VKcN/aNNWonizBj39yGwUzVDVTlMYJMK2Wp6xdpy72mfArFq5uK+NOuexfzZlzI1z9+AQ==
@@ -274,6 +274,15 @@
"@babel/template" "^7.14.5"
"@babel/types" "^7.14.5"
+"@babel/helper-function-name@^7.16.0":
+ version "7.16.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.0.tgz#b7dd0797d00bbfee4f07e9c4ea5b0e30c8bb1481"
+ integrity sha512-BZh4mEk1xi2h4HFjWUXRQX5AEx4rvaZxHgax9gcjdLWdkjsY7MKt5p0otjsg5noXw+pB+clMCjw+aEVYADMjog==
+ dependencies:
+ "@babel/helper-get-function-arity" "^7.16.0"
+ "@babel/template" "^7.16.0"
+ "@babel/types" "^7.16.0"
+
"@babel/helper-function-name@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f"
@@ -283,27 +292,34 @@
"@babel/template" "^7.16.7"
"@babel/types" "^7.16.7"
-"@babel/helper-get-function-arity@^7.14.5":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.14.5.tgz#25fbfa579b0937eee1f3b805ece4ce398c431815"
- integrity sha512-I1Db4Shst5lewOM4V+ZKJzQ0JGGaZ6VY1jYvMghRjqs6DWgxLCIyFt30GlnKkfUeFLpJt2vzbMVEXVSXlIFYUg==
- dependencies:
- "@babel/types" "^7.14.5"
-
-"@babel/helper-get-function-arity@^7.16.7":
+"@babel/helper-get-function-arity@^7.14.5", "@babel/helper-get-function-arity@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419"
integrity sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw==
dependencies:
"@babel/types" "^7.16.7"
-"@babel/helper-hoist-variables@^7.13.0", "@babel/helper-hoist-variables@^7.14.5":
+"@babel/helper-get-function-arity@^7.16.0":
+ version "7.16.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.0.tgz#0088c7486b29a9cb5d948b1a1de46db66e089cfa"
+ integrity sha512-ASCquNcywC1NkYh/z7Cgp3w31YW8aojjYIlNg4VeJiHkqyP4AzIvr4qx7pYDb4/s8YcsZWqqOSxgkvjUz1kpDQ==
+ dependencies:
+ "@babel/types" "^7.16.0"
+
+"@babel/helper-hoist-variables@^7.14.5":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.14.5.tgz#e0dd27c33a78e577d7c8884916a3e7ef1f7c7f8d"
integrity sha512-R1PXiz31Uc0Vxy4OEOm07x0oSjKAdPPCh3tPivn/Eo8cvz6gveAeuyUUPB21Hoiif0uoPQSSdhIPS3352nvdyQ==
dependencies:
"@babel/types" "^7.14.5"
+"@babel/helper-hoist-variables@^7.16.0":
+ version "7.16.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.0.tgz#4c9023c2f1def7e28ff46fc1dbcd36a39beaa81a"
+ integrity sha512-1AZlpazjUR0EQZQv3sgRNfM9mEVWPK3M6vlalczA+EECcPz3XPh6VplbErL5UoMpChhSck5wAJHthlj1bYpcmg==
+ dependencies:
+ "@babel/types" "^7.16.0"
+
"@babel/helper-hoist-variables@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246"
@@ -311,12 +327,12 @@
dependencies:
"@babel/types" "^7.16.7"
-"@babel/helper-member-expression-to-functions@^7.14.5":
- version "7.14.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.14.7.tgz#97e56244beb94211fe277bd818e3a329c66f7970"
- integrity sha512-TMUt4xKxJn6ccjcOW7c4hlwyJArizskAhoSTOCkA0uZ+KghIaci0Qg9R043kUMWI9mtQfgny+NQ5QATnZ+paaA==
+"@babel/helper-member-expression-to-functions@^7.16.0":
+ version "7.16.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.0.tgz#29287040efd197c77636ef75188e81da8bccd5a4"
+ integrity sha512-bsjlBFPuWT6IWhl28EdrQ+gTvSvj5tqVP5Xeftp07SEuz5pLnsXZuDkDD3Rfcxy0IsHmbZ+7B2/9SHzxO0T+sQ==
dependencies:
- "@babel/types" "^7.14.5"
+ "@babel/types" "^7.16.0"
"@babel/helper-member-expression-to-functions@^7.16.7":
version "7.16.7"
@@ -325,13 +341,20 @@
dependencies:
"@babel/types" "^7.16.7"
-"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.13.12":
+"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.13":
version "7.13.12"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz#c6a369a6f3621cb25da014078684da9196b61977"
integrity sha512-4cVvR2/1B693IuOvSI20xqqa/+bl7lqAMR59R4iu39R9aOX8/JoYY1sFaNvUMyMBGnHdwvJgUrzNLoUZxXypxA==
dependencies:
"@babel/types" "^7.13.12"
+"@babel/helper-module-imports@^7.15.4":
+ version "7.16.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.0.tgz#90538e60b672ecf1b448f5f4f5433d37e79a3ec3"
+ integrity sha512-kkH7sWzKPq0xt3H1n+ghb4xEMP8k0U7XV3kkB+ZGy69kDk2ySFW1qPi06sjKzFY3t1j6XbJSqr4mF9L7CYVyhg==
+ dependencies:
+ "@babel/types" "^7.16.0"
+
"@babel/helper-module-imports@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437"
@@ -368,12 +391,12 @@
"@babel/traverse" "^7.16.7"
"@babel/types" "^7.16.7"
-"@babel/helper-optimise-call-expression@^7.12.13", "@babel/helper-optimise-call-expression@^7.14.5":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.14.5.tgz#f27395a8619e0665b3f0364cddb41c25d71b499c"
- integrity sha512-IqiLIrODUOdnPU9/F8ib1Fx2ohlgDhxnIDU7OEVi+kAbEZcyiF7BLU8W6PfvPi9LzztjS7kcbzbmL7oG8kD6VA==
+"@babel/helper-optimise-call-expression@^7.16.0":
+ version "7.16.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.0.tgz#cecdb145d70c54096b1564f8e9f10cd7d193b338"
+ integrity sha512-SuI467Gi2V8fkofm2JPnZzB/SUuXoJA5zXe/xzyPP2M04686RzFKFHPK6HDVN6JvWBIEW8tt9hPR7fXdn2Lgpw==
dependencies:
- "@babel/types" "^7.14.5"
+ "@babel/types" "^7.16.0"
"@babel/helper-optimise-call-expression@^7.16.7":
version "7.16.7"
@@ -392,15 +415,6 @@
resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5"
integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA==
-"@babel/helper-remap-async-to-generator@^7.13.0":
- version "7.13.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.13.0.tgz#376a760d9f7b4b2077a9dd05aa9c3927cadb2209"
- integrity sha512-pUQpFBE9JvC9lrQbpX0TmeNIy5s7GnZjna2lhhcHC7DzgBs6fWn722Y5cfwgrtrqc7NAJwMvOa0mKhq6XaE4jg==
- dependencies:
- "@babel/helper-annotate-as-pure" "^7.12.13"
- "@babel/helper-wrap-function" "^7.13.0"
- "@babel/types" "^7.13.0"
-
"@babel/helper-remap-async-to-generator@^7.16.8":
version "7.16.8"
resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz#29ffaade68a367e2ed09c90901986918d25e57e3"
@@ -410,17 +424,7 @@
"@babel/helper-wrap-function" "^7.16.8"
"@babel/types" "^7.16.8"
-"@babel/helper-replace-supers@^7.12.13", "@babel/helper-replace-supers@^7.13.0", "@babel/helper-replace-supers@^7.14.5":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.14.5.tgz#0ecc0b03c41cd567b4024ea016134c28414abb94"
- integrity sha512-3i1Qe9/8x/hCHINujn+iuHy+mMRLoc77b2nI9TB0zjH1hvn9qGlXjWlggdwUcju36PkPCy/lpM7LLUdcTyH4Ow==
- dependencies:
- "@babel/helper-member-expression-to-functions" "^7.14.5"
- "@babel/helper-optimise-call-expression" "^7.14.5"
- "@babel/traverse" "^7.14.5"
- "@babel/types" "^7.14.5"
-
-"@babel/helper-replace-supers@^7.16.7":
+"@babel/helper-replace-supers@^7.13.0", "@babel/helper-replace-supers@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz#e9f5f5f32ac90429c1a4bdec0f231ef0c2838ab1"
integrity sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw==
@@ -431,27 +435,23 @@
"@babel/traverse" "^7.16.7"
"@babel/types" "^7.16.7"
-"@babel/helper-simple-access@^7.12.13":
- version "7.13.12"
- resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.13.12.tgz#dd6c538afb61819d205a012c31792a39c7a5eaf6"
- integrity sha512-7FEjbrx5SL9cWvXioDbnlYTppcZGuCY6ow3/D5vMggb2Ywgu4dMrpTJX0JdQAIcRRUElOIxF3yEooa9gUb9ZbA==
+"@babel/helper-replace-supers@^7.16.0":
+ version "7.16.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.0.tgz#73055e8d3cf9bcba8ddb55cad93fedc860f68f17"
+ integrity sha512-TQxuQfSCdoha7cpRNJvfaYxxxzmbxXw/+6cS7V02eeDYyhxderSoMVALvwupA54/pZcOTtVeJ0xccp1nGWladA==
dependencies:
- "@babel/types" "^7.13.12"
+ "@babel/helper-member-expression-to-functions" "^7.16.0"
+ "@babel/helper-optimise-call-expression" "^7.16.0"
+ "@babel/traverse" "^7.16.0"
+ "@babel/types" "^7.16.0"
-"@babel/helper-simple-access@^7.16.7":
+"@babel/helper-simple-access@^7.12.13", "@babel/helper-simple-access@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz#d656654b9ea08dbb9659b69d61063ccd343ff0f7"
integrity sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g==
dependencies:
"@babel/types" "^7.16.7"
-"@babel/helper-skip-transparent-expression-wrappers@^7.12.1":
- version "7.12.1"
- resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.12.1.tgz#462dc63a7e435ade8468385c63d2b84cce4b3cbf"
- integrity sha512-Mf5AUuhG1/OCChOJ/HcADmvcHM42WJockombn8ATJG3OnyiSxBK/Mm5x78BQWvmtXZKHgbjdGL2kin/HOLlZGA==
- dependencies:
- "@babel/types" "^7.12.1"
-
"@babel/helper-skip-transparent-expression-wrappers@^7.16.0":
version "7.16.0"
resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz#0ee3388070147c3ae051e487eca3ebb0e2e8bb09"
@@ -459,49 +459,46 @@
dependencies:
"@babel/types" "^7.16.0"
-"@babel/helper-split-export-declaration@^7.12.13", "@babel/helper-split-export-declaration@^7.14.5":
+"@babel/helper-split-export-declaration@^7.12.13", "@babel/helper-split-export-declaration@^7.16.7":
+ version "7.16.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b"
+ integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==
+ dependencies:
+ "@babel/types" "^7.16.7"
+
+"@babel/helper-split-export-declaration@^7.14.5":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.14.5.tgz#22b23a54ef51c2b7605d851930c1976dd0bc693a"
integrity sha512-hprxVPu6e5Kdp2puZUmvOGjaLv9TCe58E/Fl6hRq4YiVQxIcNvuq6uTM2r1mT/oPskuS9CgR+I94sqAYv0NGKA==
dependencies:
"@babel/types" "^7.14.5"
-"@babel/helper-split-export-declaration@^7.16.7":
- version "7.16.7"
- resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b"
- integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==
+"@babel/helper-split-export-declaration@^7.16.0":
+ version "7.16.0"
+ resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.0.tgz#29672f43663e936df370aaeb22beddb3baec7438"
+ integrity sha512-0YMMRpuDFNGTHNRiiqJX19GjNXA4H0E8jZ2ibccfSxaCogbm3am5WN/2nQNj0YnQwGWM1J06GOcQ2qnh3+0paw==
dependencies:
- "@babel/types" "^7.16.7"
-
-"@babel/helper-validator-identifier@^7.12.11", "@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.9":
- version "7.14.9"
- resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.9.tgz#6654d171b2024f6d8ee151bf2509699919131d48"
- integrity sha512-pQYxPY0UP6IHISRitNe8bsijHex4TWZXi2HwKVsjPiltzlhse2znVcm9Ace510VT1kxIHjGJCZZQBX2gJDbo0g==
+ "@babel/types" "^7.16.0"
-"@babel/helper-validator-identifier@^7.16.7":
+"@babel/helper-validator-identifier@^7.12.11", "@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.9", "@babel/helper-validator-identifier@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad"
integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==
-"@babel/helper-validator-option@^7.12.17", "@babel/helper-validator-option@^7.14.5":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3"
- integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==
+"@babel/helper-validator-identifier@^7.15.7":
+ version "7.15.7"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389"
+ integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w==
-"@babel/helper-validator-option@^7.16.7":
+"@babel/helper-validator-option@^7.12.17", "@babel/helper-validator-option@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23"
integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==
-"@babel/helper-wrap-function@^7.13.0":
- version "7.13.0"
- resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.13.0.tgz#bdb5c66fda8526ec235ab894ad53a1235c79fcc4"
- integrity sha512-1UX9F7K3BS42fI6qd2A4BjKzgGjToscyZTdp1DjknHLCIvpgne6918io+aL5LXFcER/8QWiwpoY902pVEqgTXA==
- dependencies:
- "@babel/helper-function-name" "^7.12.13"
- "@babel/template" "^7.12.13"
- "@babel/traverse" "^7.13.0"
- "@babel/types" "^7.13.0"
+"@babel/helper-validator-option@^7.14.5":
+ version "7.14.5"
+ resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3"
+ integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow==
"@babel/helper-wrap-function@^7.16.8":
version "7.16.8"
@@ -540,6 +537,15 @@
chalk "^2.0.0"
js-tokens "^4.0.0"
+"@babel/highlight@^7.16.0":
+ version "7.16.0"
+ resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.0.tgz#6ceb32b2ca4b8f5f361fb7fd821e3fddf4a1725a"
+ integrity sha512-t8MH41kUQylBtu2+4IQA3atqevA2lRgqA2wyVB/YiWmsDSuylZZuXOUy9ric30hfzauEFfdsuk/eXTRrGrfd0g==
+ dependencies:
+ "@babel/helper-validator-identifier" "^7.15.7"
+ chalk "^2.0.0"
+ js-tokens "^4.0.0"
+
"@babel/highlight@^7.16.7":
version "7.16.10"
resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.10.tgz#744f2eb81579d6eea753c227b0f570ad785aba88"
@@ -554,6 +560,11 @@
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.7.tgz#6099720c8839ca865a2637e6c85852ead0bdb595"
integrity sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA==
+"@babel/parser@^7.16.0":
+ version "7.16.2"
+ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.2.tgz#3723cd5c8d8773eef96ce57ea1d9b7faaccd12ac"
+ integrity sha512-RUVpT0G2h6rOZwqLDTrKk7ksNv7YpAilTnYe1/Q+eDjxEceRMKVWbCsX7t8h6C1qCFi/1Y8WZjcEPBAFG27GPw==
+
"@babel/parser@^7.16.7", "@babel/parser@^7.17.0":
version "7.17.0"
resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.0.tgz#f0ac33eddbe214e4105363bb17c3341c5ffcc43c"
@@ -575,16 +586,7 @@
"@babel/helper-skip-transparent-expression-wrappers" "^7.16.0"
"@babel/plugin-proposal-optional-chaining" "^7.16.7"
-"@babel/plugin-proposal-async-generator-functions@^7.13.8":
- version "7.13.8"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.13.8.tgz#87aacb574b3bc4b5603f6fe41458d72a5a2ec4b1"
- integrity sha512-rPBnhj+WgoSmgq+4gQUtXx/vOcU+UYtjy1AA/aeD61Hwj410fwYyqfUcRP3lR8ucgliVJL/G7sXcNUecC75IXA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/helper-remap-async-to-generator" "^7.13.0"
- "@babel/plugin-syntax-async-generators" "^7.8.4"
-
-"@babel/plugin-proposal-async-generator-functions@^7.16.8":
+"@babel/plugin-proposal-async-generator-functions@^7.13.8", "@babel/plugin-proposal-async-generator-functions@^7.16.8":
version "7.16.8"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz#3bdd1ebbe620804ea9416706cd67d60787504bc8"
integrity sha512-71YHIvMuiuqWJQkebWJtdhQTfd4Q4mF76q2IX37uZPkG9+olBxsX+rH1vkhFto4UeJZ9dPY2s+mDvhDm1u2BGQ==
@@ -593,7 +595,7 @@
"@babel/helper-remap-async-to-generator" "^7.16.8"
"@babel/plugin-syntax-async-generators" "^7.8.4"
-"@babel/plugin-proposal-class-properties@^7.10.4", "@babel/plugin-proposal-class-properties@^7.13.0":
+"@babel/plugin-proposal-class-properties@^7.10.4":
version "7.13.0"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.13.0.tgz#146376000b94efd001e57a40a88a525afaab9f37"
integrity sha512-KnTDjFNC1g+45ka0myZNvSBFLhNCLN+GeGYLDEA8Oq7MZ6yMgfLoIRh86GRT0FjtJhZw8JyUskP9uvj5pHM9Zg==
@@ -601,7 +603,7 @@
"@babel/helper-create-class-features-plugin" "^7.13.0"
"@babel/helper-plugin-utils" "^7.13.0"
-"@babel/plugin-proposal-class-properties@^7.16.7":
+"@babel/plugin-proposal-class-properties@^7.13.0", "@babel/plugin-proposal-class-properties@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz#925cad7b3b1a2fcea7e59ecc8eb5954f961f91b0"
integrity sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww==
@@ -618,15 +620,7 @@
"@babel/helper-plugin-utils" "^7.16.7"
"@babel/plugin-syntax-class-static-block" "^7.14.5"
-"@babel/plugin-proposal-dynamic-import@^7.13.8":
- version "7.13.8"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.13.8.tgz#876a1f6966e1dec332e8c9451afda3bebcdf2e1d"
- integrity sha512-ONWKj0H6+wIRCkZi9zSbZtE/r73uOhMVHh256ys0UzfM7I3d4n+spZNWjOnJv2gzopumP2Wxi186vI8N0Y2JyQ==
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/plugin-syntax-dynamic-import" "^7.8.3"
-
-"@babel/plugin-proposal-dynamic-import@^7.16.7":
+"@babel/plugin-proposal-dynamic-import@^7.13.8", "@babel/plugin-proposal-dynamic-import@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz#c19c897eaa46b27634a00fee9fb7d829158704b2"
integrity sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg==
@@ -634,15 +628,7 @@
"@babel/helper-plugin-utils" "^7.16.7"
"@babel/plugin-syntax-dynamic-import" "^7.8.3"
-"@babel/plugin-proposal-export-namespace-from@^7.12.13":
- version "7.14.2"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.2.tgz#62542f94aa9ce8f6dba79eec698af22112253791"
- integrity sha512-sRxW3z3Zp3pFfLAgVEvzTFutTXax837oOatUIvSG9o5gRj9mKwm3br1Se5f4QalTQs9x4AzlA/HrCWbQIHASUQ==
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/plugin-syntax-export-namespace-from" "^7.8.3"
-
-"@babel/plugin-proposal-export-namespace-from@^7.16.7":
+"@babel/plugin-proposal-export-namespace-from@^7.12.13", "@babel/plugin-proposal-export-namespace-from@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz#09de09df18445a5786a305681423ae63507a6163"
integrity sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA==
@@ -650,15 +636,7 @@
"@babel/helper-plugin-utils" "^7.16.7"
"@babel/plugin-syntax-export-namespace-from" "^7.8.3"
-"@babel/plugin-proposal-json-strings@^7.13.8":
- version "7.13.8"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.13.8.tgz#bf1fb362547075afda3634ed31571c5901afef7b"
- integrity sha512-w4zOPKUFPX1mgvTmL/fcEqy34hrQ1CRcGxdphBc6snDnnqJ47EZDIyop6IwXzAC8G916hsIuXB2ZMBCExC5k7Q==
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/plugin-syntax-json-strings" "^7.8.3"
-
-"@babel/plugin-proposal-json-strings@^7.16.7":
+"@babel/plugin-proposal-json-strings@^7.13.8", "@babel/plugin-proposal-json-strings@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz#9732cb1d17d9a2626a08c5be25186c195b6fa6e8"
integrity sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ==
@@ -666,15 +644,7 @@
"@babel/helper-plugin-utils" "^7.16.7"
"@babel/plugin-syntax-json-strings" "^7.8.3"
-"@babel/plugin-proposal-logical-assignment-operators@^7.13.8":
- version "7.13.8"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.13.8.tgz#93fa78d63857c40ce3c8c3315220fd00bfbb4e1a"
- integrity sha512-aul6znYB4N4HGweImqKn59Su9RS8lbUIqxtXTOcAGtNIDczoEFv+l1EhmX8rUBp3G1jMjKJm8m0jXVp63ZpS4A==
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4"
-
-"@babel/plugin-proposal-logical-assignment-operators@^7.16.7":
+"@babel/plugin-proposal-logical-assignment-operators@^7.13.8", "@babel/plugin-proposal-logical-assignment-operators@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz#be23c0ba74deec1922e639832904be0bea73cdea"
integrity sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg==
@@ -682,15 +652,7 @@
"@babel/helper-plugin-utils" "^7.16.7"
"@babel/plugin-syntax-logical-assignment-operators" "^7.10.4"
-"@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8":
- version "7.13.8"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.13.8.tgz#3730a31dafd3c10d8ccd10648ed80a2ac5472ef3"
- integrity sha512-iePlDPBn//UhxExyS9KyeYU7RM9WScAG+D3Hhno0PLJebAEpDZMocbDe64eqynhNAnwz/vZoL/q/QB2T1OH39A==
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3"
-
-"@babel/plugin-proposal-nullish-coalescing-operator@^7.16.7":
+"@babel/plugin-proposal-nullish-coalescing-operator@^7.13.8", "@babel/plugin-proposal-nullish-coalescing-operator@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz#141fc20b6857e59459d430c850a0011e36561d99"
integrity sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ==
@@ -698,15 +660,7 @@
"@babel/helper-plugin-utils" "^7.16.7"
"@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3"
-"@babel/plugin-proposal-numeric-separator@^7.12.13":
- version "7.14.2"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.2.tgz#82b4cc06571143faf50626104b335dd71baa4f9e"
- integrity sha512-DcTQY9syxu9BpU3Uo94fjCB3LN9/hgPS8oUL7KrSW3bA2ePrKZZPJcc5y0hoJAM9dft3pGfErtEUvxXQcfLxUg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/plugin-syntax-numeric-separator" "^7.10.4"
-
-"@babel/plugin-proposal-numeric-separator@^7.16.7":
+"@babel/plugin-proposal-numeric-separator@^7.12.13", "@babel/plugin-proposal-numeric-separator@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz#d6b69f4af63fb38b6ca2558442a7fb191236eba9"
integrity sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw==
@@ -714,7 +668,7 @@
"@babel/helper-plugin-utils" "^7.16.7"
"@babel/plugin-syntax-numeric-separator" "^7.10.4"
-"@babel/plugin-proposal-object-rest-spread@^7.10.1", "@babel/plugin-proposal-object-rest-spread@^7.13.8":
+"@babel/plugin-proposal-object-rest-spread@^7.10.1":
version "7.14.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.14.7.tgz#5920a2b3df7f7901df0205974c0641b13fd9d363"
integrity sha512-082hsZz+sVabfmDWo1Oct1u1AgbKbUAyVgmX4otIc7bdsRgHBXwTwb3DpDmD4Eyyx6DNiuz5UAATT655k+kL5g==
@@ -725,7 +679,7 @@
"@babel/plugin-syntax-object-rest-spread" "^7.8.3"
"@babel/plugin-transform-parameters" "^7.14.5"
-"@babel/plugin-proposal-object-rest-spread@^7.16.7":
+"@babel/plugin-proposal-object-rest-spread@^7.13.8", "@babel/plugin-proposal-object-rest-spread@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.16.7.tgz#94593ef1ddf37021a25bdcb5754c4a8d534b01d8"
integrity sha512-3O0Y4+dw94HA86qSg9IHfyPktgR7q3gpNVAeiKQd+8jBKFaU5NQS1Yatgo4wY+UFNuLjvxcSmzcsHqrhgTyBUA==
@@ -736,15 +690,7 @@
"@babel/plugin-syntax-object-rest-spread" "^7.8.3"
"@babel/plugin-transform-parameters" "^7.16.7"
-"@babel/plugin-proposal-optional-catch-binding@^7.13.8":
- version "7.13.8"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.13.8.tgz#3ad6bd5901506ea996fc31bdcf3ccfa2bed71107"
- integrity sha512-0wS/4DUF1CuTmGo+NiaHfHcVSeSLj5S3e6RivPTg/2k3wOv3jO35tZ6/ZWsQhQMvdgI7CwphjQa/ccarLymHVA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
-
-"@babel/plugin-proposal-optional-catch-binding@^7.16.7":
+"@babel/plugin-proposal-optional-catch-binding@^7.13.8", "@babel/plugin-proposal-optional-catch-binding@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz#c623a430674ffc4ab732fd0a0ae7722b67cb74cf"
integrity sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA==
@@ -752,16 +698,7 @@
"@babel/helper-plugin-utils" "^7.16.7"
"@babel/plugin-syntax-optional-catch-binding" "^7.8.3"
-"@babel/plugin-proposal-optional-chaining@^7.13.8":
- version "7.13.8"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.13.8.tgz#e39df93efe7e7e621841babc197982e140e90756"
- integrity sha512-hpbBwbTgd7Cz1QryvwJZRo1U0k1q8uyBmeXOSQUjdg/A2TASkhR/rz7AyqZ/kS8kbpsNA80rOYbxySBJAqmhhQ==
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1"
- "@babel/plugin-syntax-optional-chaining" "^7.8.3"
-
-"@babel/plugin-proposal-optional-chaining@^7.16.7":
+"@babel/plugin-proposal-optional-chaining@^7.13.8", "@babel/plugin-proposal-optional-chaining@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz#7cd629564724816c0e8a969535551f943c64c39a"
integrity sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA==
@@ -770,15 +707,7 @@
"@babel/helper-skip-transparent-expression-wrappers" "^7.16.0"
"@babel/plugin-syntax-optional-chaining" "^7.8.3"
-"@babel/plugin-proposal-private-methods@^7.13.0":
- version "7.13.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.13.0.tgz#04bd4c6d40f6e6bbfa2f57e2d8094bad900ef787"
- integrity sha512-MXyyKQd9inhx1kDYPkFRVOBXQ20ES8Pto3T7UZ92xj2mY0EVD8oAVzeyYuVfy/mxAdTSIayOvg+aVzcHV2bn6Q==
- dependencies:
- "@babel/helper-create-class-features-plugin" "^7.13.0"
- "@babel/helper-plugin-utils" "^7.13.0"
-
-"@babel/plugin-proposal-private-methods@^7.16.11":
+"@babel/plugin-proposal-private-methods@^7.13.0", "@babel/plugin-proposal-private-methods@^7.16.11":
version "7.16.11"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz#e8df108288555ff259f4527dbe84813aac3a1c50"
integrity sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw==
@@ -796,15 +725,7 @@
"@babel/helper-plugin-utils" "^7.16.7"
"@babel/plugin-syntax-private-property-in-object" "^7.14.5"
-"@babel/plugin-proposal-unicode-property-regex@^7.12.13", "@babel/plugin-proposal-unicode-property-regex@^7.4.4":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.12.13.tgz#bebde51339be829c17aaaaced18641deb62b39ba"
- integrity sha512-XyJmZidNfofEkqFV5VC/bLabGmO5QzenPO/YOfGuEbgU+2sSwMmio3YLb4WtBgcmmdwZHyVyv8on77IUjQ5Gvg==
- dependencies:
- "@babel/helper-create-regexp-features-plugin" "^7.12.13"
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-proposal-unicode-property-regex@^7.16.7":
+"@babel/plugin-proposal-unicode-property-regex@^7.12.13", "@babel/plugin-proposal-unicode-property-regex@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz#635d18eb10c6214210ffc5ff4932552de08188a2"
integrity sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg==
@@ -812,6 +733,14 @@
"@babel/helper-create-regexp-features-plugin" "^7.16.7"
"@babel/helper-plugin-utils" "^7.16.7"
+"@babel/plugin-proposal-unicode-property-regex@^7.4.4":
+ version "7.16.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.0.tgz#890482dfc5ea378e42e19a71e709728cabf18612"
+ integrity sha512-ti7IdM54NXv29cA4+bNNKEMS4jLMCbJgl+Drv+FgYy0erJLAxNAIXcNjNjrRZEcWq0xJHsNVwQezskMFpF8N9g==
+ dependencies:
+ "@babel/helper-create-regexp-features-plugin" "^7.16.0"
+ "@babel/helper-plugin-utils" "^7.14.5"
+
"@babel/plugin-syntax-async-generators@^7.8.4":
version "7.8.4"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d"
@@ -854,13 +783,6 @@
dependencies:
"@babel/helper-plugin-utils" "^7.8.0"
-"@babel/plugin-syntax-jsx@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.13.tgz#044fb81ebad6698fe62c478875575bcbb9b70f15"
- integrity sha512-d4HM23Q1K7oq/SLNmG6mRt85l2csmQ0cHRaxRXjKW0YFdEXqlZ5kzFQKH5Uc3rDJECgu+yCRgPkG04Mm98R/1g==
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
"@babel/plugin-syntax-jsx@^7.16.0", "@babel/plugin-syntax-jsx@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.16.7.tgz#50b6571d13f764266a113d77c82b4a6508bbe665"
@@ -917,51 +839,28 @@
dependencies:
"@babel/helper-plugin-utils" "^7.14.5"
-"@babel/plugin-syntax-top-level-await@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.12.13.tgz#c5f0fa6e249f5b739727f923540cf7a806130178"
- integrity sha512-A81F9pDwyS7yM//KwbCSDqy3Uj4NMIurtplxphWxoYtNPov7cJsDkAFNNyVlIZ3jwGycVsurZ+LtOA8gZ376iQ==
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-syntax-top-level-await@^7.14.5":
+"@babel/plugin-syntax-top-level-await@^7.12.13", "@babel/plugin-syntax-top-level-await@^7.14.5":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c"
integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==
dependencies:
"@babel/helper-plugin-utils" "^7.14.5"
-"@babel/plugin-syntax-typescript@^7.14.5":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.14.5.tgz#b82c6ce471b165b5ce420cf92914d6fb46225716"
- integrity sha512-u6OXzDaIXjEstBRRoBCQ/uKQKlbuaeE5in0RvWdA4pN6AhqxTIwUsnHPU1CFZA/amYObMsuWhYfRl3Ch90HD0Q==
+"@babel/plugin-syntax-typescript@^7.16.0":
+ version "7.16.0"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.0.tgz#2feeb13d9334cc582ea9111d3506f773174179bb"
+ integrity sha512-Xv6mEXqVdaqCBfJFyeab0fH2DnUoMsDmhamxsSi4j8nLd4Vtw213WMJr55xxqipC/YVWyPY3K0blJncPYji+dQ==
dependencies:
"@babel/helper-plugin-utils" "^7.14.5"
-"@babel/plugin-transform-arrow-functions@^7.13.0":
- version "7.13.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.13.0.tgz#10a59bebad52d637a027afa692e8d5ceff5e3dae"
- integrity sha512-96lgJagobeVmazXFaDrbmCLQxBysKu7U6Do3mLsx27gf5Dk85ezysrs2BZUpXD703U/Su1xTBDxxar2oa4jAGg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
-
-"@babel/plugin-transform-arrow-functions@^7.16.7":
+"@babel/plugin-transform-arrow-functions@^7.13.0", "@babel/plugin-transform-arrow-functions@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz#44125e653d94b98db76369de9c396dc14bef4154"
integrity sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ==
dependencies:
"@babel/helper-plugin-utils" "^7.16.7"
-"@babel/plugin-transform-async-to-generator@^7.13.0":
- version "7.13.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.13.0.tgz#8e112bf6771b82bf1e974e5e26806c5c99aa516f"
- integrity sha512-3j6E004Dx0K3eGmhxVJxwwI89CTJrce7lg3UrtFuDAVQ/2+SJ/h/aSFOeE6/n0WB1GsOffsJp6MnPQNQ8nmwhg==
- dependencies:
- "@babel/helper-module-imports" "^7.12.13"
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/helper-remap-async-to-generator" "^7.13.0"
-
-"@babel/plugin-transform-async-to-generator@^7.16.8":
+"@babel/plugin-transform-async-to-generator@^7.13.0", "@babel/plugin-transform-async-to-generator@^7.16.8":
version "7.16.8"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz#b83dff4b970cf41f1b819f8b49cc0cfbaa53a808"
integrity sha512-MtmUmTJQHCnyJVrScNzNlofQJ3dLFuobYn3mwOTKHnSCMtbNsqvF71GQmJfFjdrXSsAA7iysFmYWw4bXZ20hOg==
@@ -970,48 +869,21 @@
"@babel/helper-plugin-utils" "^7.16.7"
"@babel/helper-remap-async-to-generator" "^7.16.8"
-"@babel/plugin-transform-block-scoped-functions@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.12.13.tgz#a9bf1836f2a39b4eb6cf09967739de29ea4bf4c4"
- integrity sha512-zNyFqbc3kI/fVpqwfqkg6RvBgFpC4J18aKKMmv7KdQ/1GgREapSJAykLMVNwfRGO3BtHj3YQZl8kxCXPcVMVeg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-block-scoped-functions@^7.16.7":
+"@babel/plugin-transform-block-scoped-functions@^7.12.13", "@babel/plugin-transform-block-scoped-functions@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz#4d0d57d9632ef6062cdf354bb717102ee042a620"
integrity sha512-JUuzlzmF40Z9cXyytcbZEZKckgrQzChbQJw/5PuEHYeqzCsvebDx0K0jWnIIVcmmDOAVctCgnYs0pMcrYj2zJg==
dependencies:
"@babel/helper-plugin-utils" "^7.16.7"
-"@babel/plugin-transform-block-scoping@^7.12.13":
- version "7.14.2"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.14.2.tgz#761cb12ab5a88d640ad4af4aa81f820e6b5fdf5c"
- integrity sha512-neZZcP19NugZZqNwMTH+KoBjx5WyvESPSIOQb4JHpfd+zPfqcH65RMu5xJju5+6q/Y2VzYrleQTr+b6METyyxg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
-
-"@babel/plugin-transform-block-scoping@^7.16.7":
+"@babel/plugin-transform-block-scoping@^7.12.13", "@babel/plugin-transform-block-scoping@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz#f50664ab99ddeaee5bc681b8f3a6ea9d72ab4f87"
integrity sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ==
dependencies:
"@babel/helper-plugin-utils" "^7.16.7"
-"@babel/plugin-transform-classes@^7.13.0":
- version "7.13.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.13.0.tgz#0265155075c42918bf4d3a4053134176ad9b533b"
- integrity sha512-9BtHCPUARyVH1oXGcSJD3YpsqRLROJx5ZNP6tN5vnk17N0SVf9WCtf8Nuh1CFmgByKKAIMstitKduoCmsaDK5g==
- dependencies:
- "@babel/helper-annotate-as-pure" "^7.12.13"
- "@babel/helper-function-name" "^7.12.13"
- "@babel/helper-optimise-call-expression" "^7.12.13"
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/helper-replace-supers" "^7.13.0"
- "@babel/helper-split-export-declaration" "^7.12.13"
- globals "^11.1.0"
-
-"@babel/plugin-transform-classes@^7.16.7":
+"@babel/plugin-transform-classes@^7.13.0", "@babel/plugin-transform-classes@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz#8f4b9562850cd973de3b498f1218796eb181ce00"
integrity sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ==
@@ -1025,43 +897,21 @@
"@babel/helper-split-export-declaration" "^7.16.7"
globals "^11.1.0"
-"@babel/plugin-transform-computed-properties@^7.13.0":
- version "7.13.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.13.0.tgz#845c6e8b9bb55376b1fa0b92ef0bdc8ea06644ed"
- integrity sha512-RRqTYTeZkZAz8WbieLTvKUEUxZlUTdmL5KGMyZj7FnMfLNKV4+r5549aORG/mgojRmFlQMJDUupwAMiF2Q7OUg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
-
-"@babel/plugin-transform-computed-properties@^7.16.7":
+"@babel/plugin-transform-computed-properties@^7.13.0", "@babel/plugin-transform-computed-properties@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz#66dee12e46f61d2aae7a73710f591eb3df616470"
integrity sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw==
dependencies:
"@babel/helper-plugin-utils" "^7.16.7"
-"@babel/plugin-transform-destructuring@^7.13.0":
- version "7.13.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.13.0.tgz#c5dce270014d4e1ebb1d806116694c12b7028963"
- integrity sha512-zym5em7tePoNT9s964c0/KU3JPPnuq7VhIxPRefJ4/s82cD+q1mgKfuGRDMCPL0HTyKz4dISuQlCusfgCJ86HA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
-
-"@babel/plugin-transform-destructuring@^7.16.7":
+"@babel/plugin-transform-destructuring@^7.13.0", "@babel/plugin-transform-destructuring@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.16.7.tgz#ca9588ae2d63978a4c29d3f33282d8603f618e23"
integrity sha512-VqAwhTHBnu5xBVDCvrvqJbtLUa++qZaWC0Fgr2mqokBlulZARGyIvZDoqbPlPaKImQ9dKAcCzbv+ul//uqu70A==
dependencies:
"@babel/helper-plugin-utils" "^7.16.7"
-"@babel/plugin-transform-dotall-regex@^7.12.13", "@babel/plugin-transform-dotall-regex@^7.4.4":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz#3f1601cc29905bfcb67f53910f197aeafebb25ad"
- integrity sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ==
- dependencies:
- "@babel/helper-create-regexp-features-plugin" "^7.12.13"
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-dotall-regex@^7.16.7":
+"@babel/plugin-transform-dotall-regex@^7.12.13", "@babel/plugin-transform-dotall-regex@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz#6b2d67686fab15fb6a7fd4bd895d5982cfc81241"
integrity sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ==
@@ -1069,29 +919,22 @@
"@babel/helper-create-regexp-features-plugin" "^7.16.7"
"@babel/helper-plugin-utils" "^7.16.7"
-"@babel/plugin-transform-duplicate-keys@^7.12.13":
+"@babel/plugin-transform-dotall-regex@^7.4.4":
version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.12.13.tgz#6f06b87a8b803fd928e54b81c258f0a0033904de"
- integrity sha512-NfADJiiHdhLBW3pulJlJI2NB0t4cci4WTZ8FtdIuNc2+8pslXdPtRRAEWqUY+m9kNOk2eRYbTAOipAxlrOcwwQ==
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.12.13.tgz#3f1601cc29905bfcb67f53910f197aeafebb25ad"
+ integrity sha512-foDrozE65ZFdUC2OfgeOCrEPTxdB3yjqxpXh8CH+ipd9CHd4s/iq81kcUpyH8ACGNEPdFqbtzfgzbT/ZGlbDeQ==
dependencies:
+ "@babel/helper-create-regexp-features-plugin" "^7.12.13"
"@babel/helper-plugin-utils" "^7.12.13"
-"@babel/plugin-transform-duplicate-keys@^7.16.7":
+"@babel/plugin-transform-duplicate-keys@^7.12.13", "@babel/plugin-transform-duplicate-keys@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz#2207e9ca8f82a0d36a5a67b6536e7ef8b08823c9"
integrity sha512-03DvpbRfvWIXyK0/6QiR1KMTWeT6OcQ7tbhjrXyFS02kjuX/mu5Bvnh5SDSWHxyawit2g5aWhKwI86EE7GUnTw==
dependencies:
"@babel/helper-plugin-utils" "^7.16.7"
-"@babel/plugin-transform-exponentiation-operator@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.12.13.tgz#4d52390b9a273e651e4aba6aee49ef40e80cd0a1"
- integrity sha512-fbUelkM1apvqez/yYx1/oICVnGo2KM5s63mhGylrmXUxK/IAXSIf87QIxVfZldWf4QsOafY6vV3bX8aMHSvNrA==
- dependencies:
- "@babel/helper-builder-binary-assignment-operator-visitor" "^7.12.13"
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-exponentiation-operator@^7.16.7":
+"@babel/plugin-transform-exponentiation-operator@^7.12.13", "@babel/plugin-transform-exponentiation-operator@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz#efa9862ef97e9e9e5f653f6ddc7b665e8536fe9b"
integrity sha512-8UYLSlyLgRixQvlYH3J2ekXFHDFLQutdy7FfFAMm3CPZ6q9wHCwnUyiXpQCe3gVVnQlHc5nsuiEVziteRNTXEA==
@@ -1099,29 +942,14 @@
"@babel/helper-builder-binary-assignment-operator-visitor" "^7.16.7"
"@babel/helper-plugin-utils" "^7.16.7"
-"@babel/plugin-transform-for-of@^7.13.0":
- version "7.13.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.13.0.tgz#c799f881a8091ac26b54867a845c3e97d2696062"
- integrity sha512-IHKT00mwUVYE0zzbkDgNRP6SRzvfGCYsOxIRz8KsiaaHCcT9BWIkO+H9QRJseHBLOGBZkHUdHiqj6r0POsdytg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
-
-"@babel/plugin-transform-for-of@^7.16.7":
+"@babel/plugin-transform-for-of@^7.13.0", "@babel/plugin-transform-for-of@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz#649d639d4617dff502a9a158c479b3b556728d8c"
integrity sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg==
dependencies:
"@babel/helper-plugin-utils" "^7.16.7"
-"@babel/plugin-transform-function-name@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.12.13.tgz#bb024452f9aaed861d374c8e7a24252ce3a50051"
- integrity sha512-6K7gZycG0cmIwwF7uMK/ZqeCikCGVBdyP2J5SKNCXO5EOHcqi+z7Jwf8AmyDNcBgxET8DrEtCt/mPKPyAzXyqQ==
- dependencies:
- "@babel/helper-function-name" "^7.12.13"
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-function-name@^7.16.7":
+"@babel/plugin-transform-function-name@^7.12.13", "@babel/plugin-transform-function-name@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz#5ab34375c64d61d083d7d2f05c38d90b97ec65cf"
integrity sha512-SU/C68YVwTRxqWj5kgsbKINakGag0KTgq9f2iZEXdStoAbOzLHEBRYzImmA6yFo8YZhJVflvXmIHUO7GWHmxxA==
@@ -1130,44 +958,21 @@
"@babel/helper-function-name" "^7.16.7"
"@babel/helper-plugin-utils" "^7.16.7"
-"@babel/plugin-transform-literals@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.12.13.tgz#2ca45bafe4a820197cf315794a4d26560fe4bdb9"
- integrity sha512-FW+WPjSR7hiUxMcKqyNjP05tQ2kmBCdpEpZHY1ARm96tGQCCBvXKnpjILtDplUnJ/eHZ0lALLM+d2lMFSpYJrQ==
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-literals@^7.16.7":
+"@babel/plugin-transform-literals@^7.12.13", "@babel/plugin-transform-literals@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz#254c9618c5ff749e87cb0c0cef1a0a050c0bdab1"
integrity sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ==
dependencies:
"@babel/helper-plugin-utils" "^7.16.7"
-"@babel/plugin-transform-member-expression-literals@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.12.13.tgz#5ffa66cd59b9e191314c9f1f803b938e8c081e40"
- integrity sha512-kxLkOsg8yir4YeEPHLuO2tXP9R/gTjpuTOjshqSpELUN3ZAg2jfDnKUvzzJxObun38sw3wm4Uu69sX/zA7iRvg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-member-expression-literals@^7.16.7":
+"@babel/plugin-transform-member-expression-literals@^7.12.13", "@babel/plugin-transform-member-expression-literals@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz#6e5dcf906ef8a098e630149d14c867dd28f92384"
integrity sha512-mBruRMbktKQwbxaJof32LT9KLy2f3gH+27a5XSuXo6h7R3vqltl0PgZ80C8ZMKw98Bf8bqt6BEVi3svOh2PzMw==
dependencies:
"@babel/helper-plugin-utils" "^7.16.7"
-"@babel/plugin-transform-modules-amd@^7.13.0":
- version "7.13.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.13.0.tgz#19f511d60e3d8753cc5a6d4e775d3a5184866cc3"
- integrity sha512-EKy/E2NHhY/6Vw5d1k3rgoobftcNUmp9fGjb9XZwQLtTctsRBOTRO7RHHxfIky1ogMN5BxN7p9uMA3SzPfotMQ==
- dependencies:
- "@babel/helper-module-transforms" "^7.13.0"
- "@babel/helper-plugin-utils" "^7.13.0"
- babel-plugin-dynamic-import-node "^2.3.3"
-
-"@babel/plugin-transform-modules-amd@^7.16.7":
+"@babel/plugin-transform-modules-amd@^7.13.0", "@babel/plugin-transform-modules-amd@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz#b28d323016a7daaae8609781d1f8c9da42b13186"
integrity sha512-KaaEtgBL7FKYwjJ/teH63oAmE3lP34N3kshz8mm4VMAw7U3PxjVwwUmxEFksbgsNUaO3wId9R2AVQYSEGRa2+g==
@@ -1176,17 +981,7 @@
"@babel/helper-plugin-utils" "^7.16.7"
babel-plugin-dynamic-import-node "^2.3.3"
-"@babel/plugin-transform-modules-commonjs@^7.13.8":
- version "7.13.8"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.13.8.tgz#7b01ad7c2dcf2275b06fa1781e00d13d420b3e1b"
- integrity sha512-9QiOx4MEGglfYZ4XOnU79OHr6vIWUakIj9b4mioN8eQIoEh+pf5p/zEB36JpDFWA12nNMiRf7bfoRvl9Rn79Bw==
- dependencies:
- "@babel/helper-module-transforms" "^7.13.0"
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/helper-simple-access" "^7.12.13"
- babel-plugin-dynamic-import-node "^2.3.3"
-
-"@babel/plugin-transform-modules-commonjs@^7.16.8":
+"@babel/plugin-transform-modules-commonjs@^7.13.8", "@babel/plugin-transform-modules-commonjs@^7.16.8":
version "7.16.8"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.16.8.tgz#cdee19aae887b16b9d331009aa9a219af7c86afe"
integrity sha512-oflKPvsLT2+uKQopesJt3ApiaIS2HW+hzHFcwRNtyDGieAeC/dIHZX8buJQ2J2X1rxGPy4eRcUijm3qcSPjYcA==
@@ -1196,18 +991,7 @@
"@babel/helper-simple-access" "^7.16.7"
babel-plugin-dynamic-import-node "^2.3.3"
-"@babel/plugin-transform-modules-systemjs@^7.13.8":
- version "7.13.8"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.13.8.tgz#6d066ee2bff3c7b3d60bf28dec169ad993831ae3"
- integrity sha512-hwqctPYjhM6cWvVIlOIe27jCIBgHCsdH2xCJVAYQm7V5yTMoilbVMi9f6wKg0rpQAOn6ZG4AOyvCqFF/hUh6+A==
- dependencies:
- "@babel/helper-hoist-variables" "^7.13.0"
- "@babel/helper-module-transforms" "^7.13.0"
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/helper-validator-identifier" "^7.12.11"
- babel-plugin-dynamic-import-node "^2.3.3"
-
-"@babel/plugin-transform-modules-systemjs@^7.16.7":
+"@babel/plugin-transform-modules-systemjs@^7.13.8", "@babel/plugin-transform-modules-systemjs@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.16.7.tgz#887cefaef88e684d29558c2b13ee0563e287c2d7"
integrity sha512-DuK5E3k+QQmnOqBR9UkusByy5WZWGRxfzV529s9nPra1GE7olmxfqO2FHobEOYSPIjPBTr4p66YDcjQnt8cBmw==
@@ -1218,15 +1002,7 @@
"@babel/helper-validator-identifier" "^7.16.7"
babel-plugin-dynamic-import-node "^2.3.3"
-"@babel/plugin-transform-modules-umd@^7.13.0":
- version "7.13.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.13.0.tgz#8a3d96a97d199705b9fd021580082af81c06e70b"
- integrity sha512-D/ILzAh6uyvkWjKKyFE/W0FzWwasv6vPTSqPcjxFqn6QpX3u8DjRVliq4F2BamO2Wee/om06Vyy+vPkNrd4wxw==
- dependencies:
- "@babel/helper-module-transforms" "^7.13.0"
- "@babel/helper-plugin-utils" "^7.13.0"
-
-"@babel/plugin-transform-modules-umd@^7.16.7":
+"@babel/plugin-transform-modules-umd@^7.13.0", "@babel/plugin-transform-modules-umd@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz#23dad479fa585283dbd22215bff12719171e7618"
integrity sha512-EMh7uolsC8O4xhudF2F6wedbSHm1HHZ0C6aJ7K67zcDNidMzVcxWdGr+htW9n21klm+bOn+Rx4CBsAntZd3rEQ==
@@ -1234,43 +1010,21 @@
"@babel/helper-module-transforms" "^7.16.7"
"@babel/helper-plugin-utils" "^7.16.7"
-"@babel/plugin-transform-named-capturing-groups-regex@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.12.13.tgz#2213725a5f5bbbe364b50c3ba5998c9599c5c9d9"
- integrity sha512-Xsm8P2hr5hAxyYblrfACXpQKdQbx4m2df9/ZZSQ8MAhsadw06+jW7s9zsSw6he+mJZXRlVMyEnVktJo4zjk1WA==
- dependencies:
- "@babel/helper-create-regexp-features-plugin" "^7.12.13"
-
-"@babel/plugin-transform-named-capturing-groups-regex@^7.16.8":
+"@babel/plugin-transform-named-capturing-groups-regex@^7.12.13", "@babel/plugin-transform-named-capturing-groups-regex@^7.16.8":
version "7.16.8"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.16.8.tgz#7f860e0e40d844a02c9dcf9d84965e7dfd666252"
integrity sha512-j3Jw+n5PvpmhRR+mrgIh04puSANCk/T/UA3m3P1MjJkhlK906+ApHhDIqBQDdOgL/r1UYpz4GNclTXxyZrYGSw==
dependencies:
"@babel/helper-create-regexp-features-plugin" "^7.16.7"
-"@babel/plugin-transform-new-target@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.12.13.tgz#e22d8c3af24b150dd528cbd6e685e799bf1c351c"
- integrity sha512-/KY2hbLxrG5GTQ9zzZSc3xWiOy379pIETEhbtzwZcw9rvuaVV4Fqy7BYGYOWZnaoXIQYbbJ0ziXLa/sKcGCYEQ==
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-new-target@^7.16.7":
+"@babel/plugin-transform-new-target@^7.12.13", "@babel/plugin-transform-new-target@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz#9967d89a5c243818e0800fdad89db22c5f514244"
integrity sha512-xiLDzWNMfKoGOpc6t3U+etCE2yRnn3SM09BXqWPIZOBpL2gvVrBWUKnsJx0K/ADi5F5YC5f8APFfWrz25TdlGg==
dependencies:
"@babel/helper-plugin-utils" "^7.16.7"
-"@babel/plugin-transform-object-super@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.12.13.tgz#b4416a2d63b8f7be314f3d349bd55a9c1b5171f7"
- integrity sha512-JzYIcj3XtYspZDV8j9ulnoMPZZnF/Cj0LUxPOjR89BdBVx+zYJI9MdMIlUZjbXDX+6YVeS6I3e8op+qQ3BYBoQ==
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
- "@babel/helper-replace-supers" "^7.12.13"
-
-"@babel/plugin-transform-object-super@^7.16.7":
+"@babel/plugin-transform-object-super@^7.12.13", "@babel/plugin-transform-object-super@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz#ac359cf8d32cf4354d27a46867999490b6c32a94"
integrity sha512-14J1feiQVWaGvRxj2WjyMuXS2jsBkgB3MdSN5HuC2G5nRspa5RK9COcs82Pwy5BuGcjb+fYaUj94mYcOj7rCvw==
@@ -1278,28 +1032,14 @@
"@babel/helper-plugin-utils" "^7.16.7"
"@babel/helper-replace-supers" "^7.16.7"
-"@babel/plugin-transform-parameters@^7.13.0", "@babel/plugin-transform-parameters@^7.14.5":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.14.5.tgz#49662e86a1f3ddccac6363a7dfb1ff0a158afeb3"
- integrity sha512-Tl7LWdr6HUxTmzQtzuU14SqbgrSKmaR77M0OKyq4njZLQTPfOvzblNKyNkGwOfEFCEx7KeYHQHDI0P3F02IVkA==
- dependencies:
- "@babel/helper-plugin-utils" "^7.14.5"
-
-"@babel/plugin-transform-parameters@^7.16.7":
+"@babel/plugin-transform-parameters@^7.13.0", "@babel/plugin-transform-parameters@^7.14.5", "@babel/plugin-transform-parameters@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz#a1721f55b99b736511cb7e0152f61f17688f331f"
integrity sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw==
dependencies:
"@babel/helper-plugin-utils" "^7.16.7"
-"@babel/plugin-transform-property-literals@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.12.13.tgz#4e6a9e37864d8f1b3bc0e2dce7bf8857db8b1a81"
- integrity sha512-nqVigwVan+lR+g8Fj8Exl0UQX2kymtjcWfMOYM1vTYEKujeyv2SkMgazf2qNcK7l4SDiKyTA/nHCPqL4e2zo1A==
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-property-literals@^7.16.7":
+"@babel/plugin-transform-property-literals@^7.12.13", "@babel/plugin-transform-property-literals@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz#2dadac85155436f22c696c4827730e0fe1057a55"
integrity sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw==
@@ -1313,46 +1053,21 @@
dependencies:
"@babel/helper-plugin-utils" "^7.16.7"
-"@babel/plugin-transform-react-display-name@^7.12.13":
- version "7.14.2"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.14.2.tgz#2e854544d42ab3bb9c21f84e153d62e800fbd593"
- integrity sha512-zCubvP+jjahpnFJvPaHPiGVfuVUjXHhFvJKQdNnsmSsiU9kR/rCZ41jHc++tERD2zV+p7Hr6is+t5b6iWTCqSw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
-
-"@babel/plugin-transform-react-display-name@^7.16.7":
+"@babel/plugin-transform-react-display-name@^7.12.13", "@babel/plugin-transform-react-display-name@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.16.7.tgz#7b6d40d232f4c0f550ea348593db3b21e2404340"
integrity sha512-qgIg8BcZgd0G/Cz916D5+9kqX0c7nPZyXaP8R2tLNN5tkyIZdG5fEwBrxwplzSnjC1jvQmyMNVwUCZPcbGY7Pg==
dependencies:
"@babel/helper-plugin-utils" "^7.16.7"
-"@babel/plugin-transform-react-jsx-development@^7.12.17":
- version "7.12.17"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.12.17.tgz#f510c0fa7cd7234153539f9a362ced41a5ca1447"
- integrity sha512-BPjYV86SVuOaudFhsJR1zjgxxOhJDt6JHNoD48DxWEIxUCAMjV1ys6DYw4SDYZh0b1QsS2vfIA9t/ZsQGsDOUQ==
- dependencies:
- "@babel/plugin-transform-react-jsx" "^7.12.17"
-
-"@babel/plugin-transform-react-jsx-development@^7.16.7":
+"@babel/plugin-transform-react-jsx-development@^7.12.17", "@babel/plugin-transform-react-jsx-development@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.16.7.tgz#43a00724a3ed2557ed3f276a01a929e6686ac7b8"
integrity sha512-RMvQWvpla+xy6MlBpPlrKZCMRs2AGiHOGHY3xRwl0pEeim348dDyxeH4xBsMPbIMhujeq7ihE702eM2Ew0Wo+A==
dependencies:
"@babel/plugin-transform-react-jsx" "^7.16.7"
-"@babel/plugin-transform-react-jsx@^7.12.17", "@babel/plugin-transform-react-jsx@^7.13.12":
- version "7.13.12"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.13.12.tgz#1df5dfaf0f4b784b43e96da6f28d630e775f68b3"
- integrity sha512-jcEI2UqIcpCqB5U5DRxIl0tQEProI2gcu+g8VTIqxLO5Iidojb4d77q+fwGseCvd8af/lJ9masp4QWzBXFE2xA==
- dependencies:
- "@babel/helper-annotate-as-pure" "^7.12.13"
- "@babel/helper-module-imports" "^7.13.12"
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/plugin-syntax-jsx" "^7.12.13"
- "@babel/types" "^7.13.12"
-
-"@babel/plugin-transform-react-jsx@^7.16.7":
+"@babel/plugin-transform-react-jsx@^7.13.12", "@babel/plugin-transform-react-jsx@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.16.7.tgz#86a6a220552afd0e4e1f0388a68a372be7add0d4"
integrity sha512-8D16ye66fxiE8m890w0BpPpngG9o9OVBBy0gH2E+2AR7qMR2ZpTYJEqLxAsoroenMId0p/wMW+Blc0meDgu0Ag==
@@ -1363,15 +1078,7 @@
"@babel/plugin-syntax-jsx" "^7.16.7"
"@babel/types" "^7.16.7"
-"@babel/plugin-transform-react-pure-annotations@^7.12.1":
- version "7.12.1"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.12.1.tgz#05d46f0ab4d1339ac59adf20a1462c91b37a1a42"
- integrity sha512-RqeaHiwZtphSIUZ5I85PEH19LOSzxfuEazoY7/pWASCAIBuATQzpSVD+eT6MebeeZT2F4eSL0u4vw6n4Nm0Mjg==
- dependencies:
- "@babel/helper-annotate-as-pure" "^7.10.4"
- "@babel/helper-plugin-utils" "^7.10.4"
-
-"@babel/plugin-transform-react-pure-annotations@^7.16.7":
+"@babel/plugin-transform-react-pure-annotations@^7.12.1", "@babel/plugin-transform-react-pure-annotations@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.16.7.tgz#232bfd2f12eb551d6d7d01d13fe3f86b45eb9c67"
integrity sha512-hs71ToC97k3QWxswh2ElzMFABXHvGiJ01IB1TbYQDGeWRKWz/MPUTh5jGExdHvosYKpnJW5Pm3S4+TA3FyX+GA==
@@ -1379,57 +1086,28 @@
"@babel/helper-annotate-as-pure" "^7.16.7"
"@babel/helper-plugin-utils" "^7.16.7"
-"@babel/plugin-transform-regenerator@^7.12.13":
- version "7.13.15"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.13.15.tgz#e5eb28945bf8b6563e7f818945f966a8d2997f39"
- integrity sha512-Bk9cOLSz8DiurcMETZ8E2YtIVJbFCPGW28DJWUakmyVWtQSm6Wsf0p4B4BfEr/eL2Nkhe/CICiUiMOCi1TPhuQ==
- dependencies:
- regenerator-transform "^0.14.2"
-
-"@babel/plugin-transform-regenerator@^7.16.7":
+"@babel/plugin-transform-regenerator@^7.12.13", "@babel/plugin-transform-regenerator@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.16.7.tgz#9e7576dc476cb89ccc5096fff7af659243b4adeb"
integrity sha512-mF7jOgGYCkSJagJ6XCujSQg+6xC1M77/03K2oBmVJWoFGNUtnVJO4WHKJk3dnPC8HCcj4xBQP1Egm8DWh3Pb3Q==
dependencies:
regenerator-transform "^0.14.2"
-"@babel/plugin-transform-reserved-words@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.12.13.tgz#7d9988d4f06e0fe697ea1d9803188aa18b472695"
- integrity sha512-xhUPzDXxZN1QfiOy/I5tyye+TRz6lA7z6xaT4CLOjPRMVg1ldRf0LHw0TDBpYL4vG78556WuHdyO9oi5UmzZBg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-reserved-words@^7.16.7":
+"@babel/plugin-transform-reserved-words@^7.12.13", "@babel/plugin-transform-reserved-words@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz#1d798e078f7c5958eec952059c460b220a63f586"
integrity sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg==
dependencies:
"@babel/helper-plugin-utils" "^7.16.7"
-"@babel/plugin-transform-shorthand-properties@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.12.13.tgz#db755732b70c539d504c6390d9ce90fe64aff7ad"
- integrity sha512-xpL49pqPnLtf0tVluuqvzWIgLEhuPpZzvs2yabUHSKRNlN7ScYU7aMlmavOeyXJZKgZKQRBlh8rHbKiJDraTSw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-shorthand-properties@^7.16.7":
+"@babel/plugin-transform-shorthand-properties@^7.12.13", "@babel/plugin-transform-shorthand-properties@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz#e8549ae4afcf8382f711794c0c7b6b934c5fbd2a"
integrity sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg==
dependencies:
"@babel/helper-plugin-utils" "^7.16.7"
-"@babel/plugin-transform-spread@^7.13.0":
- version "7.13.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.13.0.tgz#84887710e273c1815ace7ae459f6f42a5d31d5fd"
- integrity sha512-V6vkiXijjzYeFmQTr3dBxPtZYLPcUfY34DebOU27jIl2M/Y8Egm52Hw82CSjjPqd54GTlJs5x+CR7HeNr24ckg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
- "@babel/helper-skip-transparent-expression-wrappers" "^7.12.1"
-
-"@babel/plugin-transform-spread@^7.16.7":
+"@babel/plugin-transform-spread@^7.13.0", "@babel/plugin-transform-spread@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz#a303e2122f9f12e0105daeedd0f30fb197d8ff44"
integrity sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg==
@@ -1437,80 +1115,44 @@
"@babel/helper-plugin-utils" "^7.16.7"
"@babel/helper-skip-transparent-expression-wrappers" "^7.16.0"
-"@babel/plugin-transform-sticky-regex@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.12.13.tgz#760ffd936face73f860ae646fb86ee82f3d06d1f"
- integrity sha512-Jc3JSaaWT8+fr7GRvQP02fKDsYk4K/lYwWq38r/UGfaxo89ajud321NH28KRQ7xy1Ybc0VUE5Pz8psjNNDUglg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-sticky-regex@^7.16.7":
+"@babel/plugin-transform-sticky-regex@^7.12.13", "@babel/plugin-transform-sticky-regex@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz#c84741d4f4a38072b9a1e2e3fd56d359552e8660"
integrity sha512-NJa0Bd/87QV5NZZzTuZG5BPJjLYadeSZ9fO6oOUoL4iQx+9EEuw/eEM92SrsT19Yc2jgB1u1hsjqDtH02c3Drw==
dependencies:
"@babel/helper-plugin-utils" "^7.16.7"
-"@babel/plugin-transform-template-literals@^7.13.0":
- version "7.13.0"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.13.0.tgz#a36049127977ad94438dee7443598d1cefdf409d"
- integrity sha512-d67umW6nlfmr1iehCcBv69eSUSySk1EsIS8aTDX4Xo9qajAh6mYtcl4kJrBkGXuxZPEgVr7RVfAvNW6YQkd4Mw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.13.0"
-
-"@babel/plugin-transform-template-literals@^7.16.7":
+"@babel/plugin-transform-template-literals@^7.13.0", "@babel/plugin-transform-template-literals@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz#f3d1c45d28967c8e80f53666fc9c3e50618217ab"
integrity sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA==
dependencies:
"@babel/helper-plugin-utils" "^7.16.7"
-"@babel/plugin-transform-typeof-symbol@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.12.13.tgz#785dd67a1f2ea579d9c2be722de8c84cb85f5a7f"
- integrity sha512-eKv/LmUJpMnu4npgfvs3LiHhJua5fo/CysENxa45YCQXZwKnGCQKAg87bvoqSW1fFT+HA32l03Qxsm8ouTY3ZQ==
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-typeof-symbol@^7.16.7":
+"@babel/plugin-transform-typeof-symbol@^7.12.13", "@babel/plugin-transform-typeof-symbol@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz#9cdbe622582c21368bd482b660ba87d5545d4f7e"
integrity sha512-p2rOixCKRJzpg9JB4gjnG4gjWkWa89ZoYUnl9snJ1cWIcTH/hvxZqfO+WjG6T8DRBpctEol5jw1O5rA8gkCokQ==
dependencies:
"@babel/helper-plugin-utils" "^7.16.7"
-"@babel/plugin-transform-typescript@^7.14.5":
- version "7.14.6"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.14.6.tgz#6e9c2d98da2507ebe0a883b100cde3c7279df36c"
- integrity sha512-XlTdBq7Awr4FYIzqhmYY80WN0V0azF74DMPyFqVHBvf81ZUgc4X7ZOpx6O8eLDK6iM5cCQzeyJw0ynTaefixRA==
+"@babel/plugin-transform-typescript@^7.16.0":
+ version "7.16.1"
+ resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.16.1.tgz#cc0670b2822b0338355bc1b3d2246a42b8166409"
+ integrity sha512-NO4XoryBng06jjw/qWEU2LhcLJr1tWkhpMam/H4eas/CDKMX/b2/Ylb6EI256Y7+FVPCawwSM1rrJNOpDiz+Lg==
dependencies:
- "@babel/helper-create-class-features-plugin" "^7.14.6"
+ "@babel/helper-create-class-features-plugin" "^7.16.0"
"@babel/helper-plugin-utils" "^7.14.5"
- "@babel/plugin-syntax-typescript" "^7.14.5"
-
-"@babel/plugin-transform-unicode-escapes@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.12.13.tgz#840ced3b816d3b5127dd1d12dcedc5dead1a5e74"
- integrity sha512-0bHEkdwJ/sN/ikBHfSmOXPypN/beiGqjo+o4/5K+vxEFNPRPdImhviPakMKG4x96l85emoa0Z6cDflsdBusZbw==
- dependencies:
- "@babel/helper-plugin-utils" "^7.12.13"
+ "@babel/plugin-syntax-typescript" "^7.16.0"
-"@babel/plugin-transform-unicode-escapes@^7.16.7":
+"@babel/plugin-transform-unicode-escapes@^7.12.13", "@babel/plugin-transform-unicode-escapes@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz#da8717de7b3287a2c6d659750c964f302b31ece3"
integrity sha512-TAV5IGahIz3yZ9/Hfv35TV2xEm+kaBDaZQCn2S/hG9/CZ0DktxJv9eKfPc7yYCvOYR4JGx1h8C+jcSOvgaaI/Q==
dependencies:
"@babel/helper-plugin-utils" "^7.16.7"
-"@babel/plugin-transform-unicode-regex@^7.12.13":
- version "7.12.13"
- resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.12.13.tgz#b52521685804e155b1202e83fc188d34bb70f5ac"
- integrity sha512-mDRzSNY7/zopwisPZ5kM9XKCfhchqIYwAKRERtEnhYscZB79VRekuRSoYbN0+KVe3y8+q1h6A4svXtP7N+UoCA==
- dependencies:
- "@babel/helper-create-regexp-features-plugin" "^7.12.13"
- "@babel/helper-plugin-utils" "^7.12.13"
-
-"@babel/plugin-transform-unicode-regex@^7.16.7":
+"@babel/plugin-transform-unicode-regex@^7.12.13", "@babel/plugin-transform-unicode-regex@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz#0f7aa4a501198976e25e82702574c34cfebe9ef2"
integrity sha512-oC5tYYKw56HO75KZVLQ+R/Nl3Hro9kf8iG0hXoaHP7tjAyCpvqBiSNe6vGrZni1Z6MggmUOC6A7VP7AVmw225Q==
@@ -1672,18 +1314,7 @@
core-js-compat "^3.20.2"
semver "^6.3.0"
-"@babel/preset-modules@^0.1.4":
- version "0.1.4"
- resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.4.tgz#362f2b68c662842970fdb5e254ffc8fc1c2e415e"
- integrity sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg==
- dependencies:
- "@babel/helper-plugin-utils" "^7.0.0"
- "@babel/plugin-proposal-unicode-property-regex" "^7.4.4"
- "@babel/plugin-transform-dotall-regex" "^7.4.4"
- "@babel/types" "^7.4.4"
- esutils "^2.0.2"
-
-"@babel/preset-modules@^0.1.5":
+"@babel/preset-modules@^0.1.4", "@babel/preset-modules@^0.1.5":
version "0.1.5"
resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9"
integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA==
@@ -1719,18 +1350,18 @@
"@babel/plugin-transform-react-pure-annotations" "^7.16.7"
"@babel/preset-typescript@^7.8.3":
- version "7.14.5"
- resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.14.5.tgz#aa98de119cf9852b79511f19e7f44a2d379bcce0"
- integrity sha512-u4zO6CdbRKbS9TypMqrlGH7sd2TAJppZwn3c/ZRLeO/wGsbddxgbPDUZVNrie3JWYLQ9vpineKlsrWFvO6Pwkw==
+ version "7.16.0"
+ resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.16.0.tgz#b0b4f105b855fb3d631ec036cdc9d1ffd1fa5eac"
+ integrity sha512-txegdrZYgO9DlPbv+9QOVpMnKbOtezsLHWsnsRF4AjbSIsVaujrq1qg8HK0mxQpWv0jnejt0yEoW1uWpvbrDTg==
dependencies:
"@babel/helper-plugin-utils" "^7.14.5"
"@babel/helper-validator-option" "^7.14.5"
- "@babel/plugin-transform-typescript" "^7.14.5"
+ "@babel/plugin-transform-typescript" "^7.16.0"
"@babel/runtime@^7.0.0", "@babel/runtime@^7.12.0", "@babel/runtime@^7.13.10", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.0", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7":
- version "7.14.0"
- resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.0.tgz#46794bc20b612c5f75e62dd071e24dfd95f1cbe6"
- integrity sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==
+ version "7.16.0"
+ resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.0.tgz#e27b977f2e2088ba24748bf99b5e1dece64e4f0b"
+ integrity sha512-Nht8L0O8YCktmsDV6FqFue7vQLRx3Hb0B37lS5y0jDRqRxlBG4wIJHnf9/bgSE2UyipKFA01YtS+npRdTWBUyw==
dependencies:
regenerator-runtime "^0.13.4"
@@ -1748,7 +1379,7 @@
dependencies:
regenerator-runtime "^0.13.4"
-"@babel/template@^7.12.13", "@babel/template@^7.14.5":
+"@babel/template@^7.12.13":
version "7.14.5"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.14.5.tgz#a9bc9d8b33354ff6e55a9c60d1109200a68974f4"
integrity sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g==
@@ -1757,7 +1388,7 @@
"@babel/parser" "^7.14.5"
"@babel/types" "^7.14.5"
-"@babel/template@^7.16.7":
+"@babel/template@^7.14.5", "@babel/template@^7.16.7":
version "7.16.7"
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155"
integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==
@@ -1766,7 +1397,16 @@
"@babel/parser" "^7.16.7"
"@babel/types" "^7.16.7"
-"@babel/traverse@^7.13.0", "@babel/traverse@^7.14.5", "@babel/traverse@^7.4.5":
+"@babel/template@^7.16.0":
+ version "7.16.0"
+ resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.0.tgz#d16a35ebf4cd74e202083356fab21dd89363ddd6"
+ integrity sha512-MnZdpFD/ZdYhXwiunMqqgyZyucaYsbL0IrjoGjaVhGilz+x8YB++kRfygSOIj1yOtWKPlx7NBp+9I1RQSgsd5A==
+ dependencies:
+ "@babel/code-frame" "^7.16.0"
+ "@babel/parser" "^7.16.0"
+ "@babel/types" "^7.16.0"
+
+"@babel/traverse@^7.13.0", "@babel/traverse@^7.4.5":
version "7.14.7"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.7.tgz#64007c9774cfdc3abd23b0780bc18a3ce3631753"
integrity sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ==
@@ -1781,6 +1421,21 @@
debug "^4.1.0"
globals "^11.1.0"
+"@babel/traverse@^7.16.0":
+ version "7.16.0"
+ resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.0.tgz#965df6c6bfc0a958c1e739284d3c9fa4a6e3c45b"
+ integrity sha512-qQ84jIs1aRQxaGaxSysII9TuDaguZ5yVrEuC0BN2vcPlalwfLovVmCjbFDPECPXcYM/wLvNFfp8uDOliLxIoUQ==
+ dependencies:
+ "@babel/code-frame" "^7.16.0"
+ "@babel/generator" "^7.16.0"
+ "@babel/helper-function-name" "^7.16.0"
+ "@babel/helper-hoist-variables" "^7.16.0"
+ "@babel/helper-split-export-declaration" "^7.16.0"
+ "@babel/parser" "^7.16.0"
+ "@babel/types" "^7.16.0"
+ debug "^4.1.0"
+ globals "^11.1.0"
+
"@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.17.0":
version "7.17.0"
resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.0.tgz#3143e5066796408ccc880a33ecd3184f3e75cd30"
@@ -1797,15 +1452,7 @@
debug "^4.1.0"
globals "^11.1.0"
-"@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.13.0", "@babel/types@^7.13.12", "@babel/types@^7.14.5", "@babel/types@^7.4.4":
- version "7.15.4"
- resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.4.tgz#74eeb86dbd6748d2741396557b9860e57fce0a0d"
- integrity sha512-0f1HJFuGmmbrKTCZtbm3cU+b/AqdEYk5toj5iQur58xkVMlS0JWaKxTBSmCXd47uiN7vbcozAupm6Mvs80GNhw==
- dependencies:
- "@babel/helper-validator-identifier" "^7.14.9"
- to-fast-properties "^2.0.0"
-
-"@babel/types@^7.12.6", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0":
+"@babel/types@^7.12.6", "@babel/types@^7.13.12", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0":
version "7.17.0"
resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b"
integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==
@@ -1813,6 +1460,14 @@
"@babel/helper-validator-identifier" "^7.16.7"
to-fast-properties "^2.0.0"
+"@babel/types@^7.13.0", "@babel/types@^7.14.5", "@babel/types@^7.4.4":
+ version "7.15.4"
+ resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.4.tgz#74eeb86dbd6748d2741396557b9860e57fce0a0d"
+ integrity sha512-0f1HJFuGmmbrKTCZtbm3cU+b/AqdEYk5toj5iQur58xkVMlS0JWaKxTBSmCXd47uiN7vbcozAupm6Mvs80GNhw==
+ dependencies:
+ "@babel/helper-validator-identifier" "^7.14.9"
+ to-fast-properties "^2.0.0"
+
"@colors/colors@1.5.0":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9"
@@ -1831,9 +1486,9 @@
"@date-io/core" "^1.3.13"
"@discoveryjs/json-ext@^0.5.0":
- version "0.5.3"
- resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.3.tgz#90420f9f9c6d3987f176a19a7d8e764271a2f55d"
- integrity sha512-Fxt+AfXgjMoin2maPIYzFZnQjAXjAL0PHscM5pRTtatFqB+vZxAM9tLp2Optnuw3QOQC40jTNeGYFOMvyf7v9g==
+ version "0.5.5"
+ resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.5.tgz#9283c9ce5b289a3c4f61c12757469e59377f81f3"
+ integrity sha512-6nFkfkmSeV/rqSaS4oWHgmpnYw194f6hmWF5is6b0J1naJZoiD0NTc9AiUwPHvWsowkjuHErCZT1wa0jg+BLIA==
"@emotion/cache@^10.0.27":
version "10.0.29"
@@ -1845,16 +1500,16 @@
"@emotion/utils" "0.11.3"
"@emotion/weak-memoize" "0.2.5"
-"@emotion/cache@^11.4.0":
- version "11.4.0"
- resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.4.0.tgz#293fc9d9a7a38b9aad8e9337e5014366c3b09ac0"
- integrity sha512-Zx70bjE7LErRO9OaZrhf22Qye1y4F7iDl+ITjet0J+i+B88PrAOBkKvaAWhxsZf72tDLajwCgfCjJ2dvH77C3g==
+"@emotion/cache@^11.4.0", "@emotion/cache@^11.5.0":
+ version "11.5.0"
+ resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.5.0.tgz#a5eb78cbef8163939ee345e3ddf0af217b845e62"
+ integrity sha512-mAZ5QRpLriBtaj/k2qyrXwck6yeoz1V5lMt/jfj6igWU35yYlNKs2LziXVgvH81gnJZ+9QQNGelSsnuoAy6uIw==
dependencies:
"@emotion/memoize" "^0.7.4"
- "@emotion/sheet" "^1.0.0"
+ "@emotion/sheet" "^1.0.3"
"@emotion/utils" "^1.0.0"
"@emotion/weak-memoize" "^0.2.5"
- stylis "^4.0.3"
+ stylis "^4.0.10"
"@emotion/cache@^11.7.1":
version "11.7.1"
@@ -1918,14 +1573,14 @@
integrity sha512-igX9a37DR2ZPGYtV6suZ6whr8pTFtyHL3K/oLUotxpSVO2ASaprmAe2Dkq7tBo7CRY7MMDrAa9nuQP9/YG8FxQ==
"@emotion/react@^11.1.1", "@emotion/react@^11.1.5":
- version "11.4.0"
- resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.4.0.tgz#2465ad7b073a691409b88dfd96dc17097ddad9b7"
- integrity sha512-4XklWsl9BdtatLoJpSjusXhpKv9YVteYKh9hPKP1Sxl+mswEFoUe0WtmtWjxEjkA51DQ2QRMCNOvKcSlCQ7ivg==
+ version "11.5.0"
+ resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.5.0.tgz#19b5771bbfbda5e8517e948a2d9064810f0022bd"
+ integrity sha512-MYq/bzp3rYbee4EMBORCn4duPQfgpiEB5XzrZEBnUZAL80Qdfr7CEv/T80jwaTl/dnZmt9SnTa8NkTrwFNpLlw==
dependencies:
"@babel/runtime" "^7.13.10"
- "@emotion/cache" "^11.4.0"
+ "@emotion/cache" "^11.5.0"
"@emotion/serialize" "^1.0.2"
- "@emotion/sheet" "^1.0.1"
+ "@emotion/sheet" "^1.0.3"
"@emotion/utils" "^1.0.0"
"@emotion/weak-memoize" "^0.2.5"
hoist-non-react-statics "^3.3.1"
@@ -1957,10 +1612,10 @@
resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-0.9.4.tgz#894374bea39ec30f489bbfc3438192b9774d32e5"
integrity sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA==
-"@emotion/sheet@^1.0.0", "@emotion/sheet@^1.0.1":
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.0.1.tgz#245f54abb02dfd82326e28689f34c27aa9b2a698"
- integrity sha512-GbIvVMe4U+Zc+929N1V7nW6YYJtidj31lidSmdYcWozwoBIObXBnaJkKNDjZrLm9Nc0BR+ZyHNaRZxqNZbof5g==
+"@emotion/sheet@^1.0.1", "@emotion/sheet@^1.0.3":
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.0.3.tgz#00c326cd7985c5ccb8fe2c1b592886579dcfab8f"
+ integrity sha512-YoX5GyQ4db7LpbmXHMuc8kebtBGP6nZfRC5Z13OKJMixBEwdZrJ914D6yJv/P+ZH/YY3F5s89NYX2hlZAf3SRQ==
"@emotion/sheet@^1.1.0":
version "1.1.0"
@@ -2010,15 +1665,15 @@
resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46"
integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA==
-"@eslint/eslintrc@^0.4.0":
- version "0.4.0"
- resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.0.tgz#99cc0a0584d72f1df38b900fb062ba995f395547"
- integrity sha512-2ZPCc+uNbjV5ERJr+aKSPRwZgKd2z11x0EgLvb1PURmUrn9QNRXFqje0Ldq454PfAVyaJYyrDvvIKSFP4NnBog==
+"@eslint/eslintrc@^0.4.3":
+ version "0.4.3"
+ resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c"
+ integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==
dependencies:
ajv "^6.12.4"
debug "^4.1.1"
espree "^7.3.0"
- globals "^12.1.0"
+ globals "^13.9.0"
ignore "^4.0.6"
import-fresh "^3.2.1"
js-yaml "^3.13.1"
@@ -2035,6 +1690,20 @@
resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.2.tgz#30aa825f11d438671d585bd44e7fd564535fc210"
integrity sha512-82cpyJyKRoQoRi+14ibCeGPu0CwypgtBAdBhq1WfvagpCZNKqwXbKwXllYSMG91DhmG4jt9gN8eP6lGOtozuaw==
+"@humanwhocodes/config-array@^0.5.0":
+ version "0.5.0"
+ resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9"
+ integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==
+ dependencies:
+ "@humanwhocodes/object-schema" "^1.2.0"
+ debug "^4.1.1"
+ minimatch "^3.0.4"
+
+"@humanwhocodes/object-schema@^1.2.0":
+ version "1.2.1"
+ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45"
+ integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==
+
"@istanbuljs/schema@^0.1.2":
version "0.1.3"
resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98"
@@ -2090,9 +1759,9 @@
react-is "^16.8.0 || ^17.0.0"
"@material-ui/pickers@^3.2.10":
- version "3.2.10"
- resolved "https://registry.yarnpkg.com/@material-ui/pickers/-/pickers-3.2.10.tgz#19df024895876eb0ec7cd239bbaea595f703f0ae"
- integrity sha512-B8G6Obn5S3RCl7hwahkQj9sKUapwXWFjiaz/Bsw1fhYFdNMnDUolRiWQSoKPb1/oKe37Dtfszoywi1Ynbo3y8w==
+ version "3.3.10"
+ resolved "https://registry.yarnpkg.com/@material-ui/pickers/-/pickers-3.3.10.tgz#f1b0f963348cc191645ef0bdeff7a67c6aa25485"
+ integrity sha512-hS4pxwn1ZGXVkmgD4tpFpaumUaAg2ZzbTrxltfC5yPw4BJV+mGkfnQOB4VpWEYZw2jv65Z0wLwDE/piQiPPZ3w==
dependencies:
"@babel/runtime" "^7.6.0"
"@date-io/core" "1.x"
@@ -2234,25 +1903,25 @@
prop-types "^15.7.2"
react-is "^17.0.2"
-"@nodelib/fs.scandir@2.1.4":
- version "2.1.4"
- resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.4.tgz#d4b3549a5db5de2683e0c1071ab4f140904bbf69"
- integrity sha512-33g3pMJk3bg5nXbL/+CY6I2eJDzZAni49PfJnL5fghPTggPvBd/pFNSgJsdAgWptuFu7qq/ERvOYFlhvsLTCKA==
+"@nodelib/fs.scandir@2.1.5":
+ version "2.1.5"
+ resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
+ integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==
dependencies:
- "@nodelib/fs.stat" "2.0.4"
+ "@nodelib/fs.stat" "2.0.5"
run-parallel "^1.1.9"
-"@nodelib/fs.stat@2.0.4", "@nodelib/fs.stat@^2.0.2":
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.4.tgz#a3f2dd61bab43b8db8fa108a121cfffe4c676655"
- integrity sha512-IYlHJA0clt2+Vg7bccq+TzRdJvv19c2INqBSsoOLp1je7xjtr7J26+WXR72MCdvU9q1qTzIWDfhMf+DRvQJK4Q==
+"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2":
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b"
+ integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
"@nodelib/fs.walk@^1.2.3":
- version "1.2.6"
- resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.6.tgz#cce9396b30aa5afe9e3756608f5831adcb53d063"
- integrity sha512-8Broas6vTtW4GIXTAHDoE32hnN2M5ykgCpWGbuXHQ15vEMqr23pB76e/GZcYsZCHALv50ktd24qhEyKr6wBtow==
+ version "1.2.8"
+ resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a"
+ integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==
dependencies:
- "@nodelib/fs.scandir" "2.1.4"
+ "@nodelib/fs.scandir" "2.1.5"
fastq "^1.6.0"
"@npmcli/fs@^1.0.0":
@@ -2271,20 +1940,20 @@
mkdirp "^1.0.4"
rimraf "^3.0.2"
-"@polka/url@^1.0.0-next.15":
- version "1.0.0-next.15"
- resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.15.tgz#6a9d143f7f4f49db2d782f9e1c8839a29b43ae23"
- integrity sha512-15spi3V28QdevleWBNXE4pIls3nFZmBbUGrW9IVPwiQczuSb9n76TCB4bsk8TSel+I1OkHEdPhu5QKMfY6rQHA==
+"@polka/url@^1.0.0-next.20":
+ version "1.0.0-next.21"
+ resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.21.tgz#5de5a2385a35309427f6011992b544514d559aa1"
+ integrity sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==
"@popperjs/core@^2.11.4":
version "2.11.4"
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.4.tgz#d8c7b8db9226d2d7664553a0741ad7d0397ee503"
integrity sha512-q/ytXxO5NKvyT37pmisQAItCFqA7FD/vNb8dgaJy3/630Fsc+Mz9/9f2SziBoIZ30TJooXyTwZmhi1zjXmObYg==
-"@popperjs/core@^2.8.3":
- version "2.9.0"
- resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.9.0.tgz#32e63212293dd3efbb521cd35a5020ab66eaa546"
- integrity sha512-wjtKehFAIARq2OxK8j3JrggNlEslJfNuSm2ArteIbKyRMts2g0a7KzTxfRVNUM+O0gnBJ2hNV8nWPOYBgI1sew==
+"@popperjs/core@^2.9.0":
+ version "2.10.2"
+ resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.10.2.tgz#0798c03351f0dea1a5a4cabddf26a55a7cbee590"
+ integrity sha512-IXf3XA7+XyN7CP9gGh/XB0UxVMlvARGEgGXLubFICsUMGz6Q+DU+i4gGlpOxTjKvXjkJDJC8YdqdKkDj9qZHEQ==
"@projectstorm/geometry@^6.6.1":
version "6.6.1"
@@ -2331,12 +2000,17 @@
"@projectstorm/react-diagrams-defaults" "^6.6.1"
"@projectstorm/react-diagrams-routing" "^6.6.1"
+"@react-leaflet/core@^1.1.1":
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/@react-leaflet/core/-/core-1.1.1.tgz#827fd05bb542cf874116176d8ef48d5b12163f81"
+ integrity sha512-7PGLWa9MZ5x/cWy8EH2VzI4T8q5WpuHbixzCDXqixP/WyqwIrg5NDUPgYuFnB4IEIZF+6nA265mYzswFo/h1Pw==
+
"@simonwep/pickr@^1.5.1":
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/@simonwep/pickr/-/pickr-1.8.1.tgz#e136cbd9c345ddbb7d71eb14af544c798165d495"
- integrity sha512-3Q5+INWW0Py+/E9hgy0cyD0/0w/yGZbkxam6RzFVFDOEHgAqMVJR+x9znx58/ky/ZIvE/78FbH189yIC9h111A==
+ version "1.8.2"
+ resolved "https://registry.yarnpkg.com/@simonwep/pickr/-/pickr-1.8.2.tgz#96dc86675940d7cad63d69c22083dd1cbb9797cb"
+ integrity sha512-/l5w8BIkrpP6n1xsetx9MWPWlU6OblN5YgZZphxan0Tq4BByTCETL6lyIeY8lagalS2Nbt4F2W034KHLIiunKA==
dependencies:
- core-js "^3.12.1"
+ core-js "^3.15.1"
nanopop "^2.1.0"
"@sindresorhus/is@^0.7.0":
@@ -2349,6 +2023,11 @@
resolved "https://registry.yarnpkg.com/@socket.io/base64-arraybuffer/-/base64-arraybuffer-1.0.2.tgz#568d9beae00b0d835f4f8c53fd55714986492e61"
integrity sha512-dOlCBKnDw4iShaIsH/bxujKTM18+2TOAsYz+KSc11Am38H4q5Xw8Bbz97ZYdrVNM+um3p7w86Bvvmcn9q+5+eQ==
+"@socket.io/component-emitter@~3.0.0":
+ version "3.0.0"
+ resolved "https://registry.yarnpkg.com/@socket.io/component-emitter/-/component-emitter-3.0.0.tgz#8863915676f837d9dad7b76f50cb500c1e9422e9"
+ integrity sha512-2pTGuibAXJswAPJjaKisthqS/NOK5ypG4LYT6tEAV0S/mxW0zOIvYvGK0V8w8+SHxAm6vRMSjqSalFXeBAqs+Q==
+
"@sphinxxxx/color-conversion@^2.2.2":
version "2.2.2"
resolved "https://registry.yarnpkg.com/@sphinxxxx/color-conversion/-/color-conversion-2.2.2.tgz#03ecc29279e3c0c832f6185a5bfa3497858ac8ca"
@@ -2466,9 +2145,9 @@
react-transition-state "^1.1.3"
"@tippyjs/react@^4.2.0":
- version "4.2.3"
- resolved "https://registry.yarnpkg.com/@tippyjs/react/-/react-4.2.3.tgz#c2dbe9eb71bd9ffa3974f9ba8e3a4a6fc1538aed"
- integrity sha512-44vBapqROQI7Q5nDtX1MMAgcAV+3DsIi+m/45CxQ72C5LDNmNDq9h3f04x3NHMrUhWcfgfgjYA2EmeLSH/4eRg==
+ version "4.2.6"
+ resolved "https://registry.yarnpkg.com/@tippyjs/react/-/react-4.2.6.tgz#971677a599bf663f20bb1c60a62b9555b749cc71"
+ integrity sha512-91RicDR+H7oDSyPycI13q3b7o4O60wa2oRbjlz2fyRLmHImc4vyDwuUP8NtZaN0VARJY5hybvDYrFzhY9+Lbyw==
dependencies:
tippy.js "^6.3.1"
@@ -2490,9 +2169,9 @@
classnames "*"
"@types/component-emitter@^1.2.10":
- version "1.2.10"
- resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.10.tgz#ef5b1589b9f16544642e473db5ea5639107ef3ea"
- integrity sha512-bsjleuRKWmGqajMerkzox19aGbscQX5rmmvvXl3wlIp5gMG1HgkiwPxsN5p070fBDKTNSPgojVbuY1+HWMbFhg==
+ version "1.2.11"
+ resolved "https://registry.yarnpkg.com/@types/component-emitter/-/component-emitter-1.2.11.tgz#50d47d42b347253817a39709fef03ce66a108506"
+ integrity sha512-SRXjM+tfsSlA9VuG8hGO2nft2p8zjXCK1VcC6N4NXbBbYbSia9kzCChYQajIjzIqOOOuh5Ock6MmV2oux4jDZQ==
"@types/cookie@^0.4.1":
version "0.4.1"
@@ -2505,68 +2184,63 @@
integrity sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==
"@types/eslint-scope@^3.7.0":
- version "3.7.0"
- resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.0.tgz#4792816e31119ebd506902a482caec4951fabd86"
- integrity sha512-O/ql2+rrCUe2W2rs7wMR+GqPRcgB6UiqN5RhrR5xruFlY7l9YLMn0ZkDzjoHLeiFkR8MCQZVudUuuvQ2BLC9Qw==
+ version "3.7.1"
+ resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.1.tgz#8dc390a7b4f9dd9f1284629efce982e41612116e"
+ integrity sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g==
dependencies:
"@types/eslint" "*"
"@types/estree" "*"
"@types/eslint@*":
- version "7.2.7"
- resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.2.7.tgz#f7ef1cf0dceab0ae6f9a976a0a9af14ab1baca26"
- integrity sha512-EHXbc1z2GoQRqHaAT7+grxlTJ3WE2YNeD6jlpPoRc83cCoThRY+NUWjCUZaYmk51OICkPXn2hhphcWcWXgNW0Q==
+ version "7.28.2"
+ resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.28.2.tgz#0ff2947cdd305897c52d5372294e8c76f351db68"
+ integrity sha512-KubbADPkfoU75KgKeKLsFHXnU4ipH7wYg0TRT33NK3N3yiu7jlFAAoygIWBV+KbuHx/G+AvuGX6DllnK35gfJA==
dependencies:
"@types/estree" "*"
"@types/json-schema" "*"
-"@types/estree@*", "@types/estree@^0.0.46":
- version "0.0.46"
- resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.46.tgz#0fb6bfbbeabd7a30880504993369c4bf1deab1fe"
- integrity sha512-laIjwTQaD+5DukBZaygQ79K1Z0jb1bPEMRrkXSLjtCcZm+abyp5YbrqpSLzD42FwWW6gK/aS4NYpJ804nG2brg==
+"@types/estree@*", "@types/estree@^0.0.50":
+ version "0.0.50"
+ resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83"
+ integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw==
"@types/glob@^7.1.1":
- version "7.1.3"
- resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183"
- integrity sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==
+ version "7.2.0"
+ resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb"
+ integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==
dependencies:
"@types/minimatch" "*"
"@types/node" "*"
-"@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6":
- version "7.0.7"
- resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.7.tgz#98a993516c859eb0d5c4c8f098317a9ea68db9ad"
- integrity sha512-cxWFQVseBm6O9Gbw1IWb8r6OS4OhSt3hPZLkFApLjM8TEXROBuQGLAH2i2gZpcXdLBIrpXuTDhH7Vbm1iXmNGA==
+"@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8":
+ version "7.0.9"
+ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d"
+ integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ==
"@types/minimatch@*":
- version "3.0.4"
- resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.4.tgz#f0ec25dbf2f0e4b18647313ac031134ca5b24b21"
- integrity sha512-1z8k4wzFnNjVK/tlxvrWuK5WMt6mydWWP7+zvH5eFep4oj+UkrfiJTRtjCeBXNpwaA/FYqqtb4/QS4ianFpIRA==
+ version "3.0.5"
+ resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40"
+ integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==
"@types/node@*", "@types/node@>=10.0.0":
- version "14.14.32"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.32.tgz#90c5c4a8d72bbbfe53033f122341343249183448"
- integrity sha512-/Ctrftx/zp4m8JOujM5ZhwzlWLx22nbQJiVqz8/zE15gOeEW+uly3FSX4fGFpcfEvFzXcMCJwq9lGVWgyARXhg==
+ version "16.11.6"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.6.tgz#6bef7a2a0ad684cf6e90fcfe31cecabd9ce0a3ae"
+ integrity sha512-ua7PgUoeQFjmWPcoo9khiPum3Pd60k4/2ZGXt18sm2Slk0W0xZTqt5Y0Ny1NyBiN1EVQ/+FaF9NcY4Qe6rwk5w==
"@types/parse-json@^4.0.0":
version "4.0.0"
resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
-"@types/prop-types@*":
- version "15.7.3"
- resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7"
- integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==
-
-"@types/prop-types@^15.7.4":
+"@types/prop-types@*", "@types/prop-types@^15.7.4":
version "15.7.4"
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.4.tgz#fcf7205c25dff795ee79af1e30da2c9790808f11"
integrity sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==
"@types/q@^1.5.1":
- version "1.5.4"
- resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24"
- integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==
+ version "1.5.5"
+ resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.5.tgz#75a2a8e7d8ab4b230414505d92335d1dcb53a6df"
+ integrity sha512-L28j2FcJfSZOnL1WBjDYp2vUHCeIFlyYI/53EwD/rKUBQ7MtUUfbQWiyKJGpcnv4/WgrhWsFKrcPstcAt/J0tQ==
"@types/react-dom@^16.0.11":
version "16.9.14"
@@ -2596,7 +2270,7 @@
dependencies:
"@types/react" "*"
-"@types/react@*", "@types/react@^16":
+"@types/react@*":
version "16.14.10"
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.10.tgz#76bc1c42ed5ab0d2ab13e5c58faaccaad3449477"
integrity sha512-QadBsMyF6ldjEAXEhsmEW/L0uBDJT8yw7Qoe5sRnEKVrzMkiYoJwqoL5TKJOlArsn/wvIJM/XdVzkdL6+AS64Q==
@@ -2605,24 +2279,24 @@
"@types/scheduler" "*"
csstype "^3.0.2"
-"@types/react@^16.7.18":
- version "16.14.18"
- resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.18.tgz#b2bcea05ee244fde92d409f91bd888ca8e54b20f"
- integrity sha512-eeyqd1mqoG43mI0TvNKy9QNf1Tjz3DEOsRP3rlPo35OeMIt05I+v9RR8ZvL2GuYZeF2WAcLXJZMzu6zdz3VbtQ==
+"@types/react@^16", "@types/react@^16.7.18":
+ version "16.14.20"
+ resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.20.tgz#ff6e932ad71d92c27590e4a8667c7a53a7d0baad"
+ integrity sha512-SV7TaVc8e9E/5Xuv6TIyJ5VhQpZoVFJqX6IZgj5HZoFCtIDCArE3qXkcHlc6O/Ud4UwcMoX+tlvDA95YrKdLgA==
dependencies:
"@types/prop-types" "*"
"@types/scheduler" "*"
csstype "^3.0.2"
"@types/scheduler@*":
- version "0.16.1"
- resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.1.tgz#18845205e86ff0038517aab7a18a62a6b9f71275"
- integrity sha512-EaCxbanVeyxDRTQBkdLb3Bvl/HK7PBK6UJjsSixB0iHKoWxE5uu2Q/DgtpOhPIojN0Zl1whvOd7PoHs2P0s5eA==
+ version "0.16.2"
+ resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39"
+ integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==
"@types/styled-jsx@^2.2.8":
- version "2.2.8"
- resolved "https://registry.yarnpkg.com/@types/styled-jsx/-/styled-jsx-2.2.8.tgz#b50d13d8a3c34036282d65194554cf186bab7234"
- integrity sha512-Yjye9VwMdYeXfS71ihueWRSxrruuXTwKCbzue4+5b2rjnQ//AtyM7myZ1BEhNhBQ/nL/RE7bdToUoLln2miKvg==
+ version "2.2.9"
+ resolved "https://registry.yarnpkg.com/@types/styled-jsx/-/styled-jsx-2.2.9.tgz#e50b3f868c055bcbf9bc353eca6c10fdad32a53f"
+ integrity sha512-W/iTlIkGEyTBGTEvZCey8EgQlQ5l0DwMqi3iOXlLs2kyBwYTXHKEiU6IZ5EwoRwngL8/dGYuzezSup89ttVHLw==
dependencies:
"@types/react" "*"
@@ -2642,143 +2316,143 @@
underscore "^1.9.1"
url-join "^4.0.0"
-"@webassemblyjs/ast@1.11.0":
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.0.tgz#a5aa679efdc9e51707a4207139da57920555961f"
- integrity sha512-kX2W49LWsbthrmIRMbQZuQDhGtjyqXfEmmHyEi4XWnSZtPmxY0+3anPIzsnRb45VH/J55zlOfWvZuY47aJZTJg==
+"@webassemblyjs/ast@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7"
+ integrity sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==
dependencies:
- "@webassemblyjs/helper-numbers" "1.11.0"
- "@webassemblyjs/helper-wasm-bytecode" "1.11.0"
+ "@webassemblyjs/helper-numbers" "1.11.1"
+ "@webassemblyjs/helper-wasm-bytecode" "1.11.1"
-"@webassemblyjs/floating-point-hex-parser@1.11.0":
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.0.tgz#34d62052f453cd43101d72eab4966a022587947c"
- integrity sha512-Q/aVYs/VnPDVYvsCBL/gSgwmfjeCb4LW8+TMrO3cSzJImgv8lxxEPM2JA5jMrivE7LSz3V+PFqtMbls3m1exDA==
+"@webassemblyjs/floating-point-hex-parser@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f"
+ integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ==
-"@webassemblyjs/helper-api-error@1.11.0":
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.0.tgz#aaea8fb3b923f4aaa9b512ff541b013ffb68d2d4"
- integrity sha512-baT/va95eXiXb2QflSx95QGT5ClzWpGaa8L7JnJbgzoYeaA27FCvuBXU758l+KXWRndEmUXjP0Q5fibhavIn8w==
+"@webassemblyjs/helper-api-error@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16"
+ integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg==
-"@webassemblyjs/helper-buffer@1.11.0":
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.0.tgz#d026c25d175e388a7dbda9694e91e743cbe9b642"
- integrity sha512-u9HPBEl4DS+vA8qLQdEQ6N/eJQ7gT7aNvMIo8AAWvAl/xMrcOSiI2M0MAnMCy3jIFke7bEee/JwdX1nUpCtdyA==
+"@webassemblyjs/helper-buffer@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5"
+ integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA==
-"@webassemblyjs/helper-numbers@1.11.0":
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.0.tgz#7ab04172d54e312cc6ea4286d7d9fa27c88cd4f9"
- integrity sha512-DhRQKelIj01s5IgdsOJMKLppI+4zpmcMQ3XboFPLwCpSNH6Hqo1ritgHgD0nqHeSYqofA6aBN/NmXuGjM1jEfQ==
+"@webassemblyjs/helper-numbers@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae"
+ integrity sha512-vDkbxiB8zfnPdNK9Rajcey5C0w+QJugEglN0of+kmO8l7lDb77AnlKYQF7aarZuCrv+l0UvqL+68gSDr3k9LPQ==
dependencies:
- "@webassemblyjs/floating-point-hex-parser" "1.11.0"
- "@webassemblyjs/helper-api-error" "1.11.0"
+ "@webassemblyjs/floating-point-hex-parser" "1.11.1"
+ "@webassemblyjs/helper-api-error" "1.11.1"
"@xtuc/long" "4.2.2"
-"@webassemblyjs/helper-wasm-bytecode@1.11.0":
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.0.tgz#85fdcda4129902fe86f81abf7e7236953ec5a4e1"
- integrity sha512-MbmhvxXExm542tWREgSFnOVo07fDpsBJg3sIl6fSp9xuu75eGz5lz31q7wTLffwL3Za7XNRCMZy210+tnsUSEA==
+"@webassemblyjs/helper-wasm-bytecode@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1"
+ integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q==
-"@webassemblyjs/helper-wasm-section@1.11.0":
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.0.tgz#9ce2cc89300262509c801b4af113d1ca25c1a75b"
- integrity sha512-3Eb88hcbfY/FCukrg6i3EH8H2UsD7x8Vy47iVJrP967A9JGqgBVL9aH71SETPx1JrGsOUVLo0c7vMCN22ytJew==
+"@webassemblyjs/helper-wasm-section@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a"
+ integrity sha512-10P9No29rYX1j7F3EVPX3JvGPQPae+AomuSTPiF9eBQeChHI6iqjMIwR9JmOJXwpnn/oVGDk7I5IlskuMwU/pg==
dependencies:
- "@webassemblyjs/ast" "1.11.0"
- "@webassemblyjs/helper-buffer" "1.11.0"
- "@webassemblyjs/helper-wasm-bytecode" "1.11.0"
- "@webassemblyjs/wasm-gen" "1.11.0"
+ "@webassemblyjs/ast" "1.11.1"
+ "@webassemblyjs/helper-buffer" "1.11.1"
+ "@webassemblyjs/helper-wasm-bytecode" "1.11.1"
+ "@webassemblyjs/wasm-gen" "1.11.1"
-"@webassemblyjs/ieee754@1.11.0":
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.0.tgz#46975d583f9828f5d094ac210e219441c4e6f5cf"
- integrity sha512-KXzOqpcYQwAfeQ6WbF6HXo+0udBNmw0iXDmEK5sFlmQdmND+tr773Ti8/5T/M6Tl/413ArSJErATd8In3B+WBA==
+"@webassemblyjs/ieee754@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614"
+ integrity sha512-hJ87QIPtAMKbFq6CGTkZYJivEwZDbQUgYd3qKSadTNOhVY7p+gfP6Sr0lLRVTaG1JjFj+r3YchoqRYxNH3M0GQ==
dependencies:
"@xtuc/ieee754" "^1.2.0"
-"@webassemblyjs/leb128@1.11.0":
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.0.tgz#f7353de1df38aa201cba9fb88b43f41f75ff403b"
- integrity sha512-aqbsHa1mSQAbeeNcl38un6qVY++hh8OpCOzxhixSYgbRfNWcxJNJQwe2rezK9XEcssJbbWIkblaJRwGMS9zp+g==
+"@webassemblyjs/leb128@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5"
+ integrity sha512-BJ2P0hNZ0u+Th1YZXJpzW6miwqQUGcIHT1G/sf72gLVD9DZ5AdYTqPNbHZh6K1M5VmKvFXwGSWZADz+qBWxeRw==
dependencies:
"@xtuc/long" "4.2.2"
-"@webassemblyjs/utf8@1.11.0":
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.0.tgz#86e48f959cf49e0e5091f069a709b862f5a2cadf"
- integrity sha512-A/lclGxH6SpSLSyFowMzO/+aDEPU4hvEiooCMXQPcQFPPJaYcPQNKGOCLUySJsYJ4trbpr+Fs08n4jelkVTGVw==
-
-"@webassemblyjs/wasm-edit@1.11.0":
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.0.tgz#ee4a5c9f677046a210542ae63897094c2027cb78"
- integrity sha512-JHQ0damXy0G6J9ucyKVXO2j08JVJ2ntkdJlq1UTiUrIgfGMmA7Ik5VdC/L8hBK46kVJgujkBIoMtT8yVr+yVOQ==
- dependencies:
- "@webassemblyjs/ast" "1.11.0"
- "@webassemblyjs/helper-buffer" "1.11.0"
- "@webassemblyjs/helper-wasm-bytecode" "1.11.0"
- "@webassemblyjs/helper-wasm-section" "1.11.0"
- "@webassemblyjs/wasm-gen" "1.11.0"
- "@webassemblyjs/wasm-opt" "1.11.0"
- "@webassemblyjs/wasm-parser" "1.11.0"
- "@webassemblyjs/wast-printer" "1.11.0"
-
-"@webassemblyjs/wasm-gen@1.11.0":
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.0.tgz#3cdb35e70082d42a35166988dda64f24ceb97abe"
- integrity sha512-BEUv1aj0WptCZ9kIS30th5ILASUnAPEvE3tVMTrItnZRT9tXCLW2LEXT8ezLw59rqPP9klh9LPmpU+WmRQmCPQ==
- dependencies:
- "@webassemblyjs/ast" "1.11.0"
- "@webassemblyjs/helper-wasm-bytecode" "1.11.0"
- "@webassemblyjs/ieee754" "1.11.0"
- "@webassemblyjs/leb128" "1.11.0"
- "@webassemblyjs/utf8" "1.11.0"
-
-"@webassemblyjs/wasm-opt@1.11.0":
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.0.tgz#1638ae188137f4bb031f568a413cd24d32f92978"
- integrity sha512-tHUSP5F4ywyh3hZ0+fDQuWxKx3mJiPeFufg+9gwTpYp324mPCQgnuVKwzLTZVqj0duRDovnPaZqDwoyhIO8kYg==
- dependencies:
- "@webassemblyjs/ast" "1.11.0"
- "@webassemblyjs/helper-buffer" "1.11.0"
- "@webassemblyjs/wasm-gen" "1.11.0"
- "@webassemblyjs/wasm-parser" "1.11.0"
-
-"@webassemblyjs/wasm-parser@1.11.0":
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.0.tgz#3e680b8830d5b13d1ec86cc42f38f3d4a7700754"
- integrity sha512-6L285Sgu9gphrcpDXINvm0M9BskznnzJTE7gYkjDbxET28shDqp27wpruyx3C2S/dvEwiigBwLA1cz7lNUi0kw==
- dependencies:
- "@webassemblyjs/ast" "1.11.0"
- "@webassemblyjs/helper-api-error" "1.11.0"
- "@webassemblyjs/helper-wasm-bytecode" "1.11.0"
- "@webassemblyjs/ieee754" "1.11.0"
- "@webassemblyjs/leb128" "1.11.0"
- "@webassemblyjs/utf8" "1.11.0"
-
-"@webassemblyjs/wast-printer@1.11.0":
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.0.tgz#680d1f6a5365d6d401974a8e949e05474e1fab7e"
- integrity sha512-Fg5OX46pRdTgB7rKIUojkh9vXaVN6sGYCnEiJN1GYkb0RPwShZXp6KTDqmoMdQPKhcroOXh3fEzmkWmCYaKYhQ==
- dependencies:
- "@webassemblyjs/ast" "1.11.0"
+"@webassemblyjs/utf8@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff"
+ integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ==
+
+"@webassemblyjs/wasm-edit@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6"
+ integrity sha512-g+RsupUC1aTHfR8CDgnsVRVZFJqdkFHpsHMfJuWQzWU3tvnLC07UqHICfP+4XyL2tnr1amvl1Sdp06TnYCmVkA==
+ dependencies:
+ "@webassemblyjs/ast" "1.11.1"
+ "@webassemblyjs/helper-buffer" "1.11.1"
+ "@webassemblyjs/helper-wasm-bytecode" "1.11.1"
+ "@webassemblyjs/helper-wasm-section" "1.11.1"
+ "@webassemblyjs/wasm-gen" "1.11.1"
+ "@webassemblyjs/wasm-opt" "1.11.1"
+ "@webassemblyjs/wasm-parser" "1.11.1"
+ "@webassemblyjs/wast-printer" "1.11.1"
+
+"@webassemblyjs/wasm-gen@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76"
+ integrity sha512-F7QqKXwwNlMmsulj6+O7r4mmtAlCWfO/0HdgOxSklZfQcDu0TpLiD1mRt/zF25Bk59FIjEuGAIyn5ei4yMfLhA==
+ dependencies:
+ "@webassemblyjs/ast" "1.11.1"
+ "@webassemblyjs/helper-wasm-bytecode" "1.11.1"
+ "@webassemblyjs/ieee754" "1.11.1"
+ "@webassemblyjs/leb128" "1.11.1"
+ "@webassemblyjs/utf8" "1.11.1"
+
+"@webassemblyjs/wasm-opt@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2"
+ integrity sha512-VqnkNqnZlU5EB64pp1l7hdm3hmQw7Vgqa0KF/KCNO9sIpI6Fk6brDEiX+iCOYrvMuBWDws0NkTOxYEb85XQHHw==
+ dependencies:
+ "@webassemblyjs/ast" "1.11.1"
+ "@webassemblyjs/helper-buffer" "1.11.1"
+ "@webassemblyjs/wasm-gen" "1.11.1"
+ "@webassemblyjs/wasm-parser" "1.11.1"
+
+"@webassemblyjs/wasm-parser@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199"
+ integrity sha512-rrBujw+dJu32gYB7/Lup6UhdkPx9S9SnobZzRVL7VcBH9Bt9bCBLEuX/YXOOtBsOZ4NQrRykKhffRWHvigQvOA==
+ dependencies:
+ "@webassemblyjs/ast" "1.11.1"
+ "@webassemblyjs/helper-api-error" "1.11.1"
+ "@webassemblyjs/helper-wasm-bytecode" "1.11.1"
+ "@webassemblyjs/ieee754" "1.11.1"
+ "@webassemblyjs/leb128" "1.11.1"
+ "@webassemblyjs/utf8" "1.11.1"
+
+"@webassemblyjs/wast-printer@1.11.1":
+ version "1.11.1"
+ resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0"
+ integrity sha512-IQboUWM4eKzWW+N/jij2sRatKMh99QEelo3Eb2q0qXkvPRISAj8Qxtmw5itwqK+TTkBuUIE45AxYPToqPtL5gg==
+ dependencies:
+ "@webassemblyjs/ast" "1.11.1"
"@xtuc/long" "4.2.2"
-"@webpack-cli/configtest@^1.0.3":
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.0.3.tgz#204bcff87cda3ea4810881f7ea96e5f5321b87b9"
- integrity sha512-WQs0ep98FXX2XBAfQpRbY0Ma6ADw8JR6xoIkaIiJIzClGOMqVRvPCWqndTxf28DgFopWan0EKtHtg/5W1h0Zkw==
+"@webpack-cli/configtest@^1.1.0":
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.1.0.tgz#8342bef0badfb7dfd3b576f2574ab80c725be043"
+ integrity sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg==
-"@webpack-cli/info@^1.2.4":
- version "1.2.4"
- resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.2.4.tgz#7381fd41c9577b2d8f6c2594fad397ef49ad5573"
- integrity sha512-ogE2T4+pLhTTPS/8MM3IjHn0IYplKM4HbVNMCWA9N4NrdPzunwenpCsqKEXyejMfRu6K8mhauIPYf8ZxWG5O6g==
+"@webpack-cli/info@^1.4.0":
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.4.0.tgz#b9179c3227ab09cbbb149aa733475fcf99430223"
+ integrity sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw==
dependencies:
envinfo "^7.7.3"
-"@webpack-cli/serve@^1.4.0":
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.4.0.tgz#f84fd07bcacefe56ce762925798871092f0f228e"
- integrity sha512-xgT/HqJ+uLWGX+Mzufusl3cgjAcnqYYskaB7o0vRcwOEfuu6hMzSILQpnIzFMGsTaeaX4Nnekl+6fadLbl1/Vg==
+"@webpack-cli/serve@^1.6.0":
+ version "1.6.0"
+ resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.6.0.tgz#2c275aa05c895eccebbfc34cfb223c6e8bd591a2"
+ integrity sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA==
"@wojtekmaj/enzyme-adapter-react-17@^0.4.1":
version "0.4.1"
@@ -2832,18 +2506,23 @@ accepts@~1.3.4:
negotiator "0.6.2"
ace-builds@^1.4.12:
- version "1.4.12"
- resolved "https://registry.yarnpkg.com/ace-builds/-/ace-builds-1.4.12.tgz#888efa386e36f4345f40b5233fcc4fe4c588fae7"
- integrity sha512-G+chJctFPiiLGvs3+/Mly3apXTcfgE45dT5yp12BcWZ1kUs+gm0qd3/fv4gsz6fVag4mM0moHVpjHDIgph6Psg==
+ version "1.4.13"
+ resolved "https://registry.yarnpkg.com/ace-builds/-/ace-builds-1.4.13.tgz#186f42d3849ebcc6a48b93088a058489897514c1"
+ integrity sha512-SOLzdaQkY6ecPKYRDDg+MY1WoGgXA34cIvYJNNoBMGGUswHmlauU2Hy0UL96vW0Fs/LgFbMUjD+6vqzWTldIYQ==
"acitree@git+https://github.com/imsurinder90/jquery-aciTree.git#rc.7":
version "4.5.0-rc.7"
resolved "git+https://github.com/imsurinder90/jquery-aciTree.git#24dcd7536a008abe25da6adb7bfde8eeb53892f1"
+acorn-import-assertions@^1.7.6:
+ version "1.8.0"
+ resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9"
+ integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw==
+
acorn-jsx@^5.3.1:
- version "5.3.1"
- resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b"
- integrity sha512-K0Ptm/47OKfQRpNQ2J/oIN/3QYiK6FwW+eJbILhsdxh2WTLdl+30o8aGdTbm5JbffpFFAg/g+zi1E+jvJha5ng==
+ version "5.3.2"
+ resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937"
+ integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==
acorn-node@^1.2.0, acorn-node@^1.3.0, acorn-node@^1.5.2, acorn-node@^1.6.1:
version "1.8.2"
@@ -2860,19 +2539,19 @@ acorn-walk@^7.0.0:
integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==
acorn-walk@^8.0.0:
- version "8.1.0"
- resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.1.0.tgz#d3c6a9faf00987a5e2b9bdb506c2aa76cd707f83"
- integrity sha512-mjmzmv12YIG/G8JQdQuz2MUDShEJ6teYpT5bmWA4q7iwoGen8xtt3twF3OvzIUl+Q06aWIjvnwQUKvQ6TtMRjg==
+ version "8.2.0"
+ resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1"
+ integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==
acorn@^7.0.0, acorn@^7.4.0:
version "7.4.1"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa"
integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==
-acorn@^8.0.4:
- version "8.2.4"
- resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.2.4.tgz#caba24b08185c3b56e3168e97d15ed17f4d31fd0"
- integrity sha512-Ibt84YwBDDA890eDiDCEqcbwvHlBvzzDkU2cGBBDDI1QWT12jTiXIOn2CIw5KK4i6N5Z2HUxwYjzriDyqaqqZg==
+acorn@^8.0.4, acorn@^8.4.1:
+ version "8.5.0"
+ resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.5.0.tgz#4512ccb99b3698c752591e9bb4472e38ad43cee2"
+ integrity sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q==
agent-base@6, agent-base@^6.0.2:
version "6.0.2"
@@ -2944,9 +2623,9 @@ ajv@^6.1.0, ajv@^6.10.0, ajv@^6.12.4, ajv@^6.12.5, ajv@^6.12.6:
uri-js "^4.2.2"
ajv@^8.0.1:
- version "8.5.0"
- resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.5.0.tgz#695528274bcb5afc865446aa275484049a18ae4b"
- integrity sha512-Y2l399Tt1AguU3BPRP9Fn4eN+Or+StUGWCUpbnFyXSo8NZ9S4uj+AG2pjs5apK+ZMOwYOz1+a+VKvKH7CudXgQ==
+ version "8.6.3"
+ resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.6.3.tgz#11a66527761dc3e9a3845ea775d2d3c0414e8764"
+ integrity sha512-SMJOdDP6LqTkD0Uq8qLi+gMwSt0imXLSV080qFVwJCpH9U6Mb+SUGHAXM0KNbcBPguytWyvFxcHgMLe2D2XSpw==
dependencies:
fast-deep-equal "^3.1.1"
json-schema-traverse "^1.0.0"
@@ -2982,7 +2661,7 @@ ansi-regex@^2.0.0:
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8=
-ansi-regex@^5.0.0:
+ansi-regex@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
@@ -3006,7 +2685,7 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0:
dependencies:
color-convert "^2.0.1"
-anymatch@~3.1.1, anymatch@~3.1.2:
+anymatch@~3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716"
integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==
@@ -3051,16 +2730,16 @@ argparse@^2.0.1:
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
-array-includes@^3.1.2, array-includes@^3.1.3:
- version "3.1.3"
- resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.3.tgz#c7f619b382ad2afaf5326cddfdc0afc61af7690a"
- integrity sha512-gcem1KlBU7c9rB+Rq8/3PPKsK2kjqeEBa3bD5kkQo4nYlOHQCJqIJFqBXDEfwaRuYTT4E+FxA9xez7Gf/e3Q7A==
+array-includes@^3.1.3:
+ version "3.1.4"
+ resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.4.tgz#f5b493162c760f3539631f005ba2bb46acb45ba9"
+ integrity sha512-ZTNSQkmWumEbiHO2GF4GmWxYVTiQyJy2XOTa15sdQSrvKn7l+180egQMqlrMOUMCyLMD7pmyQe4mMDUT6Behrw==
dependencies:
call-bind "^1.0.2"
define-properties "^1.1.3"
- es-abstract "^1.18.0-next.2"
+ es-abstract "^1.19.1"
get-intrinsic "^1.1.1"
- is-string "^1.0.5"
+ is-string "^1.0.7"
array-union@^2.1.0:
version "2.1.0"
@@ -3068,34 +2747,35 @@ array-union@^2.1.0:
integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==
array.prototype.filter@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/array.prototype.filter/-/array.prototype.filter-1.0.0.tgz#24d63e38983cdc6bf023a3c574b2f2a3f384c301"
- integrity sha512-TfO1gz+tLm+Bswq0FBOXPqAchtCr2Rn48T8dLJoRFl8NoEosjZmzptmuo1X8aZBzZcqsR1W8U761tjACJtngTQ==
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/array.prototype.filter/-/array.prototype.filter-1.0.1.tgz#20688792acdb97a09488eaaee9eebbf3966aae21"
+ integrity sha512-Dk3Ty7N42Odk7PjU/Ci3zT4pLj20YvuVnneG/58ICM6bt4Ij5kZaJTVQ9TSaWaIECX2sFyz4KItkVZqHNnciqw==
dependencies:
call-bind "^1.0.2"
define-properties "^1.1.3"
- es-abstract "^1.18.0"
+ es-abstract "^1.19.0"
es-array-method-boxes-properly "^1.0.0"
- is-string "^1.0.5"
+ is-string "^1.0.7"
array.prototype.find@^2.1.1:
- version "2.1.1"
- resolved "https://registry.yarnpkg.com/array.prototype.find/-/array.prototype.find-2.1.1.tgz#3baca26108ca7affb08db06bf0be6cb3115a969c"
- integrity sha512-mi+MYNJYLTx2eNYy+Yh6raoQacCsNeeMUaspFPh9Y141lFSsWxxB8V9mM2ye+eqiRs917J6/pJ4M9ZPzenWckA==
+ version "2.1.2"
+ resolved "https://registry.yarnpkg.com/array.prototype.find/-/array.prototype.find-2.1.2.tgz#6abbd0c2573925d8094f7d23112306af8c16d534"
+ integrity sha512-00S1O4ewO95OmmJW7EesWfQlrCrLEL8kZ40w3+GkLX2yTt0m2ggcePPa2uHPJ9KUmJvwRq+lCV9bD8Yim23x/Q==
dependencies:
+ call-bind "^1.0.2"
define-properties "^1.1.3"
- es-abstract "^1.17.4"
+ es-abstract "^1.19.0"
array.prototype.flat@^1.2.3:
- version "1.2.4"
- resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.4.tgz#6ef638b43312bd401b4c6199fdec7e2dc9e9a123"
- integrity sha512-4470Xi3GAPAjZqFcljX2xzckv1qeKPizoNkiS0+O4IoPR2ZNpcjE0pkhdihlDouK+x6QOast26B4Q/O9DJnwSg==
+ version "1.2.5"
+ resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz#07e0975d84bbc7c48cd1879d609e682598d33e13"
+ integrity sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==
dependencies:
- call-bind "^1.0.0"
+ call-bind "^1.0.2"
define-properties "^1.1.3"
- es-abstract "^1.18.0-next.1"
+ es-abstract "^1.19.0"
-array.prototype.flatmap@1.2.4, array.prototype.flatmap@^1.2.4:
+array.prototype.flatmap@1.2.4:
version "1.2.4"
resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.4.tgz#94cfd47cc1556ec0747d97f7c7738c58122004c9"
integrity sha512-r9Z0zYoxqHz60vvQbWEdXIEtCwHF0yxaWfno9qzXeNHvfyl3BZqygmGzb84dsubyaXLH4husF+NFgMSdpZhk2Q==
@@ -3105,6 +2785,15 @@ array.prototype.flatmap@1.2.4, array.prototype.flatmap@^1.2.4:
es-abstract "^1.18.0-next.1"
function-bind "^1.1.1"
+array.prototype.flatmap@^1.2.4:
+ version "1.2.5"
+ resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.2.5.tgz#908dc82d8a406930fdf38598d51e7411d18d4446"
+ integrity sha512-08u6rVyi1Lj7oqWbS9nUxliETrtIROT4XGTA4D/LWGten6E3ocm7cy9SIrmNHOL5XVbVuckUp3X6Xyg8/zpvHA==
+ dependencies:
+ call-bind "^1.0.0"
+ define-properties "^1.1.3"
+ es-abstract "^1.19.0"
+
asn1.js@^5.2.0:
version "5.4.1"
resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07"
@@ -3116,9 +2805,9 @@ asn1.js@^5.2.0:
safer-buffer "^2.1.0"
aspen-core@^1.0.4:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/aspen-core/-/aspen-core-1.0.4.tgz#a2d6a23c80303e73aaa836c124c116e447ba7a7d"
- integrity sha512-mQ79JxHstB2rf47Zgw2yduAH9L47b+3bwQtpbEAKeSJsLTPe8X7lsQ6lLP3tFbS204TNILC5LxSkVWv45FXQYg==
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/aspen-core/-/aspen-core-1.0.5.tgz#7745def811f761bca49d475d9addc8a5dbb1c71c"
+ integrity sha512-iqWORNQeQTn6XHStl1uCQ4t1yMPMw/nSWygfXVAEflf8vAWs4vR2M2TqDEZGvyoTkrxIPONv+wyQQFDnN5QCkg==
dependencies:
notificar "^1.0.1"
p-series "^1.1.0"
@@ -3165,34 +2854,35 @@ async@^2.1.4:
lodash "^4.17.14"
async@^3.2.0:
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720"
- integrity sha512-TR2mEZFVOj2pLStYxLht7TyfuRzaydfpxr3k9RpHIzMgw7A64dzsdqCxH1WJyQdoe8T10nDXd9wnEigmiuHIZw==
+ version "3.2.2"
+ resolved "https://registry.yarnpkg.com/async/-/async-3.2.2.tgz#2eb7671034bb2194d45d30e31e24ec7e7f9670cd"
+ integrity sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g==
autoprefixer@^10.2.4:
- version "10.2.6"
- resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.2.6.tgz#aadd9ec34e1c98d403e01950038049f0eb252949"
- integrity sha512-8lChSmdU6dCNMCQopIf4Pe5kipkAGj/fvTMslCsih0uHpOrXOPUEVOmYMMqmw3cekQkSD7EhIeuYl5y0BLdKqg==
+ version "10.4.0"
+ resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.0.tgz#c3577eb32a1079a440ec253e404eaf1eb21388c8"
+ integrity sha512-7FdJ1ONtwzV1G43GDD0kpVMn/qbiNqyOPMFTX5nRffI+7vgWoFEc6DcXOxHJxrWNDXrZh18eDsZjvZGUljSRGA==
dependencies:
- browserslist "^4.16.6"
- caniuse-lite "^1.0.30001230"
- colorette "^1.2.2"
+ browserslist "^4.17.5"
+ caniuse-lite "^1.0.30001272"
fraction.js "^4.1.1"
normalize-range "^0.1.2"
+ picocolors "^1.0.0"
postcss-value-parser "^4.1.0"
-available-typed-arrays@^1.0.2:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.4.tgz#9e0ae84ecff20caae6a94a1c3bc39b955649b7a9"
- integrity sha512-SA5mXJWrId1TaQjfxUYghbqQ/hYioKmLJvPJyDuYRtXXenFNMjj4hSSt1Cf1xsuXSXrtxrVC5Ot4eU6cOtBDdA==
+available-typed-arrays@^1.0.5:
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7"
+ integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==
axios-mock-adapter@^1.17.0:
- version "1.19.0"
- resolved "https://registry.yarnpkg.com/axios-mock-adapter/-/axios-mock-adapter-1.19.0.tgz#9d72e321a6c5418e1eff067aa99761a86c5188a4"
- integrity sha512-D+0U4LNPr7WroiBDvWilzTMYPYTuZlbo6BI8YHZtj7wYQS8NkARlP9KBt8IWWHTQJ0q/8oZ0ClPBtKCCkx8cQg==
+ version "1.20.0"
+ resolved "https://registry.yarnpkg.com/axios-mock-adapter/-/axios-mock-adapter-1.20.0.tgz#21f5b4b625306f43e8c05673616719da86e20dcb"
+ integrity sha512-shZRhTjLP0WWdcvHKf3rH3iW9deb3UdKbdnKUoHmmsnBhVXN3sjPJM6ZvQ2r/ywgvBVQrMnjrSyQab60G1sr2w==
dependencies:
fast-deep-equal "^3.1.3"
- is-buffer "^2.0.3"
+ is-blob "^2.1.0"
+ is-buffer "^2.0.5"
axios@^0.21.1:
version "0.21.4"
@@ -3225,9 +2915,9 @@ babel-generator@^6.18.0:
trim-right "^1.0.1"
babel-loader@^8.1.0:
- version "8.2.2"
- resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.2.tgz#9363ce84c10c9a40e6c753748e1441b60c8a0b81"
- integrity sha512-JvTd0/D889PQBtUXJ2PXaKU/pjZDMtHA9V2ecm+eNRmmBCMR09a+fmpGTNwnJtFmFl5Ei7Vy47LjBb+L0wQ99g==
+ version "8.2.3"
+ resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.3.tgz#8986b40f1a64cacfcb4b8429320085ef68b1342d"
+ integrity sha512-n4Zeta8NC3QAsuyiizu0GkmRcQ6clkV9WFUnUf1iXP//IeSKbWjofW3UHyZVwlOB4y039YQKefawyTn64Zwbuw==
dependencies:
find-cache-dir "^3.3.1"
loader-utils "^1.4.0"
@@ -3321,13 +3011,13 @@ babel-plugin-polyfill-regenerator@^0.3.0:
dependencies:
"@babel/helper-define-polyfill-provider" "^0.3.1"
-"babel-plugin-styled-components@>= 1":
- version "1.12.0"
- resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.12.0.tgz#1dec1676512177de6b827211e9eda5a30db4f9b9"
- integrity sha512-FEiD7l5ZABdJPpLssKXjBUJMYqzbcNzBowfXDCdJhOpbhWiewapUaY+LZGT8R4Jg2TwOjGjG4RKeyrO5p9sBkA==
+"babel-plugin-styled-components@>= 1.12.0":
+ version "1.13.3"
+ resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.13.3.tgz#1f1cb3927d4afa1e324695c78f690900e3d075bc"
+ integrity sha512-meGStRGv+VuKA/q0/jXxrPNWEm4LPfYIqxooDTdmh8kFsP/Ph7jJG5rUPwUPX3QHUvggwdbgdGpo88P/rRYsVw==
dependencies:
- "@babel/helper-annotate-as-pure" "^7.0.0"
- "@babel/helper-module-imports" "^7.0.0"
+ "@babel/helper-annotate-as-pure" "^7.15.4"
+ "@babel/helper-module-imports" "^7.15.4"
babel-plugin-syntax-jsx "^6.18.0"
lodash "^4.17.11"
@@ -3449,16 +3139,16 @@ balanced-match@^1.0.0:
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
-base64-arraybuffer@0.1.4:
- version "0.1.4"
- resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.4.tgz#9818c79e059b1355f97e0428a017c838e90ba812"
- integrity sha1-mBjHngWbE1X5fgQooBfIOOkLqBI=
-
base64-arraybuffer@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.2.0.tgz#4b944fac0191aa5907afe2d8c999ccc57ce80f45"
integrity sha512-7emyCsu1/xiBXgQZrscw/8KPRT44I4Yq9Pe6EGs3aPRTsWuggML1/1DTuZUuIaJPIm1FTDUVXl4x/yW8s0kQDQ==
+base64-arraybuffer@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-1.0.1.tgz#87bd13525626db4a9838e00a508c2b73efcf348c"
+ integrity sha512-vFIUq7FdLtjZMhATwDul5RZWv2jpXQ09Pd6jcVEOvIsqCWTRFD/ONHNfyOS8dA/Ippi5dsIgpyKWKZaAKZltbA==
+
base64-js@^1.0.2, base64-js@^1.3.1:
version "1.5.1"
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a"
@@ -3596,9 +3286,9 @@ bootstrap4-toggle@^3.6.1:
integrity sha512-eRejcTc9YurhZ64nHY9Ii9DQn+F9/R74H9RPoeANVM3N1+C2lZ2tUuFCx1w3orOJ1y/iG4A7iCwdDZphMDIrYg==
bootstrap@^4.3.1, bootstrap@^4.5.2:
- version "4.6.0"
- resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.6.0.tgz#97b9f29ac98f98dfa43bf7468262d84392552fd7"
- integrity sha512-Io55IuQY3kydzHtbGvQya3H+KorS/M9rSNyfCGCg9WZ4pyT/lCxIlpJgG1GXW/PswzC84Tr2fBYi+7+jFVQQBw==
+ version "4.6.1"
+ resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.6.1.tgz#bc25380c2c14192374e8dec07cf01b2742d222a2"
+ integrity sha512-0dj+VgI9Ecom+rvvpNZ4MUZJz8dcX7WCX+eTID9+/8HgOkv3dsRzi8BGeZJCQU6flWQVYxwTQnEZFrmJSEO7og==
bowser@^2.11.0:
version "2.11.0"
@@ -3772,16 +3462,16 @@ browserify@^17.0.0:
vm-browserify "^1.0.0"
xtend "^4.0.0"
-browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.16.0, browserslist@^4.16.3, browserslist@^4.16.6:
- version "4.16.6"
- resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.16.6.tgz#d7901277a5a88e554ed305b183ec9b0c08f66fa2"
- integrity sha512-Wspk/PqO+4W9qp5iUTJsa1B/QrYn1keNCcEP5OvP7WBwT4KaDly0uONYmC6Xa3Z5IqnUgS0KcgLYu1l74x0ZXQ==
+browserslist@^4.0.0, browserslist@^4.14.5, browserslist@^4.16.0, browserslist@^4.16.6:
+ version "4.17.6"
+ resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.17.6.tgz#c76be33e7786b497f66cad25a73756c8b938985d"
+ integrity sha512-uPgz3vyRTlEiCv4ee9KlsKgo2V6qPk7Jsn0KAn2OBqbqKo3iNcPEC1Ti6J4dwnz+aIRfEEEuOzC9IBk8tXUomw==
dependencies:
- caniuse-lite "^1.0.30001219"
- colorette "^1.2.2"
- electron-to-chromium "^1.3.723"
+ caniuse-lite "^1.0.30001274"
+ electron-to-chromium "^1.3.886"
escalade "^3.1.1"
- node-releases "^1.1.71"
+ node-releases "^2.0.1"
+ picocolors "^1.0.0"
browserslist@^4.17.5, browserslist@^4.19.1:
version "4.19.1"
@@ -3818,9 +3508,9 @@ buffer-fill@^1.0.0:
integrity sha1-+PeLdniYiO858gXNY39o5wISKyw=
buffer-from@^1.0.0:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
- integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
+ integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
buffer-xor@^1.0.3:
version "1.0.3"
@@ -3943,11 +3633,16 @@ caniuse-api@^3.0.0:
lodash.memoize "^4.1.2"
lodash.uniq "^4.5.0"
-caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001219, caniuse-lite@^1.0.30001230, caniuse-lite@^1.0.30001286:
+caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001286:
version "1.0.30001309"
resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001309.tgz"
integrity sha512-Pl8vfigmBXXq+/yUz1jUwULeq9xhMJznzdc/xwl4WclDAuebcTHVefpz8lE/bMI+UN7TOkSSe7B7RnZd6+dzjA==
+caniuse-lite@^1.0.30001272, caniuse-lite@^1.0.30001274:
+ version "1.0.30001278"
+ resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001278.tgz#51cafc858df77d966b17f59b5839250b24417fff"
+ integrity sha512-mpF9KeH8u5cMoEmIic/cr7PNS+F5LWBk0t2ekGT60lFf0Wq+n9LspAj0g3P+o7DQhD3sUdlMln4YFAWhFYn9jg==
+
caw@^2.0.0, caw@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/caw/-/caw-2.0.1.tgz#6c3ca071fc194720883c2dc5da9b074bfc7e9e95"
@@ -3979,9 +3674,9 @@ chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2:
supports-color "^5.3.0"
chalk@^4.0.0, chalk@^4.1.0:
- version "4.1.1"
- resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad"
- integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==
+ version "4.1.2"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
+ integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
dependencies:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
@@ -4009,44 +3704,44 @@ chartjs-color@^2.1.0:
chartjs-color-string "^0.6.0"
color-convert "^1.9.3"
-cheerio-select@^1.4.0:
- version "1.4.0"
- resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-1.4.0.tgz#3a16f21e37a2ef0f211d6d1aa4eff054bb22cdc9"
- integrity sha512-sobR3Yqz27L553Qa7cK6rtJlMDbiKPdNywtR95Sj/YgfpLfy0u6CGJuaBKe5YE/vTc23SCRKxWSdlon/w6I/Ew==
+cheerio-select@^1.5.0:
+ version "1.5.0"
+ resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-1.5.0.tgz#faf3daeb31b17c5e1a9dabcee288aaf8aafa5823"
+ integrity sha512-qocaHPv5ypefh6YNxvnbABM07KMxExbtbfuJoIie3iZXX1ERwYmJcIiRrr9H05ucQP1k28dav8rpdDgjQd8drg==
dependencies:
- css-select "^4.1.2"
- css-what "^5.0.0"
+ css-select "^4.1.3"
+ css-what "^5.0.1"
domelementtype "^2.2.0"
domhandler "^4.2.0"
- domutils "^2.6.0"
+ domutils "^2.7.0"
cheerio@^1.0.0-rc.3:
- version "1.0.0-rc.9"
- resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.9.tgz#a3ae6b7ce7af80675302ff836f628e7cb786a67f"
- integrity sha512-QF6XVdrLONO6DXRF5iaolY+odmhj2CLj+xzNod7INPWMi/x9X4SOylH0S/vaPpX+AUU6t04s34SQNh7DbkuCng==
+ version "1.0.0-rc.10"
+ resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.10.tgz#2ba3dcdfcc26e7956fc1f440e61d51c643379f3e"
+ integrity sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==
dependencies:
- cheerio-select "^1.4.0"
- dom-serializer "^1.3.1"
+ cheerio-select "^1.5.0"
+ dom-serializer "^1.3.2"
domhandler "^4.2.0"
htmlparser2 "^6.1.0"
parse5 "^6.0.1"
parse5-htmlparser2-tree-adapter "^6.0.1"
tslib "^2.2.0"
-"chokidar@>=2.0.0 <4.0.0":
- version "3.5.1"
- resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a"
- integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==
+"chokidar@>=3.0.0 <4.0.0":
+ version "3.5.2"
+ resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75"
+ integrity sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==
dependencies:
- anymatch "~3.1.1"
+ anymatch "~3.1.2"
braces "~3.0.2"
- glob-parent "~5.1.0"
+ glob-parent "~5.1.2"
is-binary-path "~2.1.0"
is-glob "~4.0.1"
normalize-path "~3.0.0"
- readdirp "~3.5.0"
+ readdirp "~3.6.0"
optionalDependencies:
- fsevents "~2.3.1"
+ fsevents "~2.3.2"
chokidar@^3.5.1:
version "3.5.3"
@@ -4153,9 +3848,9 @@ code-point-at@^1.0.0:
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
codemirror@^5.59.2:
- version "5.59.4"
- resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.59.4.tgz#bfc11c8ce32b04818e8d661bbd790a94f4b3a6f3"
- integrity sha512-achw5JBgx8QPcACDDn+EUUXmCYzx/zxEtOGXyjvLEvYY8GleUrnfm5D+Zb+UjShHggXKDT9AXrbkBZX6a0YSQg==
+ version "5.63.3"
+ resolved "https://registry.yarnpkg.com/codemirror/-/codemirror-5.63.3.tgz#97042a242027fe0c87c09b36bc01931d37b76527"
+ integrity sha512-1C+LELr+5grgJYqwZKqxrcbPsHFHapVaVAloBsFBASbpLnQqLw1U8yXJ3gT5D+rhxIiSpo+kTqN+hQ+9ialIXw==
color-convert@^1.9.0, color-convert@^1.9.3:
version "1.9.3"
@@ -4181,15 +3876,15 @@ color-name@^1.0.0, color-name@~1.1.4:
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
-colord@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/colord/-/colord-2.0.0.tgz#f8c19f2526b7dc5b22d6e57ef102f03a2a43a3d8"
- integrity sha512-WMDFJfoY3wqPZNpKUFdse3HhD5BHCbE9JCdxRzoVH+ywRITGOeWAHNkGEmyxLlErEpN9OLMWgdM9dWQtDk5dog==
+colord@^2.9.1:
+ version "2.9.1"
+ resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.1.tgz#c961ea0efeb57c9f0f4834458f26cb9cc4a3f90e"
+ integrity sha512-4LBMSt09vR0uLnPVkOUBnmxgoaeN4ewRbx801wY/bXcltXfpR/G46OdWn96XpYmCWuYvO46aBZP4NgX8HpNAcw==
-colorette@^1.2.1, colorette@^1.2.2:
- version "1.2.2"
- resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.2.tgz#cbcc79d5e99caea2dbf10eb3a26fd8b3e6acfa94"
- integrity sha512-MKGMzyfeuutC/ZJ1cba9NqcNpfeqMUcYmyF1ZFY6/Cn7CNSAKx6a+s48sqLqyAiZuaP2TcqMhoo+dlwFnVxT9w==
+colorette@^2.0.14:
+ version "2.0.16"
+ resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da"
+ integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==
combine-source-map@^0.8.0, combine-source-map@~0.8.0:
version "0.8.0"
@@ -4211,17 +3906,7 @@ commander@^4.0.1:
resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
-commander@^6.2.0:
- version "6.2.1"
- resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c"
- integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==
-
-commander@^7.0.0:
- version "7.1.0"
- resolved "https://registry.yarnpkg.com/commander/-/commander-7.1.0.tgz#f2eaecf131f10e36e07d894698226e36ae0eb5ff"
- integrity sha512-pRxBna3MJe6HKnBGsDyMv8ETbptw3axEdYHoqNh7gu5oDcew8fs0xnivZGm06Ogk8zGAJ9VX+OPEr2GXEQK4dg==
-
-commander@^7.2.0:
+commander@^7.0.0, commander@^7.2.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7"
integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==
@@ -4252,9 +3937,9 @@ concat-stream@^1.6.0, concat-stream@^1.6.1, concat-stream@~1.6.0:
typedarray "^0.0.6"
config-chain@^1.1.11:
- version "1.1.12"
- resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa"
- integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==
+ version "1.1.13"
+ resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.13.tgz#fad0795aa6a6cdaff9ed1b68e9dff94372c232f4"
+ integrity sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==
dependencies:
ini "^1.3.4"
proto-list "~1.2.1"
@@ -4320,13 +4005,6 @@ cookie@~0.4.1:
resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1"
integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==
-copy-to-clipboard@^3.3.1:
- version "3.3.1"
- resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz#115aa1a9998ffab6196f93076ad6da3b913662ae"
- integrity sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==
- dependencies:
- toggle-selection "^1.0.6"
-
copy-webpack-plugin@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-7.0.0.tgz#3506f867ca6e861ee2769d4deaf8fa0d2563ada9"
@@ -4341,7 +4019,7 @@ copy-webpack-plugin@^7.0.0:
schema-utils "^3.0.0"
serialize-javascript "^5.0.1"
-core-js-compat@^3.20.2, core-js-compat@^3.21.0:
+core-js-compat@^3.20.2, core-js-compat@^3.21.0, core-js-compat@^3.8.1, core-js-compat@^3.9.0:
version "3.21.0"
resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.21.0.tgz#bcc86aa5a589cee358e7a7fa0a4979d5a76c3885"
integrity sha512-OSXseNPSK2OPJa6GdtkMz/XxeXx8/CJvfhQWTqd6neuUraujcL4jVsjkLQz1OWnax8xVQJnRPe0V2jqNWORA+A==
@@ -4349,28 +4027,20 @@ core-js-compat@^3.20.2, core-js-compat@^3.21.0:
browserslist "^4.19.1"
semver "7.0.0"
-core-js-compat@^3.8.1, core-js-compat@^3.9.0:
- version "3.9.1"
- resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.9.1.tgz#4e572acfe90aff69d76d8c37759d21a5c59bb455"
- integrity sha512-jXAirMQxrkbiiLsCx9bQPJFA6llDadKMpYrBJQJ3/c4/vsPP/fAf29h24tviRlvwUL6AmY5CHLu2GvjuYviQqA==
- dependencies:
- browserslist "^4.16.3"
- semver "7.0.0"
-
core-js@^2.4.0:
version "2.6.12"
resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
-core-js@^3.12.1, core-js@^3.2.1:
- version "3.12.1"
- resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.12.1.tgz#6b5af4ff55616c08a44d386f1f510917ff204112"
- integrity sha512-Ne9DKPHTObRuB09Dru5AjwKjY4cJHVGu+y5f7coGn1E9Grkc3p2iBwE9AI/nJzsE29mQF7oq+mhYYRqOMFN1Bw==
+core-js@^3.15.1, core-js@^3.2.1:
+ version "3.19.1"
+ resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.19.1.tgz#f6f173cae23e73a7d88fa23b6e9da329276c6641"
+ integrity sha512-Tnc7E9iKd/b/ff7GFbhwPVzJzPztGrChB8X8GLqoYGdEOG8IpLnK1xPyo3ZoO3HsK6TodJS58VGPOxA+hLHQMg==
core-util-is@~1.0.0:
- version "1.0.2"
- resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
- integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=
+ version "1.0.3"
+ resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
+ integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
cors@~2.8.5:
version "2.8.5"
@@ -4392,9 +4062,9 @@ cosmiconfig@^6.0.0:
yaml "^1.7.2"
cosmiconfig@^7.0.0:
- version "7.0.0"
- resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.0.tgz#ef9b44d773959cae63ddecd122de23853b60f8d3"
- integrity sha512-pondGvTuVYDk++upghXJabWzL6Kxu6f26ljFw64Swq9v6sQPUL3EUlVDV56diOjpCayKihL6hVe8exIACU4XcA==
+ version "7.0.1"
+ resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d"
+ integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==
dependencies:
"@types/parse-json" "^4.0.0"
import-fresh "^3.2.1"
@@ -4491,59 +4161,52 @@ css-color-keywords@^1.0.0:
resolved "https://registry.yarnpkg.com/css-color-keywords/-/css-color-keywords-1.0.0.tgz#fea2616dc676b2962686b3af8dbdbe180b244e05"
integrity sha1-/qJhbcZ2spYmhrOvjb2+GAskTgU=
-css-color-names@^0.0.4:
- version "0.0.4"
- resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-0.0.4.tgz#808adc2e79cf84738069b646cb20ec27beb629e0"
- integrity sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=
-
css-color-names@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-1.0.1.tgz#6ff7ee81a823ad46e020fa2fd6ab40a887e2ba67"
integrity sha512-/loXYOch1qU1biStIFsHH8SxTmOseh1IJqFvy8IujXOm1h+QjUdDhkzOrR5HG8K8mlxREj0yfi8ewCHx0eMxzA==
css-declaration-sorter@^6.0.3:
- version "6.0.3"
- resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.0.3.tgz#9dfd8ea0df4cc7846827876fafb52314890c21a9"
- integrity sha512-52P95mvW1SMzuRZegvpluT6yEv0FqQusydKQPZsNN5Q7hh8EwQvN8E2nwuJ16BBvNN6LcoIZXu/Bk58DAhrrxw==
+ version "6.1.3"
+ resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.1.3.tgz#e9852e4cf940ba79f509d9425b137d1f94438dc2"
+ integrity sha512-SvjQjNRZgh4ULK1LDJ2AduPKUKxIqmtU7ZAyi47BTV+M90Qvxr9AB6lKlLbDUfXqI9IQeYA8LbAsCZPpJEV3aA==
dependencies:
timsort "^0.3.0"
-css-line-break@1.1.1:
- version "1.1.1"
- resolved "https://registry.yarnpkg.com/css-line-break/-/css-line-break-1.1.1.tgz#d5e9bdd297840099eb0503c7310fd34927a026ef"
- integrity sha512-1feNVaM4Fyzdj4mKPIQNL2n70MmuYzAXZ1aytlROFX1JsOo070OsugwGjj7nl6jnDJWHDM8zRZswkmeYVWZJQA==
+css-line-break@2.0.1:
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/css-line-break/-/css-line-break-2.0.1.tgz#3dc74c2ed5eb64211480281932475790243e7338"
+ integrity sha512-gwKYIMUn7xodIcb346wgUhE2Dt5O1Kmrc16PWi8sL4FTfyDj8P5095rzH7+O8CTZudJr+uw2GCI/hwEkDJFI2w==
dependencies:
base64-arraybuffer "^0.2.0"
css-loader@^5.0.1:
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.1.1.tgz#9362d444a0f7c08c148a109596715c904e252879"
- integrity sha512-5FfhpjwtuRgxqmusDidowqmLlcb+1HgnEDMsi2JhiUrZUcoc+cqw+mUtMIF/+OfeMYaaFCLYp1TaIt9H6I/fKA==
+ version "5.2.7"
+ resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.7.tgz#9b9f111edf6fb2be5dc62525644cbc9c232064ae"
+ integrity sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg==
dependencies:
- camelcase "^6.2.0"
- cssesc "^3.0.0"
icss-utils "^5.1.0"
loader-utils "^2.0.0"
- postcss "^8.2.6"
+ postcss "^8.2.15"
postcss-modules-extract-imports "^3.0.0"
postcss-modules-local-by-default "^4.0.0"
postcss-modules-scope "^3.0.0"
postcss-modules-values "^4.0.0"
postcss-value-parser "^4.1.0"
schema-utils "^3.0.0"
- semver "^7.3.4"
+ semver "^7.3.5"
css-minimizer-webpack-plugin@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.0.0.tgz#5b1edbffe1a3e6450d8cb53fb4f4c5013b7af313"
- integrity sha512-yIrqG0pPphR1RoNx2wDxYmxRf2ubRChLDXxv7ccipEm5bRKsZRYp8n+2peeXehtTF5s3yNxlqsdz3WQOsAgUkw==
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.1.1.tgz#27bafa3b75054713565b2266c64b0228acd18634"
+ integrity sha512-KlB8l5uoNcf9F7i5kXnkxoqJGd2BXH4f0+Lj2vSWSmuvMLYO1kNsJ1KHSzeDW8e45/whgSOPcKVT/3JopkT8dg==
dependencies:
- cssnano "^5.0.0"
- jest-worker "^26.3.0"
+ cssnano "^5.0.6"
+ jest-worker "^27.0.2"
p-limit "^3.0.2"
- postcss "^8.2.9"
- schema-utils "^3.0.0"
- serialize-javascript "^5.0.1"
+ postcss "^8.3.5"
+ schema-utils "^3.1.0"
+ serialize-javascript "^6.0.0"
source-map "^0.6.1"
css-select-base-adapter@^0.1.1:
@@ -4561,7 +4224,7 @@ css-select@^2.0.0:
domutils "^1.7.0"
nth-check "^1.0.2"
-css-select@^4.1.2, css-select@^4.1.3:
+css-select@^4.1.3:
version "4.1.3"
resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.1.3.tgz#a70440f70317f2669118ad74ff105e65849c7067"
integrity sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA==
@@ -4610,7 +4273,7 @@ css-what@^3.2.1:
resolved "https://registry.yarnpkg.com/css-what/-/css-what-3.4.2.tgz#ea7026fcb01777edbde52124e21f327e7ae950e4"
integrity sha512-ACUm3L0/jiZTqfzRM3Hi9Q8eZqd6IK37mMWPLz9PJxkLWllYeRf+EHUSHYEtFop2Eqytaq1FizFVh7XfBnXCDQ==
-css-what@^5.0.0:
+css-what@^5.0.0, css-what@^5.0.1:
version "5.1.0"
resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.1.0.tgz#3f7b707aadf633baf62c2ceb8579b545bb40f7fe"
integrity sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw==
@@ -4620,24 +4283,24 @@ cssesc@^3.0.0:
resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee"
integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==
-cssnano-preset-default@^5.1.1:
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.1.1.tgz#5cd783caed942cc94159aeb10583af4691445b8c"
- integrity sha512-kAhR71Tascmnjlhl4UegGA3KGGbMLXHkkqVpA9idsRT1JmIhIsz1C3tDpBeQMUw5EX5Rfb1HGc/PRqD2AFk3Vg==
+cssnano-preset-default@^5.1.5:
+ version "5.1.5"
+ resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.1.5.tgz#6effb7175ee5d296f95330e137587e27ee974d44"
+ integrity sha512-fF00UI+d3PWkGfMd62geqmoUe5h+LOhGE2GH4Fqq3beNKdCU1LWwLUyIcu4/A72lWv0737cHey5zhhWw3rW0sA==
dependencies:
css-declaration-sorter "^6.0.3"
cssnano-utils "^2.0.1"
postcss-calc "^8.0.0"
- postcss-colormin "^5.1.1"
- postcss-convert-values "^5.0.1"
+ postcss-colormin "^5.2.1"
+ postcss-convert-values "^5.0.2"
postcss-discard-comments "^5.0.1"
postcss-discard-duplicates "^5.0.1"
postcss-discard-empty "^5.0.1"
postcss-discard-overridden "^5.0.1"
postcss-merge-longhand "^5.0.2"
- postcss-merge-rules "^5.0.1"
+ postcss-merge-rules "^5.0.2"
postcss-minify-font-values "^5.0.1"
- postcss-minify-gradients "^5.0.1"
+ postcss-minify-gradients "^5.0.3"
postcss-minify-params "^5.0.1"
postcss-minify-selectors "^5.1.0"
postcss-normalize-charset "^5.0.1"
@@ -4647,12 +4310,12 @@ cssnano-preset-default@^5.1.1:
postcss-normalize-string "^5.0.1"
postcss-normalize-timing-functions "^5.0.1"
postcss-normalize-unicode "^5.0.1"
- postcss-normalize-url "^5.0.1"
+ postcss-normalize-url "^5.0.2"
postcss-normalize-whitespace "^5.0.1"
- postcss-ordered-values "^5.0.1"
+ postcss-ordered-values "^5.0.2"
postcss-reduce-initial "^5.0.1"
postcss-reduce-transforms "^5.0.1"
- postcss-svgo "^5.0.1"
+ postcss-svgo "^5.0.3"
postcss-unique-selectors "^5.0.1"
cssnano-utils@^2.0.1:
@@ -4660,14 +4323,15 @@ cssnano-utils@^2.0.1:
resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-2.0.1.tgz#8660aa2b37ed869d2e2f22918196a9a8b6498ce2"
integrity sha512-i8vLRZTnEH9ubIyfdZCAdIdgnHAUeQeByEeQ2I7oTilvP9oHO6RScpeq3GsFUVqeB8uZgOQ9pw8utofNn32hhQ==
-cssnano@^5.0.0, cssnano@^5.0.2:
- version "5.0.4"
- resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.0.4.tgz#5ca90729c94c71c4bc3d45abb543be10740bf381"
- integrity sha512-I+fDW74CJ4yb31765ov9xXe70XLZvFTXjwhmA//VgAAuSAU34Oblbe94Q9zffiCX1VhcSfQWARQnwhz+Nqgb4Q==
+cssnano@^5.0.2, cssnano@^5.0.6:
+ version "5.0.9"
+ resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.0.9.tgz#bd03168835c0883c16754085704f57861a32d99c"
+ integrity sha512-Y4olTKBKsPKl5izpcXHRDiB/1rVdbIDM4qVXgEKBt466kYT42SEEsnCYOQFFXzEkUYV8pJNCII9JKzb8KfDk+g==
dependencies:
- cosmiconfig "^7.0.0"
- cssnano-preset-default "^5.1.1"
+ cssnano-preset-default "^5.1.5"
is-resolvable "^1.1.0"
+ lilconfig "^2.0.3"
+ yaml "^1.10.2"
csso@^4.0.2, csso@^4.2.0:
version "4.2.0"
@@ -4677,9 +4341,9 @@ csso@^4.0.2, csso@^4.2.0:
css-tree "^1.1.2"
csstype@^2.5.2, csstype@^2.5.7:
- version "2.6.16"
- resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.16.tgz#544d69f547013b85a40d15bff75db38f34fe9c39"
- integrity sha512-61FBWoDHp/gRtsoDkq/B1nWrCUG/ok1E3tUrcNbZjsE9Cxd9yzUirjS3+nAATB8U4cTtaQmAHbNndoFz5L6C9Q==
+ version "2.6.18"
+ resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.18.tgz#980a8b53085f34af313410af064f2bd241784218"
+ integrity sha512-RSU6Hyeg14am3Ah4VZEmeX8H7kLwEEirXe6aU2IPfKNvhXwTflK5HQRDNI0ypQXoqmm+QPyG2IaPuQE5zMwSIQ==
csstype@^3.0.11:
version "3.0.11"
@@ -4687,9 +4351,9 @@ csstype@^3.0.11:
integrity sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==
csstype@^3.0.2:
- version "3.0.8"
- resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.8.tgz#d2266a792729fb227cd216fb572f43728e1ad340"
- integrity sha512-jXKhWqXPmlUeoQnF/EhTtTl4C9SnrxSH/jZUih3jmO6lBKr99rP3/+FmrMj4EFpOXzMtXHAZkd3x0E6h6Fgflw==
+ version "3.0.9"
+ resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.9.tgz#6410af31b26bd0520933d02cbc64fce9ce3fbf0b"
+ integrity sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw==
cubic2quad@^1.0.0:
version "1.2.1"
@@ -4715,14 +4379,14 @@ dash-ast@^1.0.0:
integrity sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==
date-fns@^2.24.0:
- version "2.24.0"
- resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.24.0.tgz#7d86dc0d93c87b76b63d213b4413337cfd1c105d"
- integrity sha512-6ujwvwgPID6zbI0o7UbURi2vlLDR9uP26+tW6Lg+Ji3w7dd0i3DOcjcClLjLPranT60SSEFBwdSyYwn/ZkPIuw==
+ version "2.25.0"
+ resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.25.0.tgz#8c5c8f1d958be3809a9a03f4b742eba894fc5680"
+ integrity sha512-ovYRFnTrbGPD4nqaEqescPEv1mNwvt+UTqI3Ay9SzNtey9NZnYu6E2qCcBBgJ6/2VF1zGGygpyTDITqpQQ5e+w==
date-format@^4.0.3:
version "4.0.3"
resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.3.tgz#f63de5dc08dc02efd8ef32bf2a6918e486f35873"
- integrity "sha1-9j3l3AjcAu/Y7zK/KmkY5IbzWHM= sha512-7P3FyqDcfeznLZp2b+OMitV9Sz2lUnsT87WaTat9nVwqsBkTzPG3lPLNwW3en6F4pHUiWzr6vb8CLhjdK9bcxQ=="
+ integrity sha512-7P3FyqDcfeznLZp2b+OMitV9Sz2lUnsT87WaTat9nVwqsBkTzPG3lPLNwW3en6F4pHUiWzr6vb8CLhjdK9bcxQ==
debug@2.6.9, debug@^2.6.8:
version "2.6.9"
@@ -4732,9 +4396,9 @@ debug@2.6.9, debug@^2.6.8:
ms "2.0.0"
debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@~4.3.1:
- version "4.3.1"
- resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
- integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
+ version "4.3.2"
+ resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b"
+ integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==
dependencies:
ms "2.1.2"
@@ -4823,9 +4487,9 @@ deep-equal-ident@^1.1.1:
lodash.isequal "^3.0"
deep-is@^0.1.3:
- version "0.1.3"
- resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
- integrity sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831"
+ integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==
deepmerge@^4.2.2:
version "4.2.2"
@@ -4894,12 +4558,12 @@ di@^0.0.1:
integrity sha1-gGZJMmzqp8qjMG112YXqJ0i6kTw=
diff-arrays-of-objects@^1.1.8:
- version "1.1.8"
- resolved "https://registry.yarnpkg.com/diff-arrays-of-objects/-/diff-arrays-of-objects-1.1.8.tgz#a5b008bb409af7c7f997f0064e312df0d5a1bb24"
- integrity sha512-OAaiDlQRiv5+EASUpwNSDa/sWyKHKvODQfah1CAx0dosR8OWXedFXgxAQHIdeWDobZ86D6g93BfK2X9ECIRuqw==
+ version "1.1.9"
+ resolved "https://registry.yarnpkg.com/diff-arrays-of-objects/-/diff-arrays-of-objects-1.1.9.tgz#b1f00485684c1bb2ac6610d2f604b51f9679064d"
+ integrity sha512-V3Uk0sm71RjLsEvH9NZcgz6+C8Fu2eBRLwlrFlwXDEj6dfHX5El6mlRUS1hTSEm6eNvLmE4ewJ+iQbXCqGvVgQ==
dependencies:
deep-diff "^1.0.2"
- lodash "^4.17.19"
+ lodash "4"
diffie-hellman@^5.0.0:
version "5.0.3"
@@ -4942,9 +4606,9 @@ dom-align@^1.7.0:
integrity sha512-pHuazgqrsTFrGU2WLDdXxCFabkdQDx72ddkraZNih1KsMcN5qsRSTR9O4VJRlwTPCPb5COYg3LOfiMHHcPInHg==
dom-helpers@^5.0.1:
- version "5.2.0"
- resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.0.tgz#57fd054c5f8f34c52a3eeffdb7e7e93cd357d95b"
- integrity sha512-Ru5o9+V8CpunKnz5LGgWXkmrH/20cGKwcHwS4m73zIvs54CN9epEmT/HLqFJW3kXpakAFkEdzgy1hzlJe3E4OQ==
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902"
+ integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==
dependencies:
"@babel/runtime" "^7.8.7"
csstype "^3.0.2"
@@ -4967,7 +4631,7 @@ dom-serializer@0:
domelementtype "^2.0.1"
entities "^2.0.0"
-dom-serializer@^1.0.1, dom-serializer@^1.3.1:
+dom-serializer@^1.0.1, dom-serializer@^1.3.2:
version "1.3.2"
resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91"
integrity sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==
@@ -4991,10 +4655,10 @@ domelementtype@^2.0.1, domelementtype@^2.2.0:
resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57"
integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==
-domhandler@4.2.0, domhandler@^4.0.0, domhandler@^4.2.0:
- version "4.2.0"
- resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.0.tgz#f9768a5f034be60a89a27c2e4d0f74eba0d8b059"
- integrity sha512-zk7sgt970kzPks2Bf+dwT/PLzghLnsivb9CcxkvR8Mzr66Olr0Ofd8neSbglHJHaHa2MadfoSdNlKYAaafmWfA==
+domhandler@4.2.2, domhandler@^4.0.0, domhandler@^4.2.0:
+ version "4.2.2"
+ resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.2.tgz#e825d721d19a86b8c201a35264e226c678ee755f"
+ integrity sha512-PzE9aBMsdZO8TK4BnuJwH0QT41wgMbRzuZrHUcpYncEjmQazq8QEaBWgLG7ZyC/DAZKEgglpIA6j4Qn/HmxS3w==
dependencies:
domelementtype "^2.2.0"
@@ -5006,10 +4670,10 @@ domutils@^1.7.0:
dom-serializer "0"
domelementtype "1"
-domutils@^2.5.2, domutils@^2.6.0:
- version "2.6.0"
- resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.6.0.tgz#2e15c04185d43fb16ae7057cb76433c6edb938b7"
- integrity sha512-y0BezHuy4MDYxh6OvolXYsH+1EMGmFbwv5FKW7ovwMG6zTPWqNPq3WF9ayZssFq+UlKdffGLbOEaghNdaOm1WA==
+domutils@^2.5.2, domutils@^2.6.0, domutils@^2.7.0:
+ version "2.8.0"
+ resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
+ integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==
dependencies:
dom-serializer "^1.0.1"
domelementtype "^2.2.0"
@@ -5084,10 +4748,10 @@ ejs@~3.1.6:
dependencies:
jake "^10.6.1"
-electron-to-chromium@^1.3.723:
- version "1.3.740"
- resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.740.tgz#e38b7d2b848f632191b643e6dabca51be2162922"
- integrity sha512-Mi2m55JrX2BFbNZGKYR+2ItcGnR4O5HhrvgoRRyZQlaMGQULqDhoGkLWHzJoshSzi7k1PUofxcDbNhlFrDZNhg==
+electron-to-chromium@^1.3.886:
+ version "1.3.889"
+ resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.889.tgz#0b7c6f7628559592d5406deda281788f37107790"
+ integrity sha512-suEUoPTD1mExjL9TdmH7cvEiWJVM2oEiAi+Y1p0QKxI2HcRlT44qDTP2c1aZmVwRemIPYOpxmV7CxQCOWcm4XQ==
electron-to-chromium@^1.4.17:
version "1.4.63"
@@ -5136,28 +4800,21 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0:
dependencies:
once "^1.4.0"
-engine.io-client@~5.1.1:
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-5.1.1.tgz#f5c3aaaef1bdc9443aac6ffde48b3b2fb2dc56fc"
- integrity sha512-jPFpw2HLL0lhZ2KY0BpZhIJdleQcUO9W1xkIpo0h3d6s+5D6+EV/xgQw9qWOmymszv2WXef/6KUUehyxEKomlQ==
+engine.io-client@~6.0.1:
+ version "6.0.2"
+ resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-6.0.2.tgz#ccfc059051e65ca63845e65929184757754cc34e"
+ integrity sha512-cAep9lhZV6Q8jMXx3TNSU5cydMzMed8/O7Tz5uzyqZvpNPtQ3WQXrLYGADxlsuaFmOLN7wZLmT7ImiFhUOku8g==
dependencies:
- base64-arraybuffer "0.1.4"
- component-emitter "~1.3.0"
+ "@socket.io/component-emitter" "~3.0.0"
debug "~4.3.1"
- engine.io-parser "~4.0.1"
+ engine.io-parser "~5.0.0"
has-cors "1.1.0"
parseqs "0.0.6"
parseuri "0.0.6"
- ws "~7.4.2"
+ ws "~8.2.3"
+ xmlhttprequest-ssl "~2.0.0"
yeast "0.1.2"
-engine.io-parser@~4.0.1:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-4.0.2.tgz#e41d0b3fb66f7bf4a3671d2038a154024edb501e"
- integrity sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==
- dependencies:
- base64-arraybuffer "0.1.4"
-
engine.io-parser@~5.0.0:
version "5.0.3"
resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-5.0.3.tgz#ca1f0d7b11e290b4bfda251803baea765ed89c09"
@@ -5181,10 +4838,10 @@ engine.io@~6.1.0:
engine.io-parser "~5.0.0"
ws "~8.2.3"
-enhanced-resolve@^5.7.0:
- version "5.8.2"
- resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.2.tgz#15ddc779345cbb73e97c611cd00c01c1e7bf4d8b"
- integrity sha512-F27oB3WuHDzvR2DOGNTaYy0D5o0cnrv8TeI482VM4kYgQd/FT9lUQwuNsJ0oOHtBUq7eiW5ytqzp7nBFknL+GA==
+enhanced-resolve@^5.8.3:
+ version "5.8.3"
+ resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz#6d552d465cce0423f5b3d718511ea53826a7b2f0"
+ integrity sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==
dependencies:
graceful-fs "^4.2.4"
tapable "^2.2.0"
@@ -5285,22 +4942,26 @@ error-ex@^1.3.1:
dependencies:
is-arrayish "^0.2.1"
-es-abstract@^1.17.2, es-abstract@^1.17.4, es-abstract@^1.18.0, es-abstract@^1.18.0-next.1, es-abstract@^1.18.0-next.2, es-abstract@^1.18.2:
- version "1.18.2"
- resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.18.2.tgz#6eb518b640262e8ddcbd48e0bc8549f82efd48a7"
- integrity sha512-byRiNIQXE6HWNySaU6JohoNXzYgbBjztwFnBLUTiJmWXjaU9bSq3urQLUlNLQ292tc+gc07zYZXNZjaOoAX3sw==
+es-abstract@^1.17.2, es-abstract@^1.18.0-next.1, es-abstract@^1.18.5, es-abstract@^1.19.0, es-abstract@^1.19.1:
+ version "1.19.1"
+ resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.19.1.tgz#d4885796876916959de78edaa0df456627115ec3"
+ integrity sha512-2vJ6tjA/UfqLm2MPs7jxVybLoB8i1t1Jd9R3kISld20sIxPcTbLuggQOUxeWeAvIUkduv/CfMjuh4WmiXr2v9w==
dependencies:
call-bind "^1.0.2"
es-to-primitive "^1.2.1"
function-bind "^1.1.1"
get-intrinsic "^1.1.1"
+ get-symbol-description "^1.0.0"
has "^1.0.3"
has-symbols "^1.0.2"
- is-callable "^1.2.3"
+ internal-slot "^1.0.3"
+ is-callable "^1.2.4"
is-negative-zero "^2.0.1"
- is-regex "^1.1.3"
- is-string "^1.0.6"
- object-inspect "^1.10.3"
+ is-regex "^1.1.4"
+ is-shared-array-buffer "^1.0.1"
+ is-string "^1.0.7"
+ is-weakref "^1.0.1"
+ object-inspect "^1.11.0"
object-keys "^1.1.1"
object.assign "^4.1.2"
string.prototype.trimend "^1.0.4"
@@ -5312,10 +4973,10 @@ es-array-method-boxes-properly@^1.0.0:
resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e"
integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==
-es-module-lexer@^0.4.0:
- version "0.4.1"
- resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.4.1.tgz#dda8c6a14d8f340a24e34331e0fab0cb50438e0e"
- integrity sha512-ooYciCUtfw6/d2w56UVeqHPcoCFAiJdz5XOkYpv/Txl1HMUozpXjz/2RIQgqwKdXNDPSF1W7mJCFse3G+HDyAA==
+es-module-lexer@^0.9.0:
+ version "0.9.3"
+ resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19"
+ integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ==
es-to-primitive@^1.2.1:
version "1.2.1"
@@ -5341,35 +5002,42 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
+escape-string-regexp@^4.0.0:
+ version "4.0.0"
+ resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34"
+ integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==
+
eslint-plugin-react-hooks@^4.3.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.3.0.tgz#318dbf312e06fab1c835a4abef00121751ac1172"
integrity sha512-XslZy0LnMn+84NEG9jSGR6eGqaZB3133L8xewQo3fQagbQuGt7a63gf+P1NGKZavEYEC3UXaWEAA/AqDkuN6xA==
eslint-plugin-react@^7.20.5:
- version "7.23.2"
- resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.23.2.tgz#2d2291b0f95c03728b55869f01102290e792d494"
- integrity sha512-AfjgFQB+nYszudkxRkTFu0UR1zEQig0ArVMPloKhxwlwkzaw/fBiH0QWcBBhZONlXqQC51+nfqFrkn4EzHcGBw==
+ version "7.26.1"
+ resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.26.1.tgz#41bcfe3e39e6a5ac040971c1af94437c80daa40e"
+ integrity sha512-Lug0+NOFXeOE+ORZ5pbsh6mSKjBKXDXItUD2sQoT+5Yl0eoT82DqnXeTMfUare4QVCn9QwXbfzO/dBLjLXwVjQ==
dependencies:
array-includes "^3.1.3"
array.prototype.flatmap "^1.2.4"
doctrine "^2.1.0"
- has "^1.0.3"
+ estraverse "^5.2.0"
jsx-ast-utils "^2.4.1 || ^3.0.0"
minimatch "^3.0.4"
- object.entries "^1.1.3"
+ object.entries "^1.1.4"
object.fromentries "^2.0.4"
- object.values "^1.1.3"
+ object.hasown "^1.0.0"
+ object.values "^1.1.4"
prop-types "^15.7.2"
resolve "^2.0.0-next.3"
- string.prototype.matchall "^4.0.4"
+ semver "^6.3.0"
+ string.prototype.matchall "^4.0.5"
eslint-rule-composer@^0.3.0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz#79320c927b0c5c0d3d3d2b76c8b4a488f25bbaf9"
integrity sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg==
-eslint-scope@^5.1.1:
+eslint-scope@5.1.1, eslint-scope@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"
integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==
@@ -5395,28 +5063,31 @@ eslint-visitor-keys@^2.0.0, eslint-visitor-keys@^2.1.0:
integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==
eslint@^7.19.0:
- version "7.21.0"
- resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.21.0.tgz#4ecd5b8c5b44f5dedc9b8a110b01bbfeb15d1c83"
- integrity sha512-W2aJbXpMNofUp0ztQaF40fveSsJBjlSCSWpy//gzfTvwC+USs/nceBrKmlJOiM8r1bLwP2EuYkCqArn/6QTIgg==
+ version "7.32.0"
+ resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d"
+ integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==
dependencies:
"@babel/code-frame" "7.12.11"
- "@eslint/eslintrc" "^0.4.0"
+ "@eslint/eslintrc" "^0.4.3"
+ "@humanwhocodes/config-array" "^0.5.0"
ajv "^6.10.0"
chalk "^4.0.0"
cross-spawn "^7.0.2"
debug "^4.0.1"
doctrine "^3.0.0"
enquirer "^2.3.5"
+ escape-string-regexp "^4.0.0"
eslint-scope "^5.1.1"
eslint-utils "^2.1.0"
eslint-visitor-keys "^2.0.0"
espree "^7.3.1"
esquery "^1.4.0"
esutils "^2.0.2"
+ fast-deep-equal "^3.1.3"
file-entry-cache "^6.0.1"
functional-red-black-tree "^1.0.1"
- glob-parent "^5.0.0"
- globals "^12.1.0"
+ glob-parent "^5.1.2"
+ globals "^13.6.0"
ignore "^4.0.6"
import-fresh "^3.0.0"
imurmurhash "^0.1.4"
@@ -5424,7 +5095,7 @@ eslint@^7.19.0:
js-yaml "^3.13.1"
json-stable-stringify-without-jsonify "^1.0.1"
levn "^0.4.1"
- lodash "^4.17.20"
+ lodash.merge "^4.6.2"
minimatch "^3.0.4"
natural-compare "^1.4.0"
optionator "^0.9.1"
@@ -5433,7 +5104,7 @@ eslint@^7.19.0:
semver "^7.2.1"
strip-ansi "^6.0.0"
strip-json-comments "^3.1.0"
- table "^6.0.4"
+ table "^6.0.9"
text-table "^0.2.0"
v8-compile-cache "^2.0.3"
@@ -5471,9 +5142,9 @@ estraverse@^4.1.1:
integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==
estraverse@^5.1.0, estraverse@^5.2.0:
- version "5.2.0"
- resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880"
- integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ==
+ version "5.3.0"
+ resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
+ integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
esutils@^2.0.2:
version "2.0.3"
@@ -5556,9 +5227,9 @@ execa@^4.0.0:
strip-final-newline "^2.0.0"
execa@^5.0.0:
- version "5.0.0"
- resolved "https://registry.yarnpkg.com/execa/-/execa-5.0.0.tgz#4029b0007998a841fbd1032e5f4de86a3c1e3376"
- integrity sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ==
+ version "5.1.1"
+ resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
+ integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==
dependencies:
cross-spawn "^7.0.3"
get-stream "^6.0.0"
@@ -5615,16 +5286,15 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
fast-glob@^3.0.3, fast-glob@^3.1.1, fast-glob@^3.2.4:
- version "3.2.5"
- resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661"
- integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg==
+ version "3.2.7"
+ resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1"
+ integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q==
dependencies:
"@nodelib/fs.stat" "^2.0.2"
"@nodelib/fs.walk" "^1.2.3"
- glob-parent "^5.1.0"
+ glob-parent "^5.1.2"
merge2 "^1.3.0"
- micromatch "^4.0.2"
- picomatch "^2.2.1"
+ micromatch "^4.0.4"
fast-json-stable-stringify@^2.0.0:
version "2.1.0"
@@ -5642,14 +5312,16 @@ fast-memoize@^2.5.1:
integrity sha512-Ue0LwpDYErFbmNnZSF0UH6eImUwDmogUO1jyE+JbN2gsQz/jICm1Ve7t9QT0rNSsfJt+Hs4/S3GnsDVjL4HVrw==
fast-safe-stringify@^2.0.7:
- version "2.0.7"
- resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743"
- integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==
+ version "2.1.1"
+ resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884"
+ integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==
fast-xml-parser@^3.19.0:
- version "3.19.0"
- resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-3.19.0.tgz#cb637ec3f3999f51406dd8ff0e6fc4d83e520d01"
- integrity sha512-4pXwmBplsCPv8FOY1WRakF970TjNGnGnfbOnLqjlYvMiF1SR3yOHyxMR/YCXpPTOspNF5gwudqktIP4VsWkvBg==
+ version "3.21.1"
+ resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-3.21.1.tgz#152a1d51d445380f7046b304672dd55d15c9e736"
+ integrity sha512-FTFVjYoBOZTJekiUsawGsSYV9QL0A+zDYCRj7y34IO6Jg+2IMYEtQa+bbictpdpV8dHxXywqU7C0gRDEOFtBFg==
+ dependencies:
+ strnum "^1.0.4"
fastest-levenshtein@^1.0.12:
version "1.0.12"
@@ -5657,9 +5329,9 @@ fastest-levenshtein@^1.0.12:
integrity sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==
fastq@^1.6.0:
- version "1.11.0"
- resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.11.0.tgz#bb9fb955a07130a918eb63c1f5161cc32a5d0858"
- integrity sha512-7Eczs8gIPDrVzT+EksYBcupqMyxSHXXrHOLRRxU2/DicV8789MRBRR8+Hc2uWzUupOs4YS4JzBmBxjjCVBxD/g==
+ version "1.13.0"
+ resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.13.0.tgz#616760f88a7526bdfc596b7cab8c18938c36b98c"
+ integrity sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==
dependencies:
reusify "^1.0.4"
@@ -5754,9 +5426,9 @@ finalhandler@1.1.2:
unpipe "~1.0.0"
find-cache-dir@^3.3.1:
- version "3.3.1"
- resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880"
- integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==
+ version "3.3.2"
+ resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b"
+ integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==
dependencies:
commondir "^1.0.1"
make-dir "^3.0.2"
@@ -5791,14 +5463,14 @@ flat-cache@^3.0.4:
rimraf "^3.0.2"
flatted@^3.1.0:
- version "3.1.1"
- resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.1.1.tgz#c4b489e80096d9df1dfc97c79871aea7c617c469"
- integrity sha512-zAoAQiudy+r5SvnSw3KJy5os/oRJYHzrzja/tBDqrZtNhUw8bt6y8OBzMWcjWr+8liV8Eb6yOhw8WZ7VFZ5ZzA==
+ version "3.2.2"
+ resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.2.tgz#64bfed5cb68fe3ca78b3eb214ad97b63bedce561"
+ integrity sha512-JaTY/wtrcSyvXJl4IMFHPKyFur1sE9AUqc0QnhOaJ0CxHtAoIV8pYDzeEfAaNEtGkOfq4gr3LBFmdXW5mOQFnA==
flatted@^3.2.4:
version "3.2.5"
resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.5.tgz#76c8584f4fc843db64702a6bd04ab7a8bd666da3"
- integrity "sha1-dshYT0/IQ9tkcCpr0Eq3qL1mbaM= sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg=="
+ integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==
follow-redirects@^1.0.0, follow-redirects@^1.14.0:
version "1.14.8"
@@ -5831,7 +5503,7 @@ fs-constants@^1.0.0:
fs-extra@^10.0.0:
version "10.0.0"
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.0.0.tgz#9ff61b655dde53fb34a82df84bb214ce802e17c1"
- integrity "sha1-n/YbZV3eU/s0qC34S7IUzoAuF8E= sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ=="
+ integrity sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==
dependencies:
graceful-fs "^4.2.0"
jsonfile "^6.0.1"
@@ -5849,7 +5521,7 @@ fs.realpath@^1.0.0:
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
-fsevents@~2.3.1, fsevents@~2.3.2:
+fsevents@~2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
@@ -5860,13 +5532,13 @@ function-bind@^1.1.1:
integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
function.prototype.name@^1.1.2, function.prototype.name@^1.1.3:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.4.tgz#e4ea839b9d3672ae99d0efd9f38d9191c5eaac83"
- integrity sha512-iqy1pIotY/RmhdFZygSSlW0wko2yxkSCKqsuv4pr8QESohpYyG/Z7B/XXvPRKTJS//960rgguE5mSRUsDdaJrQ==
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621"
+ integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==
dependencies:
call-bind "^1.0.2"
define-properties "^1.1.3"
- es-abstract "^1.18.0-next.2"
+ es-abstract "^1.19.0"
functions-have-names "^1.2.2"
functional-red-black-tree@^1.0.1:
@@ -5961,7 +5633,15 @@ get-stream@^6.0.0:
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==
-glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@^5.1.1, glob-parent@~5.1.0, glob-parent@~5.1.2:
+get-symbol-description@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6"
+ integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==
+ dependencies:
+ call-bind "^1.0.2"
+ get-intrinsic "^1.1.1"
+
+glob-parent@^5.1.1, glob-parent@^5.1.2, glob-parent@~5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4"
integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==
@@ -5973,19 +5653,7 @@ glob-to-regexp@^0.4.1:
resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e"
integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==
-glob@^7.1.0, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
- version "7.1.6"
- resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
- integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
- dependencies:
- fs.realpath "^1.0.0"
- inflight "^1.0.4"
- inherits "2"
- minimatch "^3.0.4"
- once "^1.3.0"
- path-is-absolute "^1.0.0"
-
-glob@^7.1.7:
+glob@^7.1.0, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.1.7:
version "7.2.0"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023"
integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==
@@ -6002,12 +5670,12 @@ globals@^11.1.0:
resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
-globals@^12.1.0:
- version "12.4.0"
- resolved "https://registry.yarnpkg.com/globals/-/globals-12.4.0.tgz#a18813576a41b00a24a97e7f815918c2e19925f8"
- integrity sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==
+globals@^13.6.0, globals@^13.9.0:
+ version "13.12.0"
+ resolved "https://registry.yarnpkg.com/globals/-/globals-13.12.0.tgz#4d733760304230a0082ed96e21e5c565f898089e"
+ integrity sha512-uS8X6lSKN2JumVoXrbUz+uG4BYG+eiawqm3qFcT7ammfbUHeCBoJMlHcec/S3krSk73/AE/f0szYFmgAA3kYZg==
dependencies:
- type-fest "^0.8.1"
+ type-fest "^0.20.2"
globals@^9.18.0:
version "9.18.0"
@@ -6029,9 +5697,9 @@ globby@^10.0.0:
slash "^3.0.0"
globby@^11.0.1:
- version "11.0.3"
- resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb"
- integrity sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg==
+ version "11.0.4"
+ resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5"
+ integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg==
dependencies:
array-union "^2.1.0"
dir-glob "^3.0.1"
@@ -6084,9 +5752,9 @@ got@^8.3.1:
url-to-options "^1.0.1"
graceful-fs@^4.1.10, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2, graceful-fs@^4.2.4, graceful-fs@^4.2.6:
- version "4.2.6"
- resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
- integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==
+ version "4.2.8"
+ resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a"
+ integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==
graphlib@^2.1.8:
version "2.1.8"
@@ -6158,6 +5826,13 @@ has-to-string-tag-x@^1.2.0:
dependencies:
has-symbol-support-x "^1.4.1"
+has-tostringtag@^1.0.0:
+ version "1.0.0"
+ resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25"
+ integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==
+ dependencies:
+ has-symbols "^1.0.2"
+
has-unicode@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9"
@@ -6197,11 +5872,6 @@ heap@0.2.5:
resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.5.tgz#713b65590ebcc40fcbeeaf55e851694092b39af1"
integrity sha1-cTtlWQ68xA/L7q9V6FFpQJKzmvE=
-hex-color-regex@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e"
- integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==
-
history@^5.2.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/history/-/history-5.3.0.tgz#1548abaa245ba47992f063a0783db91ef201c73b"
@@ -6222,25 +5892,15 @@ hoist-non-react-statics@^3.0.0, hoist-non-react-statics@^3.3.0, hoist-non-react-
version "3.3.2"
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
- dependencies:
- react-is "^16.7.0"
-
-hsl-regex@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/hsl-regex/-/hsl-regex-1.0.0.tgz#d49330c789ed819e276a4c0d272dffa30b18fe6e"
- integrity sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=
-
-hsla-regex@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/hsla-regex/-/hsla-regex-1.0.0.tgz#c1ce7a3168c8c6614033a4b5f7877f3b225f9c38"
- integrity sha1-wc56MWjIxmFAM6S194d/OyJfnDg=
+ dependencies:
+ react-is "^16.7.0"
-html-dom-parser@1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/html-dom-parser/-/html-dom-parser-1.0.1.tgz#5d147fed6656c12918edbcea4a423eefe8d0e715"
- integrity sha512-uKXISKlHzB/l9A08jrs2wseQJ9b864ZfEdmIZskj10cuP6HxCOMHSK0RdluV8NVQaWs0PwefN7d8wqG3jR0IbQ==
+html-dom-parser@1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/html-dom-parser/-/html-dom-parser-1.0.2.tgz#bb5ff844f214657d899aa4fb7b0a9e7d15607e96"
+ integrity sha512-Jq4oVkVSn+10ut3fyc2P/Fs1jqTo0l45cP6Q8d2ef/9jfkYwulO0QXmyLI0VUiZrXF4czpGgMEJRa52CQ6Fk8Q==
dependencies:
- domhandler "4.2.0"
+ domhandler "4.2.2"
htmlparser2 "6.1.0"
html-element-map@^1.2.0:
@@ -6257,21 +5917,22 @@ html-escaper@^2.0.0:
integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==
html-react-parser@^1.2.7:
- version "1.2.7"
- resolved "https://registry.yarnpkg.com/html-react-parser/-/html-react-parser-1.2.7.tgz#1674ed4b96b3440ad922962a3ff000e7f3325293"
- integrity sha512-gUUEgrZV0YaCxtZO2XuJDUnHSq7gOqKu1krye97cxgiZ+ipaIzspGMhATeq9lhy9gwYmwBF2YCHe/accrMMo8Q==
+ version "1.4.0"
+ resolved "https://registry.yarnpkg.com/html-react-parser/-/html-react-parser-1.4.0.tgz#bf264f38b9fdf4d94e2120f6a39586c15cb81bd0"
+ integrity sha512-v8Kxy+7L90ZFSM690oJWBNRzZWZOQquYPpQt6kDQPzQyZptXgOJ69kHSi7xdqNdm1mOfsDPwF4K9Bo/dS5gRTQ==
dependencies:
- domhandler "4.2.0"
- html-dom-parser "1.0.1"
- react-property "1.0.1"
+ domhandler "4.2.2"
+ html-dom-parser "1.0.2"
+ react-property "2.0.0"
style-to-js "1.1.0"
html2canvas@^1.0.0-rc.7:
- version "1.0.0-rc.7"
- resolved "https://registry.yarnpkg.com/html2canvas/-/html2canvas-1.0.0-rc.7.tgz#70c159ce0e63954a91169531894d08ad5627ac98"
- integrity sha512-yvPNZGejB2KOyKleZspjK/NruXVQuowu8NnV2HYG7gW7ytzl+umffbtUI62v2dCHQLDdsK6HIDtyJZ0W3neerA==
+ version "1.3.2"
+ resolved "https://registry.yarnpkg.com/html2canvas/-/html2canvas-1.3.2.tgz#951cc8388a3ce939fdac02131007ee28124afc27"
+ integrity sha512-4+zqv87/a1LsaCrINV69wVLGG8GBZcYBboz1JPWEgiXcWoD9kroLzccsBRU/L9UlfV2MAZ+3J92U9IQPVMDeSQ==
dependencies:
- css-line-break "1.1.1"
+ css-line-break "2.0.1"
+ text-segmentation "^1.0.2"
htmlescape@^1.1.0:
version "1.1.1"
@@ -6392,9 +6053,9 @@ ignore@^4.0.6:
integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==
ignore@^5.1.1, ignore@^5.1.4:
- version "5.1.8"
- resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57"
- integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==
+ version "5.1.9"
+ resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.9.tgz#9ec1a5cbe8e1446ec60d4420060d43aa6e7382fb"
+ integrity sha512-2zeMQpbKz5dhZ9IwL0gbxSW5w0NK/MSAMtNuhgIHEPmaU3vPdKPL0UdvUCXs5SS4JAwsBxysK5sFMW8ocFiVjQ==
image-minimizer-webpack-plugin@^2.2.0:
version "2.2.0"
@@ -6476,9 +6137,9 @@ import-lazy@^3.1.0:
integrity sha512-8/gvXvX2JMn0F+CDlSC4l6kOmVaLOO3XLkksI7CI3Ud95KDYJuYur2b9P/PUt/i/pDAMd/DulQsNbbbmRRsDIQ==
import-local@^3.0.2:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.2.tgz#a8cfd0431d1de4a2199703d003e3e62364fa6db6"
- integrity sha512-vjL3+w0oulAVZ0hBHnxa/Nm5TAurf9YLQJDhqRZyqb+VKGOB6LU8t9H1Nr5CIo16vh9XfJTOoHwU0B71S557gA==
+ version "3.0.3"
+ resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.0.3.tgz#4d51c2c495ca9393da259ec66b62e022920211e0"
+ integrity sha512-bE9iaUY3CXH8Cwfan/abDKAxe1KGT9kyGsBPqf6DMK/z0a2OzAsrukeYNgIH6cH5Xr452jb1TUL8rSfCLjZ9uA==
dependencies:
pkg-dir "^4.2.0"
resolve-cwd "^3.0.0"
@@ -6497,13 +6158,6 @@ imurmurhash@^0.1.4:
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
-indefinite-observable@^2.0.1:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/indefinite-observable/-/indefinite-observable-2.0.1.tgz#574af29bfbc17eb5947793797bddc94c9d859400"
- integrity sha512-G8vgmork+6H9S8lUAg1gtXEj2JxIQTo0g2PbFiYOdjkziSI0F7UYBiVwhZRuixhBCNGczAls34+5HJPyZysvxQ==
- dependencies:
- symbol-observable "1.2.0"
-
indent-string@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251"
@@ -6623,16 +6277,17 @@ is-absolute-url@^3.0.3:
integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==
is-any-array@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/is-any-array/-/is-any-array-1.0.0.tgz#bcb2c7e2d28aaa2fa02ee8f6b604b0b3a957bba7"
- integrity sha512-0o0ZsgObnylv72nO39P6M+PL7jPUEx39O6BEfZuX36IKPy/RpdudxluAIaRn/LZi5eVPDMlMBaLABzOK6bwPlw==
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-any-array/-/is-any-array-1.0.1.tgz#05fedec1a4dced1854bd279b2ec5df431e5bea9e"
+ integrity sha512-m+FSiaONxBt2W0h9XOUngMBu/WW8uzAKbSk4Ty2aeCcQJ+muBqENexvxUHtDpX65fk5AMCROxqgNX0sSAHstcw==
is-arguments@^1.0.4:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.0.tgz#62353031dfbee07ceb34656a6bde59efecae8dd9"
- integrity sha512-1Ij4lOMPl/xB5kBDn7I+b2ttPMKa8szhEIrXDuXQD/oe3HJLTLhqhgGspwgyGd6MOywBUqVvYicF72lkgDnIHg==
+ version "1.1.1"
+ resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b"
+ integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA==
dependencies:
- call-bind "^1.0.0"
+ call-bind "^1.0.2"
+ has-tostringtag "^1.0.0"
is-arrayish@^0.2.1:
version "0.2.1"
@@ -6640,9 +6295,11 @@ is-arrayish@^0.2.1:
integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=
is-bigint@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.1.tgz#6923051dfcbc764278540b9ce0e6b3213aa5ebc2"
- integrity sha512-J0ELF4yHFxHy0cmSxZuheDOz2luOdVvqjwmEcj8H/L1JHeuEDSDbeRP+Dk9kFVk5RTFzbucJ2Kb9F7ixY2QaCg==
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3"
+ integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==
+ dependencies:
+ has-bigints "^1.0.1"
is-binary-path@~2.1.0:
version "2.1.0"
@@ -6651,51 +6308,47 @@ is-binary-path@~2.1.0:
dependencies:
binary-extensions "^2.0.0"
+is-blob@^2.1.0:
+ version "2.1.0"
+ resolved "https://registry.yarnpkg.com/is-blob/-/is-blob-2.1.0.tgz#e36cd82c90653f1e1b930f11baf9c64216a05385"
+ integrity sha512-SZ/fTft5eUhQM6oF/ZaASFDEdbFVe89Imltn9uZr03wdKMcWNVYSMjQPFtg05QuNkt5l5c135ElvXEQG0rk4tw==
+
is-boolean-object@^1.0.1, is-boolean-object@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.0.tgz#e2aaad3a3a8fca34c28f6eee135b156ed2587ff0"
- integrity sha512-a7Uprx8UtD+HWdyYwnD1+ExtTgqQtD2k/1yJgtXP6wnMm8byhkoTZRl+95LLThpzNZJ5aEvi46cdH+ayMFRwmA==
+ version "1.1.2"
+ resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719"
+ integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==
dependencies:
- call-bind "^1.0.0"
+ call-bind "^1.0.2"
+ has-tostringtag "^1.0.0"
is-buffer@^1.1.0:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
-is-buffer@^2.0.3:
+is-buffer@^2.0.5:
version "2.0.5"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191"
integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==
-is-callable@^1.1.4, is-callable@^1.1.5, is-callable@^1.2.3:
- version "1.2.3"
- resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.3.tgz#8b1e0500b73a1d76c70487636f368e519de8db8e"
- integrity sha512-J1DcMe8UYTBSrKezuIUTUwjXsho29693unXM2YhJUTR2txK/eG47bvNa/wipPFmZFgr/N6f1GA66dv0mEyTIyQ==
-
-is-color-stop@^1.1.0:
- version "1.1.0"
- resolved "https://registry.yarnpkg.com/is-color-stop/-/is-color-stop-1.1.0.tgz#cfff471aee4dd5c9e158598fbe12967b5cdad345"
- integrity sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=
- dependencies:
- css-color-names "^0.0.4"
- hex-color-regex "^1.1.0"
- hsl-regex "^1.0.0"
- hsla-regex "^1.0.0"
- rgb-regex "^1.0.1"
- rgba-regex "^1.0.0"
+is-callable@^1.1.4, is-callable@^1.1.5, is-callable@^1.2.4:
+ version "1.2.4"
+ resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945"
+ integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==
is-core-module@^2.2.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.2.0.tgz#97037ef3d52224d85163f5597b2b63d9afed981a"
- integrity sha512-XRAfAdyyY5F5cOXn7hYQDqh2Xmii+DEfIcQGxK/uNwMHhIkPWO0g8msXcbzLe+MpGoR951MlqM/2iIlU4vKDdQ==
+ version "2.8.0"
+ resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.0.tgz#0321336c3d0925e497fd97f5d95cb114a5ccd548"
+ integrity sha512-vd15qHsaqrRL7dtH6QNuy0ndJmRDrS9HAM1CAiSifNUFv4x1a0CCVsj18hJ1mShxIG6T2i1sO78MkP56r0nYRw==
dependencies:
has "^1.0.3"
is-date-object@^1.0.1:
- version "1.0.4"
- resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.4.tgz#550cfcc03afada05eea3dd30981c7b09551f73e5"
- integrity sha512-/b4ZVsG7Z5XVtIxs/h9W8nvfLgSAyKYdtGWQLbqy6jA1icmgjf8WCoTKgeS4wy5tYaPePouzFMANbnj94c2Z+A==
+ version "1.0.5"
+ resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f"
+ integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==
+ dependencies:
+ has-tostringtag "^1.0.0"
is-docker@^2.1.1:
version "2.2.1"
@@ -6725,14 +6378,16 @@ is-fullwidth-code-point@^3.0.0:
integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
is-generator-function@^1.0.7:
- version "1.0.9"
- resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.9.tgz#e5f82c2323673e7fcad3d12858c83c4039f6399c"
- integrity sha512-ZJ34p1uvIfptHCN7sFTjGibB9/oBg17sHqzDLfuwhvmN/qLVvIQXRQ8licZQ35WJ8KuEQt/etnnzQFI9C9Ue/A==
+ version "1.0.10"
+ resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72"
+ integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A==
+ dependencies:
+ has-tostringtag "^1.0.0"
is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1:
- version "4.0.1"
- resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc"
- integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==
+ version "4.0.3"
+ resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084"
+ integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==
dependencies:
is-extglob "^2.1.1"
@@ -6762,9 +6417,11 @@ is-negative-zero@^2.0.1:
integrity sha512-2z6JzQvZRa9A2Y7xC6dQQm4FSTSTNWjKIYYTt4246eMTJmIo0Q+ZyOsU66X8lxK1AbB92dFeglPLrhwpeRKO6w==
is-number-object@^1.0.4:
- version "1.0.5"
- resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.5.tgz#6edfaeed7950cff19afedce9fbfca9ee6dd289eb"
- integrity sha512-RU0lI/n95pMoUKu9v1BZP5MBcZuNSVJkMkAG2dJqC4z2GlkGUNeH68SuHuBKBD/XFe+LHZ+f9BKkLET60Niedw==
+ version "1.0.6"
+ resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.6.tgz#6a7aaf838c7f0686a50b4553f7e54a96494e89f0"
+ integrity sha512-bEVOqiRcvo3zO1+G2lVMy+gkkEm9Yh7cDMRusKKu5ZJKPUYSJwICTKZrNKHA2EbSP0Tu0+6B/emsYNHZyn6K8g==
+ dependencies:
+ has-tostringtag "^1.0.0"
is-number@^7.0.0:
version "7.0.0"
@@ -6793,13 +6450,13 @@ is-png@^2.0.0:
resolved "https://registry.yarnpkg.com/is-png/-/is-png-2.0.0.tgz#ee8cbc9e9b050425cedeeb4a6fb74a649b0a4a8d"
integrity sha512-4KPGizaVGj2LK7xwJIz8o5B2ubu1D/vcQsgOGFEDlpcvgZHto4gBnyd0ig7Ws+67ixmwKoNmu0hYnpo6AaKb5g==
-is-regex@^1.0.5, is-regex@^1.1.0, is-regex@^1.1.3:
- version "1.1.3"
- resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.3.tgz#d029f9aff6448b93ebbe3f33dac71511fdcbef9f"
- integrity sha512-qSVXFz28HM7y+IWX6vLCsexdlvzT1PJNFSBuaQLQ5o0IEw8UDYW6/2+eCMVyIsbM8CNLX2a/QWmSpyxYEHY7CQ==
+is-regex@^1.0.5, is-regex@^1.1.0, is-regex@^1.1.4:
+ version "1.1.4"
+ resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958"
+ integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==
dependencies:
call-bind "^1.0.2"
- has-symbols "^1.0.2"
+ has-tostringtag "^1.0.0"
is-relative@^1.0.0:
version "1.0.0"
@@ -6818,20 +6475,27 @@ is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0:
resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4"
integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg==
+is-shared-array-buffer@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.1.tgz#97b0c85fbdacb59c9c446fe653b82cf2b5b7cfe6"
+ integrity sha512-IU0NmyknYZN0rChcKhRO1X8LYz5Isj/Fsqh8NJOSf+N/hCOTwy29F32Ik7a+QszE63IdvmwdTPDd6cZ5pg4cwA==
+
is-stream@^1.0.0, is-stream@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44"
integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
is-stream@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3"
- integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==
+ version "2.0.1"
+ resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077"
+ integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==
-is-string@^1.0.5, is-string@^1.0.6:
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.6.tgz#3fe5d5992fb0d93404f32584d4b0179a71b54a5f"
- integrity sha512-2gdzbKUuqtQ3lYNrUTQYoClPhm7oQu4UdpSZMp1/DGgkHBT8E2Z1l0yMdb6D4zNAxwDiMv8MdulKROJGNl0Q0w==
+is-string@^1.0.5, is-string@^1.0.7:
+ version "1.0.7"
+ resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd"
+ integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==
+ dependencies:
+ has-tostringtag "^1.0.0"
is-subset@^0.1.1:
version "0.1.1"
@@ -6846,22 +6510,22 @@ is-svg@^4.2.1:
fast-xml-parser "^3.19.0"
is-symbol@^1.0.2, is-symbol@^1.0.3:
- version "1.0.3"
- resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.3.tgz#38e1014b9e6329be0de9d24a414fd7441ec61937"
- integrity sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c"
+ integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==
dependencies:
- has-symbols "^1.0.1"
+ has-symbols "^1.0.2"
-is-typed-array@^1.1.3:
- version "1.1.5"
- resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.5.tgz#f32e6e096455e329eb7b423862456aa213f0eb4e"
- integrity sha512-S+GRDgJlR3PyEbsX/Fobd9cqpZBuvUS+8asRqYDMLCb2qMzt1oz5m5oxQCxOgUDxiWsOVNi4yaF+/uvdlHlYug==
+is-typed-array@^1.1.3, is-typed-array@^1.1.7:
+ version "1.1.8"
+ resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.8.tgz#cbaa6585dc7db43318bc5b89523ea384a6f65e79"
+ integrity sha512-HqH41TNZq2fgtGT8WHVFVJhBVGuY3AnP3Q36K8JKXUxSxRgk/d+7NjmwG2vo2mYmXK8UYZKu0qH8bVP5gEisjA==
dependencies:
- available-typed-arrays "^1.0.2"
+ available-typed-arrays "^1.0.5"
call-bind "^1.0.2"
- es-abstract "^1.18.0-next.2"
+ es-abstract "^1.18.5"
foreach "^2.0.5"
- has-symbols "^1.0.1"
+ has-tostringtag "^1.0.0"
is-unc-path@^1.0.0:
version "1.0.0"
@@ -6870,6 +6534,13 @@ is-unc-path@^1.0.0:
dependencies:
unc-path-regex "^0.1.2"
+is-weakref@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.1.tgz#842dba4ec17fa9ac9850df2d6efbc1737274f2a2"
+ integrity sha512-b2jKc2pQZjaeFYWEf7ScFj+Be1I+PXmlu572Q8coTXZ+LD/QQZ7ShPMst8h16riVgyXTQwUsFEl74mDvc/3MHQ==
+ dependencies:
+ call-bind "^1.0.0"
+
isarray@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf"
@@ -6911,9 +6582,9 @@ istanbul-lib-coverage@^1.2.1:
integrity sha512-PzITeunAgyGbtY1ibVIUiV679EFChHjoMNRibEIobvmrCRaIgwLxNucOSimtNWUhEib/oO7QY2imD75JVgCJWQ==
istanbul-lib-coverage@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz#f5944a37c70b550b02a78a5c3b2055b280cec8ec"
- integrity sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3"
+ integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==
istanbul-lib-instrument@^1.7.3:
version "1.10.2"
@@ -6948,18 +6619,18 @@ istanbul-lib-report@^3.0.0:
supports-color "^7.1.0"
istanbul-lib-source-maps@^4.0.0:
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.0.tgz#75743ce6d96bb86dc7ee4352cf6366a23f0b1ad9"
- integrity sha512-c16LpFRkR8vQXyHZ5nLpY35JZtzj1PQY1iZmesUbf1FZHbIupcWfjgOXBY9YHkLEQ6puz1u4Dgj6qmU/DisrZg==
+ version "4.0.1"
+ resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551"
+ integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==
dependencies:
debug "^4.1.1"
istanbul-lib-coverage "^3.0.0"
source-map "^0.6.1"
istanbul-reports@^3.0.0:
- version "3.0.2"
- resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.2.tgz#d593210e5000683750cb09fc0644e4b6e27fd53b"
- integrity sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==
+ version "3.0.5"
+ resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.5.tgz#a2580107e71279ea6d661ddede929ffc6d693384"
+ integrity sha512-5+19PlhnGabNWB7kOFnuxT8H3T/iIyQzIbQMxXsURmmvKg86P2sbkrGOT77VnHw0Qr0gc2XzRaRfMZYYbSQCJQ==
dependencies:
html-escaper "^2.0.0"
istanbul-lib-report "^3.0.0"
@@ -6983,9 +6654,9 @@ jake@^10.6.1:
minimatch "^3.0.4"
jasmine-core@^3.6.0:
- version "3.7.1"
- resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-3.7.1.tgz#0401327f6249eac993d47bbfa18d4e8efacfb561"
- integrity sha512-DH3oYDS/AUvvr22+xUBW62m1Xoy7tUlY1tsxKEJvl5JeJ7q8zd1K5bUwiOxdH+erj6l2vAMM3hV25Xs9/WrmuQ==
+ version "3.10.1"
+ resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-3.10.1.tgz#7aa6fa2b834a522315c651a128d940eca553989a"
+ integrity sha512-ooZWSDVAdh79Rrj4/nnfklL3NQVra0BcuhcuWoAwwi+znLDoUeH87AFfeX8s+YeYi6xlv5nveRyaA1v7CintfA==
jasmine-enzyme@^7.1.2:
version "7.1.2"
@@ -6999,14 +6670,14 @@ javascript-natural-sort@^0.7.1:
resolved "https://registry.yarnpkg.com/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz#f9e2303d4507f6d74355a73664d1440fb5a0ef59"
integrity sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k=
-jest-worker@^26.3.0, jest-worker@^26.6.2:
- version "26.6.2"
- resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed"
- integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ==
+jest-worker@^27.0.2, jest-worker@^27.0.6:
+ version "27.3.1"
+ resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.3.1.tgz#0def7feae5b8042be38479799aeb7b5facac24b2"
+ integrity sha512-ks3WCzsiZaOPJl/oMsDjaf0TRiSv7ctNgs0FqRr2nARsovz6AWWy4oLElwcquGSz692DzgZQrCLScPNs5YlC4g==
dependencies:
"@types/node" "*"
merge-stream "^2.0.0"
- supports-color "^7.0.0"
+ supports-color "^8.0.0"
jmespath@^0.15.0:
version "0.15.0"
@@ -7161,7 +6832,7 @@ jsoneditor@^9.5.4:
jsonfile@^6.0.1:
version "6.1.0"
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae"
- integrity "sha1-vFWyY0eTxnnsZAMJTrE2mKbsCq4= sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ=="
+ integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==
dependencies:
universalify "^2.0.0"
optionalDependencies:
@@ -7178,82 +6849,81 @@ jsonrepair@^2.2.1:
integrity sha512-o9Je8TceILo872uQC9fIBJm957j1Io7z8Ca1iWIqY6S5S65HGE9XN7XEEw7+tUviB9Vq4sygV89MVTxl+rhZyg==
jss-plugin-camel-case@^10.5.1:
- version "10.5.1"
- resolved "https://registry.yarnpkg.com/jss-plugin-camel-case/-/jss-plugin-camel-case-10.5.1.tgz#427b24a9951b4c2eaa7e3d5267acd2e00b0934f9"
- integrity sha512-9+oymA7wPtswm+zxVti1qiowC5q7bRdCJNORtns2JUj/QHp2QPXYwSNRD8+D2Cy3/CEMtdJzlNnt5aXmpS6NAg==
+ version "10.8.2"
+ resolved "https://registry.yarnpkg.com/jss-plugin-camel-case/-/jss-plugin-camel-case-10.8.2.tgz#8d7f915c8115afaff8cbde08faf610ec9892fba6"
+ integrity sha512-2INyxR+1UdNuKf4v9It3tNfPvf7IPrtkiwzofeKuMd5D58/dxDJVUQYRVg/n460rTlHUfsEQx43hDrcxi9dSPA==
dependencies:
"@babel/runtime" "^7.3.1"
hyphenate-style-name "^1.0.3"
- jss "10.5.1"
+ jss "10.8.2"
jss-plugin-default-unit@^10.5.1:
- version "10.5.1"
- resolved "https://registry.yarnpkg.com/jss-plugin-default-unit/-/jss-plugin-default-unit-10.5.1.tgz#2be385d71d50aee2ee81c2a9ac70e00592ed861b"
- integrity sha512-D48hJBc9Tj3PusvlillHW8Fz0y/QqA7MNmTYDQaSB/7mTrCZjt7AVRROExoOHEtd2qIYKOYJW3Jc2agnvsXRlQ==
+ version "10.8.2"
+ resolved "https://registry.yarnpkg.com/jss-plugin-default-unit/-/jss-plugin-default-unit-10.8.2.tgz#c66f12e02e0815d911b85c02c2a979ee7b4ce69a"
+ integrity sha512-UZ7cwT9NFYSG+SEy7noRU50s4zifulFdjkUNKE+u6mW7vFP960+RglWjTgMfh79G6OENZmaYnjHV/gcKV4nSxg==
dependencies:
"@babel/runtime" "^7.3.1"
- jss "10.5.1"
+ jss "10.8.2"
jss-plugin-global@^10.5.1:
- version "10.5.1"
- resolved "https://registry.yarnpkg.com/jss-plugin-global/-/jss-plugin-global-10.5.1.tgz#0e1793dea86c298360a7e2004721351653c7e764"
- integrity sha512-jX4XpNgoaB8yPWw/gA1aPXJEoX0LNpvsROPvxlnYe+SE0JOhuvF7mA6dCkgpXBxfTWKJsno7cDSCgzHTocRjCQ==
+ version "10.8.2"
+ resolved "https://registry.yarnpkg.com/jss-plugin-global/-/jss-plugin-global-10.8.2.tgz#1a35632a693cf50113bcc5ffe6b51969df79c4ec"
+ integrity sha512-UaYMSPsYZ7s/ECGoj4KoHC2jwQd5iQ7K+FFGnCAILdQrv7hPmvM2Ydg45ThT/sH46DqktCRV2SqjRuxeBH8nRA==
dependencies:
"@babel/runtime" "^7.3.1"
- jss "10.5.1"
+ jss "10.8.2"
jss-plugin-nested@^10.5.1:
- version "10.5.1"
- resolved "https://registry.yarnpkg.com/jss-plugin-nested/-/jss-plugin-nested-10.5.1.tgz#8753a80ad31190fb6ac6fdd39f57352dcf1295bb"
- integrity sha512-xXkWKOCljuwHNjSYcXrCxBnjd8eJp90KVFW1rlhvKKRXnEKVD6vdKXYezk2a89uKAHckSvBvBoDGsfZrldWqqQ==
+ version "10.8.2"
+ resolved "https://registry.yarnpkg.com/jss-plugin-nested/-/jss-plugin-nested-10.8.2.tgz#79f3c7f75ea6a36ae72fe52e777035bb24d230c7"
+ integrity sha512-acRvuPJOb930fuYmhkJaa994EADpt8TxI63Iyg96C8FJ9T2xRyU5T6R1IYKRwUiqZo+2Sr7fdGzRTDD4uBZaMA==
dependencies:
"@babel/runtime" "^7.3.1"
- jss "10.5.1"
+ jss "10.8.2"
tiny-warning "^1.0.2"
jss-plugin-props-sort@^10.5.1:
- version "10.5.1"
- resolved "https://registry.yarnpkg.com/jss-plugin-props-sort/-/jss-plugin-props-sort-10.5.1.tgz#ab1c167fd2d4506fb6a1c1d66c5f3ef545ff1cd8"
- integrity sha512-t+2vcevNmMg4U/jAuxlfjKt46D/jHzCPEjsjLRj/J56CvP7Iy03scsUP58Iw8mVnaV36xAUZH2CmAmAdo8994g==
+ version "10.8.2"
+ resolved "https://registry.yarnpkg.com/jss-plugin-props-sort/-/jss-plugin-props-sort-10.8.2.tgz#e25a7471868652c394562b6dc5433dcaea7dff6f"
+ integrity sha512-wqdcjayKRWBZnNpLUrXvsWqh+5J5YToAQ+8HNBNw0kZxVvCDwzhK2Nx6AKs7p+5/MbAh2PLgNW5Ym/ysbVAuqQ==
dependencies:
"@babel/runtime" "^7.3.1"
- jss "10.5.1"
+ jss "10.8.2"
jss-plugin-rule-value-function@^10.5.1:
- version "10.5.1"
- resolved "https://registry.yarnpkg.com/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.5.1.tgz#37f4030523fb3032c8801fab48c36c373004de7e"
- integrity sha512-3gjrSxsy4ka/lGQsTDY8oYYtkt2esBvQiceGBB4PykXxHoGRz14tbCK31Zc6DHEnIeqsjMUGbq+wEly5UViStQ==
+ version "10.8.2"
+ resolved "https://registry.yarnpkg.com/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.8.2.tgz#55354b55f1b2968a15976729968f767f02d64049"
+ integrity sha512-bW0EKAs+0HXpb6BKJhrn94IDdiWb0CnSluTkh0rGEgyzY/nmD1uV/Wf6KGlesGOZ9gmJzQy+9FFdxIUID1c9Ug==
dependencies:
"@babel/runtime" "^7.3.1"
- jss "10.5.1"
+ jss "10.8.2"
tiny-warning "^1.0.2"
jss-plugin-vendor-prefixer@^10.5.1:
- version "10.5.1"
- resolved "https://registry.yarnpkg.com/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.5.1.tgz#45a183a3a0eb097bdfab0986b858d99920c0bbd8"
- integrity sha512-cLkH6RaPZWHa1TqSfd2vszNNgxT1W0omlSjAd6hCFHp3KIocSrW21gaHjlMU26JpTHwkc+tJTCQOmE/O1A4FKQ==
+ version "10.8.2"
+ resolved "https://registry.yarnpkg.com/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.8.2.tgz#ebb4a482642f34091e454901e21176441dd5f475"
+ integrity sha512-DeGv18QsSiYLSVIEB2+l0af6OToUe0JB+trpzUxyqD2QRC/5AzzDrCrYffO5AHZ81QbffYvSN/pkfZaTWpRXlg==
dependencies:
"@babel/runtime" "^7.3.1"
css-vendor "^2.0.8"
- jss "10.5.1"
+ jss "10.8.2"
-jss@10.5.1, jss@^10.5.1:
- version "10.5.1"
- resolved "https://registry.yarnpkg.com/jss/-/jss-10.5.1.tgz#93e6b2428c840408372d8b548c3f3c60fa601c40"
- integrity sha512-hbbO3+FOTqVdd7ZUoTiwpHzKXIo5vGpMNbuXH1a0wubRSWLWSBvwvaq4CiHH/U42CmjOnp6lVNNs/l+Z7ZdDmg==
+jss@10.8.2, jss@^10.5.1:
+ version "10.8.2"
+ resolved "https://registry.yarnpkg.com/jss/-/jss-10.8.2.tgz#4b2a30b094b924629a64928236017a52c7c97505"
+ integrity sha512-FkoUNxI329CKQ9OQC8L72MBF9KPf5q8mIupAJ5twU7G7XREW7ahb+7jFfrjZ4iy1qvhx1HwIWUIvkZBDnKkEdQ==
dependencies:
"@babel/runtime" "^7.3.1"
csstype "^3.0.2"
- indefinite-observable "^2.0.1"
is-in-browser "^1.1.3"
tiny-warning "^1.0.2"
"jsx-ast-utils@^2.4.1 || ^3.0.0":
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.2.0.tgz#41108d2cec408c3453c1bbe8a4aae9e1e2bd8f82"
- integrity sha512-EIsmt3O3ljsU6sot/J4E1zDRxfBNrhjyf/OKjlydwgEimQuznlM4Wv7U+ueONJMyEn1WRE0K8dhi3dVAXYT24Q==
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.2.1.tgz#720b97bfe7d901b927d87c3773637ae8ea48781b"
+ integrity sha512-uP5vu8xfy2F9A6LGC22KO7e2/vGTS1MhP+18f++ZNlf0Ohaxbc9nIEwHAsejlJKyzfZzU5UIhe5ItYkitcZnZA==
dependencies:
- array-includes "^3.1.2"
+ array-includes "^3.1.3"
object.assign "^4.1.2"
junk@^3.1.0:
@@ -7298,9 +6968,9 @@ karma-coverage@^2.0.3:
minimatch "^3.0.4"
karma-jasmine-html-reporter@^1.4.0:
- version "1.6.0"
- resolved "https://registry.yarnpkg.com/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.6.0.tgz#586e17025a1b4128e9fba55d5f1e8921bfc3bc1e"
- integrity sha512-ELO9yf0cNqpzaNLsfFgXd/wxZVYkE2+ECUwhMHUD4PZ17kcsPsYsVyjquiRqyMn2jkd2sHt0IeMyAyq1MC23Fw==
+ version "1.7.0"
+ resolved "https://registry.yarnpkg.com/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-1.7.0.tgz#52c489a74d760934a1089bfa5ea4a8fcb84cc28b"
+ integrity sha512-pzum1TL7j90DTE86eFt48/s12hqwQuiD+e5aXx2Dc9wDEn2LfGq6RoAxEZZjFiN0RDSCOnosEKRZWxbQ+iMpQQ==
karma-jasmine@^4.0.1:
version "4.0.1"
@@ -7380,9 +7050,9 @@ kind-of@^6.0.2:
integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==
klona@^2.0.4:
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0"
- integrity sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA==
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.5.tgz#d166574d90076395d9963aa7a928fabb8d76afbc"
+ integrity sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==
labeled-stream-splicer@^2.0.0:
version "2.0.2"
@@ -7405,6 +7075,11 @@ levn@^0.4.1:
prelude-ls "^1.2.1"
type-check "~0.4.0"
+lilconfig@^2.0.3:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.3.tgz#68f3005e921dafbd2a2afb48379986aa6d2579fd"
+ integrity sha512-EHKqr/+ZvdKCifpNrJCKxBTgk5XupZA3y/aCPY9mxfgBzmgh93Mt/WqjjQ38oMxXuvDokaKiM3lAgvSH2sjtHg==
+
lines-and-columns@^1.1.6:
version "1.1.6"
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00"
@@ -7425,9 +7100,9 @@ loader-utils@^1.0.3, loader-utils@^1.1.0, loader-utils@^1.4.0:
json5 "^1.0.1"
loader-utils@^2.0.0:
- version "2.0.0"
- resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0"
- integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.2.tgz#d6e3b4fb81870721ae4e0868ab11dd638368c129"
+ integrity sha512-TM57VeHptv569d/GKh6TAYdzKblwDNiumOdkFnejjD0XwTH87K90w3O7AiJRqdQoXygvi1VQTJTLGhJl7WqA7A==
dependencies:
big.js "^5.2.2"
emojis-list "^3.0.0"
@@ -7459,11 +7134,6 @@ lodash._getnative@^3.0.0:
resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=
-lodash.clonedeep@^4.5.0:
- version "4.5.0"
- resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
- integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=
-
lodash.debounce@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
@@ -7526,6 +7196,11 @@ lodash.memoize@~3.0.3:
resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-3.0.4.tgz#2dcbd2c287cbc0a55cc42328bd0c736150d53e3f"
integrity sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=
+lodash.merge@^4.6.2:
+ version "4.6.2"
+ resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
+ integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
+
lodash.truncate@^4.4.2:
version "4.4.2"
resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193"
@@ -7536,7 +7211,7 @@ lodash.uniq@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
-lodash@4.*, lodash@^4.14.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4:
+lodash@4, lodash@4.*, lodash@^4.14.1, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@@ -7626,9 +7301,9 @@ make-fetch-happen@^9.1.0:
ssri "^8.0.0"
marked@^2.0.0:
- version "2.0.1"
- resolved "https://registry.yarnpkg.com/marked/-/marked-2.0.1.tgz#5e7ed7009bfa5c95182e4eb696f85e948cefcee3"
- integrity sha512-5+/fKgMv2hARmMW7DOpykr2iLhl0NgjyELk5yn92iE7z8Se1IS9n3UsFm86hFXIkvMBmVxki8+ckcpjBeyo/hw==
+ version "2.1.3"
+ resolved "https://registry.yarnpkg.com/marked/-/marked-2.1.3.tgz#bd017cef6431724fd4b27e0657f5ceb14bff3753"
+ integrity sha512-/Q+7MGzaETqifOMWYEA7HVMaZb4XbcRfaOzcSsHZEith83KGlvaSG33u0SKu89Mj5h+T8V2hM+8O45Qc5XTgwA==
matches-selector@0.0.1:
version "0.0.1"
@@ -7679,7 +7354,7 @@ microbuffer@^1.0.0:
resolved "https://registry.yarnpkg.com/microbuffer/-/microbuffer-1.0.0.tgz#8b3832ed40c87d51f47bb234913a698a756d19d2"
integrity sha1-izgy7UDIfVH0e7I0kTppinVtGdI=
-micromatch@^4.0.2:
+micromatch@^4.0.4:
version "4.0.4"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9"
integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==
@@ -7695,17 +7370,17 @@ miller-rabin@^4.0.0:
bn.js "^4.0.0"
brorand "^1.0.1"
-mime-db@1.46.0, mime-db@^1.28.0:
- version "1.46.0"
- resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.46.0.tgz#6267748a7f799594de3cbc8cde91def349661cee"
- integrity sha512-svXaP8UQRZ5K7or+ZmfNhg2xX3yKDMUzqadsSqi4NCH/KomcH75MAMYAGVlvXn4+b/xOPhS3I2uHKRUzvjY7BQ==
+mime-db@1.50.0, mime-db@^1.28.0:
+ version "1.50.0"
+ resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.50.0.tgz#abd4ac94e98d3c0e185016c67ab45d5fde40c11f"
+ integrity sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A==
mime-types@^2.1.27, mime-types@~2.1.24:
- version "2.1.29"
- resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.29.tgz#1d4ab77da64b91f5f72489df29236563754bb1b2"
- integrity sha512-Y/jMt/S5sR9OaqteJtslsFZKWOIIqMACsJSiHghlCAyhf7jfVYjKBmLiX8OgpWeW+fjJ2b+Az69aPFPkUOY6xQ==
+ version "2.1.33"
+ resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.33.tgz#1fa12a904472fafd068e48d9e8401f74d3f70edb"
+ integrity sha512-plLElXp7pRDd0bNZHw+nMd52vRYjLwQjygaNg7ddJ2uJtTlmnTCjWuPKxVu6//AdaRuME84SvLW91sIkBqGT0g==
dependencies:
- mime-db "1.46.0"
+ mime-db "1.50.0"
mime@^2.0.3, mime@^2.3.1:
version "2.5.2"
@@ -7728,9 +7403,9 @@ mimic-response@^1.0.0:
integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
mini-css-extract-plugin@^1.3.5:
- version "1.3.9"
- resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-1.3.9.tgz#47a32132b0fd97a119acd530e8421e8f6ab16d5e"
- integrity sha512-Ac4s+xhVbqlyhXS5J/Vh/QXUz3ycXlCqoCPpg0vdfhsIBH9eg/It/9L1r1XhSCH737M1lqcWnMuWL13zcygn5A==
+ version "1.6.2"
+ resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-1.6.2.tgz#83172b4fd812f8fc4a09d6f6d16f924f53990ca8"
+ integrity sha512-WhDvO3SjGm40oV5y26GjMJYjd2UMqrLAGKy5YS2/3QKJy2F7jgynuHTir/tgUUOiNQu5saXHdc8reo7YuhhT4Q==
dependencies:
loader-utils "^2.0.0"
schema-utils "^3.0.0"
@@ -7844,9 +7519,9 @@ ml-array-min@^1.2.2:
is-any-array "^1.0.0"
ml-array-rescale@^1.3.5:
- version "1.3.5"
- resolved "https://registry.yarnpkg.com/ml-array-rescale/-/ml-array-rescale-1.3.5.tgz#a41a98535e5b3bcdcde2f1ef532f4453feb11104"
- integrity sha512-czK+faN7kYrF48SgVQeXGkxUjDEas6BA4EzF4jJNh8UEtzpSvHW3RllZCJCCyrAqeFc+Y/LhgYUzuHFpevM3qA==
+ version "1.3.6"
+ resolved "https://registry.yarnpkg.com/ml-array-rescale/-/ml-array-rescale-1.3.6.tgz#060d1c636fbb5f877265f4fcc4e0e157521d615a"
+ integrity sha512-Lzj45T6hvHNdht924JQhHzInIK+ilC55zn98uraZUvLBkOWOJGOztEkRM0xyzAjWvVuhpszLADOnoVwfBSnj8w==
dependencies:
is-any-array "^1.0.0"
ml-array-max "^1.2.3"
@@ -7925,26 +7600,31 @@ ms@2.0.0:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
-ms@2.1.2, ms@^2.0.0:
+ms@2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
+ms@^2.0.0:
+ version "2.1.3"
+ resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
+ integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
+
nan@^2.14.2:
version "2.15.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee"
integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==
-nanocolors@^0.1.12:
- version "0.1.12"
- resolved "https://registry.yarnpkg.com/nanocolors/-/nanocolors-0.1.12.tgz#8577482c58cbd7b5bb1681db4cf48f11a87fd5f6"
- integrity sha512-2nMHqg1x5PU+unxX7PGY7AuYxl2qDx7PSrTRjizr8sxdd3l/3hBuWWaki62qmtYm2U5i4Z5E7GbjlyDFhs9/EQ==
-
-nanoid@^3.0.0, nanoid@^3.1.23:
+nanoid@^3.0.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.2.0.tgz#62667522da6673971cca916a6d3eff3f415ff80c"
integrity "sha1-YmZ1Itpmc5ccypFqbT7/P0Ff+Aw= sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA=="
+nanoid@^3.1.30:
+ version "3.1.30"
+ resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362"
+ integrity sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ==
+
nanopop@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/nanopop/-/nanopop-2.1.0.tgz#23476513cee2405888afd2e8a4b54066b70b9e60"
@@ -7988,9 +7668,9 @@ nice-try@^1.0.4:
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
node-gyp@^8.1.0:
- version "8.3.0"
- resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.3.0.tgz#ebc36a146d45095e1c6af6ccb0e47d1c8fc3fe69"
- integrity sha512-e+vmKyTiybKgrmvs4M2REFKCnOd+NcrAAnn99Yko6NQA+zZdMlRvbIUHojfsHrSQ1CddLgZnHicnEVgDHziJzA==
+ version "8.4.0"
+ resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.4.0.tgz#6e1112b10617f0f8559c64b3f737e8109e5a8338"
+ integrity sha512-Bi/oCm5bH6F+FmzfUxJpPaxMEyIhszULGR3TprmTeku8/dMFcdTcypk120NeZqEt54r1BrgEKtm2jJiuIKE28Q==
dependencies:
env-paths "^2.2.0"
glob "^7.1.4"
@@ -8003,11 +7683,6 @@ node-gyp@^8.1.0:
tar "^6.1.2"
which "^2.0.2"
-node-releases@^1.1.71:
- version "1.1.72"
- resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.72.tgz#14802ab6b1039a79a0c7d662b610a5bbd76eacbe"
- integrity sha512-LLUo+PpH3dU6XizX3iVoubUNheF/owjXCZZ5yACDxNnPtgFuludV1ZL3ayK1kVep42Rmm0+R9/Y60NQbZ2bifw==
-
node-releases@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5"
@@ -8039,10 +7714,10 @@ normalize-url@2.0.1:
query-string "^5.0.1"
sort-keys "^2.0.0"
-normalize-url@^4.5.0:
- version "4.5.1"
- resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a"
- integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==
+normalize-url@^6.0.1:
+ version "6.1.0"
+ resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a"
+ integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==
notificar@^1.0.1:
version "1.0.1"
@@ -8113,10 +7788,10 @@ object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
-object-inspect@^1.10.3, object-inspect@^1.7.0, object-inspect@^1.9.0:
- version "1.10.3"
- resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.10.3.tgz#c2aa7d2d09f50c99375704f7a0adf24c5782d369"
- integrity sha512-e5mCJlSH7poANfC8z8S9s9S2IN5/4Zb3aZ33f5s8YqoazCFzNLloLU8r5VCG+G7WoqLvAAZoVMcy3tp/3X0Plw==
+object-inspect@^1.11.0, object-inspect@^1.7.0, object-inspect@^1.9.0:
+ version "1.11.0"
+ resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1"
+ integrity sha512-jp7ikS6Sd3GxQfZJPyH3cjcbJF6GZPClgdV+EFygjFLQ5FmW/dRUnTd9PQ9k0JhoNDabWFbpF1yCdSWCC6gexg==
object-is@^1.0.2, object-is@^1.1.2:
version "1.1.5"
@@ -8141,42 +7816,49 @@ object.assign@^4.1.0, object.assign@^4.1.2:
has-symbols "^1.0.1"
object-keys "^1.1.1"
-object.entries@^1.1.1, object.entries@^1.1.2, object.entries@^1.1.3:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.4.tgz#43ccf9a50bc5fd5b649d45ab1a579f24e088cafd"
- integrity sha512-h4LWKWE+wKQGhtMjZEBud7uLGhqyLwj8fpHOarZhD2uY3C9cRtk57VQ89ke3moByLXMedqs3XCHzyb4AmA2DjA==
+object.entries@^1.1.1, object.entries@^1.1.2, object.entries@^1.1.4:
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861"
+ integrity sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==
dependencies:
call-bind "^1.0.2"
define-properties "^1.1.3"
- es-abstract "^1.18.2"
+ es-abstract "^1.19.1"
object.fromentries@^2.0.3, object.fromentries@^2.0.4:
- version "2.0.4"
- resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.4.tgz#26e1ba5c4571c5c6f0890cef4473066456a120b8"
- integrity sha512-EsFBshs5RUUpQEY1D4q/m59kMfz4YJvxuNCJcv/jWwOJr34EaVnG11ZrZa0UHB3wnzV1wx8m58T4hQL8IuNXlQ==
+ version "2.0.5"
+ resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.5.tgz#7b37b205109c21e741e605727fe8b0ad5fa08251"
+ integrity sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==
dependencies:
call-bind "^1.0.2"
define-properties "^1.1.3"
- es-abstract "^1.18.0-next.2"
- has "^1.0.3"
+ es-abstract "^1.19.1"
object.getownpropertydescriptors@^2.1.0:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.2.tgz#1bd63aeacf0d5d2d2f31b5e393b03a7c601a23f7"
- integrity sha512-WtxeKSzfBjlzL+F9b7M7hewDzMwy+C8NRssHd1YrNlzHzIDrXcXiNOMrezdAEM4UXixgV+vvnyBeN7Rygl2ttQ==
+ version "2.1.3"
+ resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.3.tgz#b223cf38e17fefb97a63c10c91df72ccb386df9e"
+ integrity sha512-VdDoCwvJI4QdC6ndjpqFmoL3/+HxffFBbcJzKi5hwLLqqx3mdbedRpfZDdK0SrOSauj8X4GzBvnDZl4vTN7dOw==
dependencies:
call-bind "^1.0.2"
define-properties "^1.1.3"
- es-abstract "^1.18.0-next.2"
+ es-abstract "^1.19.1"
-object.values@^1.1.0, object.values@^1.1.1, object.values@^1.1.3:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.4.tgz#0d273762833e816b693a637d30073e7051535b30"
- integrity sha512-TnGo7j4XSnKQoK3MfvkzqKCi0nVe/D9I9IjwTNYdb/fxYHpjrluHVOgw0AF6jrRFGMPHdfuidR09tIDiIvnaSg==
+object.hasown@^1.0.0:
+ version "1.1.0"
+ resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.0.tgz#7232ed266f34d197d15cac5880232f7a4790afe5"
+ integrity sha512-MhjYRfj3GBlhSkDHo6QmvgjRLXQ2zndabdf3nX0yTyZK9rPfxb6uRpAac8HXNLy1GpqWtZ81Qh4v3uOls2sRAg==
+ dependencies:
+ define-properties "^1.1.3"
+ es-abstract "^1.19.1"
+
+object.values@^1.1.0, object.values@^1.1.1, object.values@^1.1.4:
+ version "1.1.5"
+ resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac"
+ integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==
dependencies:
call-bind "^1.0.2"
define-properties "^1.1.3"
- es-abstract "^1.18.2"
+ es-abstract "^1.19.1"
on-finished@~2.3.0:
version "2.3.0"
@@ -8598,19 +8280,20 @@ postcss-calc@^8.0.0:
postcss-selector-parser "^6.0.2"
postcss-value-parser "^4.0.2"
-postcss-colormin@^5.1.1:
- version "5.1.1"
- resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.1.1.tgz#834d262f6021f832d9085e355f08ade288a92a1d"
- integrity sha512-SyTmqKKN6PyYNeeKEC0hqIP5CDuprO1hHurdW1aezDyfofDUOn7y7MaxcolbsW3oazPwFiGiY30XRiW1V4iZpA==
+postcss-colormin@^5.2.1:
+ version "5.2.1"
+ resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.2.1.tgz#6e444a806fd3c578827dbad022762df19334414d"
+ integrity sha512-VVwMrEYLcHYePUYV99Ymuoi7WhKrMGy/V9/kTS0DkCoJYmmjdOMneyhzYUxcNgteKDVbrewOkSM7Wje/MFwxzA==
dependencies:
- browserslist "^4.16.0"
- colord "^2.0.0"
+ browserslist "^4.16.6"
+ caniuse-api "^3.0.0"
+ colord "^2.9.1"
postcss-value-parser "^4.1.0"
-postcss-convert-values@^5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.0.1.tgz#4ec19d6016534e30e3102fdf414e753398645232"
- integrity sha512-C3zR1Do2BkKkCgC0g3sF8TS0koF2G+mN8xxayZx3f10cIRmTaAnpgpRQZjNekTZxM2ciSPoh2IWJm0VZx8NoQg==
+postcss-convert-values@^5.0.2:
+ version "5.0.2"
+ resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.0.2.tgz#879b849dc3677c7d6bc94b6a2c1a3f0808798059"
+ integrity sha512-KQ04E2yadmfa1LqXm7UIDwW1ftxU/QWZmz6NKnHnUvJ3LEYbbcX6i329f/ig+WnEByHegulocXrECaZGLpL8Zg==
dependencies:
postcss-value-parser "^4.1.0"
@@ -8635,9 +8318,9 @@ postcss-discard-overridden@^5.0.1:
integrity sha512-Y28H7y93L2BpJhrdUR2SR2fnSsT+3TVx1NmVQLbcnZWwIUpJ7mfcTC6Za9M2PG6w8j7UQRfzxqn8jU2VwFxo3Q==
postcss-loader@^5.0.0:
- version "5.1.0"
- resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-5.1.0.tgz#8a36f18b8989bee94172626b25f2b9cc6160fb43"
- integrity sha512-tGgKZF6Ntn16zIWXt7yKV19L0rISaozHPCfdPt+aHOnTZrreeqVR6hCkFhZYfJ6KgpyIFRkKuW8ygHtUid4GlA==
+ version "5.3.0"
+ resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-5.3.0.tgz#1657f869e48d4fdb018a40771c235e499ee26244"
+ integrity sha512-/+Z1RAmssdiSLgIZwnJHwBMnlABPgF7giYzTN2NOfr9D21IJZ4mQC1R2miwp80zno9M4zMD/umGI8cR+2EL5zw==
dependencies:
cosmiconfig "^7.0.0"
klona "^2.0.4"
@@ -8652,12 +8335,12 @@ postcss-merge-longhand@^5.0.2:
postcss-value-parser "^4.1.0"
stylehacks "^5.0.1"
-postcss-merge-rules@^5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.0.1.tgz#4ff61c5089d86845184a0f149e88d687028bef7e"
- integrity sha512-UR6R5Ph0c96QB9TMBH3ml8/kvPCThPHepdhRqAbvMRDRHQACPC8iM5NpfIC03+VRMZTGXy4L/BvFzcDFCgb+fA==
+postcss-merge-rules@^5.0.2:
+ version "5.0.2"
+ resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.0.2.tgz#d6e4d65018badbdb7dcc789c4f39b941305d410a"
+ integrity sha512-5K+Md7S3GwBewfB4rjDeol6V/RZ8S+v4B66Zk2gChRqLTCC8yjnHQ601omj9TKftS19OPGqZ/XzoqpzNQQLwbg==
dependencies:
- browserslist "^4.16.0"
+ browserslist "^4.16.6"
caniuse-api "^3.0.0"
cssnano-utils "^2.0.1"
postcss-selector-parser "^6.0.5"
@@ -8670,13 +8353,13 @@ postcss-minify-font-values@^5.0.1:
dependencies:
postcss-value-parser "^4.1.0"
-postcss-minify-gradients@^5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-5.0.1.tgz#2dc79fd1a1afcb72a9e727bc549ce860f93565d2"
- integrity sha512-odOwBFAIn2wIv+XYRpoN2hUV3pPQlgbJ10XeXPq8UY2N+9ZG42xu45lTn/g9zZ+d70NKSQD6EOi6UiCMu3FN7g==
+postcss-minify-gradients@^5.0.3:
+ version "5.0.3"
+ resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-5.0.3.tgz#f970a11cc71e08e9095e78ec3a6b34b91c19550e"
+ integrity sha512-Z91Ol22nB6XJW+5oe31+YxRsYooxOdFKcbOqY/V8Fxse1Y3vqlNRpi1cxCqoACZTQEhl+xvt4hsbWiV5R+XI9Q==
dependencies:
+ colord "^2.9.1"
cssnano-utils "^2.0.1"
- is-color-stop "^1.1.0"
postcss-value-parser "^4.1.0"
postcss-minify-params@^5.0.1:
@@ -8777,13 +8460,13 @@ postcss-normalize-unicode@^5.0.1:
browserslist "^4.16.0"
postcss-value-parser "^4.1.0"
-postcss-normalize-url@^5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-5.0.1.tgz#ffa9fe545935d8b57becbbb7934dd5e245513183"
- integrity sha512-hkbG0j58Z1M830/CJ73VsP7gvlG1yF+4y7Fd1w4tD2c7CaA2Psll+pQ6eQhth9y9EaqZSLzamff/D0MZBMbYSg==
+postcss-normalize-url@^5.0.2:
+ version "5.0.2"
+ resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-5.0.2.tgz#ddcdfb7cede1270740cf3e4dfc6008bd96abc763"
+ integrity sha512-k4jLTPUxREQ5bpajFQZpx8bCF2UrlqOTzP9kEqcEnOfwsRshWs2+oAFIHfDQB8GO2PaUaSE0NlTAYtbluZTlHQ==
dependencies:
is-absolute-url "^3.0.3"
- normalize-url "^4.5.0"
+ normalize-url "^6.0.1"
postcss-value-parser "^4.1.0"
postcss-normalize-whitespace@^5.0.1:
@@ -8793,10 +8476,10 @@ postcss-normalize-whitespace@^5.0.1:
dependencies:
postcss-value-parser "^4.1.0"
-postcss-ordered-values@^5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.0.1.tgz#79ef6e2bd267ccad3fc0c4f4a586dfd01c131f64"
- integrity sha512-6mkCF5BQ25HvEcDfrMHCLLFHlraBSlOXFnQMHYhSpDO/5jSR1k8LdEXOkv+7+uzW6o6tBYea1Km0wQSRkPJkwA==
+postcss-ordered-values@^5.0.2:
+ version "5.0.2"
+ resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.0.2.tgz#1f351426977be00e0f765b3164ad753dac8ed044"
+ integrity sha512-8AFYDSOYWebJYLyJi3fyjl6CqMEG/UVworjiyK1r573I56kb3e879sCJLGvR3merj+fAdPpVplXKQZv+ey6CgQ==
dependencies:
cssnano-utils "^2.0.1"
postcss-value-parser "^4.1.0"
@@ -8825,13 +8508,13 @@ postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector
cssesc "^3.0.0"
util-deprecate "^1.0.2"
-postcss-svgo@^5.0.1:
- version "5.0.1"
- resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.0.1.tgz#6ed5e01e164e59204978994d844c653a331a8100"
- integrity sha512-cD7DFo6tF9i5eWvwtI4irKOHCpmASFS0xvZ5EQIgEdA1AWfM/XiHHY/iss0gcKHhkqwgYmuo2M0KhJLd5Us6mg==
+postcss-svgo@^5.0.3:
+ version "5.0.3"
+ resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.0.3.tgz#d945185756e5dfaae07f9edb0d3cae7ff79f9b30"
+ integrity sha512-41XZUA1wNDAZrQ3XgWREL/M2zSw8LJPvb5ZWivljBsUQAGoEKMYm6okHsTjJxKYI4M75RQEH4KYlEM52VwdXVA==
dependencies:
postcss-value-parser "^4.1.0"
- svgo "^2.3.0"
+ svgo "^2.7.0"
postcss-unique-selectors@^5.0.1:
version "5.0.1"
@@ -8847,14 +8530,14 @@ postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0:
resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb"
integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==
-postcss@^8.2.15, postcss@^8.2.6, postcss@^8.2.9:
- version "8.2.15"
- resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.2.15.tgz#9e66ccf07292817d226fc315cbbf9bc148fbca65"
- integrity sha512-2zO3b26eJD/8rb106Qu2o7Qgg52ND5HPjcyQiK2B98O388h43A448LCslC0dI2P97wCAQRJsFvwTRcXxTKds+Q==
+postcss@^8.2.15, postcss@^8.3.5:
+ version "8.3.11"
+ resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.11.tgz#c3beca7ea811cd5e1c4a3ec6d2e7599ef1f8f858"
+ integrity sha512-hCmlUAIlUiav8Xdqw3Io4LcpA1DOt7h3LSTAC4G6JGHFFaWzI6qvFt9oilvl8BmkbBRX1IhM90ZAmpk68zccQA==
dependencies:
- colorette "^1.2.2"
- nanoid "^3.1.23"
- source-map "^0.6.1"
+ nanoid "^3.1.30"
+ picocolors "^1.0.0"
+ source-map-js "^0.6.2"
precond@^0.2.3:
version "0.2.3"
@@ -9201,6 +8884,13 @@ react-checkbox-tree@^1.7.2:
nanoid "^3.0.0"
prop-types "^15.5.8"
+react-data-grid@^7.0.0-beta.11:
+ version "7.0.0-beta.11"
+ resolved "https://registry.yarnpkg.com/react-data-grid/-/react-data-grid-7.0.0-beta.11.tgz#16e87f87ac2d1f2c33816837f1be3c4210f1e4b2"
+ integrity sha512-IjJf3GZ7HxH7uSoDaQhKXV9+L8I64xRKgLVQNCblSgvEY20mg2XlMmEjiV9KqROTUM2MqI+IlEpeBLCZRB3mEw==
+ dependencies:
+ clsx "^1.1.1"
+
react-dom@^16.6.3:
version "16.14.0"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.14.0.tgz#7ad838ec29a777fb3c75c3a190f661cf92ab8b89"
@@ -9253,10 +8943,17 @@ react-is@^16.12.0, react-is@^16.13.1, react-is@^16.7.0, react-is@^16.8.0, react-
resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0"
integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==
-react-property@1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/react-property/-/react-property-1.0.1.tgz#4ae4211557d0a0ae050a71aa8ad288c074bea4e6"
- integrity sha512-1tKOwxFn3dXVomH6pM9IkLkq2Y8oh+fh/lYW3MJ/B03URswUTqttgckOlbxY2XHF3vPG6uanSc4dVsLW/wk3wQ==
+react-leaflet@^3.2.2:
+ version "3.2.2"
+ resolved "https://registry.yarnpkg.com/react-leaflet/-/react-leaflet-3.2.2.tgz#3d779662c32a1d8729e73d24e8ad96ee5b38beef"
+ integrity sha512-5W7iWjI9+CdTGVAICe8RUyK0n+uLshr+eLQa8eBCbmstPNpCHZJTUSbju4Ws5dkS/PUCr9t5VmoIE9CXuSBEhw==
+ dependencies:
+ "@react-leaflet/core" "^1.1.1"
+
+react-property@2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/react-property/-/react-property-2.0.0.tgz#2156ba9d85fa4741faf1918b38efc1eae3c6a136"
+ integrity sha512-kzmNjIgU32mO4mmH5+iUyrqlpFQhF8K2k7eZ4fdLSOPFrD1XgEuSBv9LDEgxRXTMBqMd8ppT0x6TIzqE5pdGdw==
react-rnd@^10.3.5:
version "10.3.5"
@@ -9323,17 +9020,7 @@ react-timer-hook@^3.0.5:
resolved "https://registry.yarnpkg.com/react-timer-hook/-/react-timer-hook-3.0.5.tgz#a8d930f99b180cd88da245965a26a17df3e7457b"
integrity sha512-n+98SdmYvui2ne3KyWb3Ldu4k0NYQa3g/VzW6VEIfZJ8GAk/jJsIY700M8Nd2vNSTj05c7wKyQfJBqZ0x7zfiA==
-react-transition-group@^4.0.0, react-transition-group@^4.3.0, react-transition-group@^4.4.0:
- version "4.4.1"
- resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.1.tgz#63868f9325a38ea5ee9535d828327f85773345c9"
- integrity sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw==
- dependencies:
- "@babel/runtime" "^7.5.5"
- dom-helpers "^5.0.1"
- loose-envify "^1.4.0"
- prop-types "^15.6.2"
-
-react-transition-group@^4.4.2:
+react-transition-group@^4.0.0, react-transition-group@^4.3.0, react-transition-group@^4.4.0, react-transition-group@^4.4.2:
version "4.4.2"
resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.2.tgz#8b59a56f09ced7b55cbd53c36768b922890d5470"
integrity sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==
@@ -9417,13 +9104,6 @@ readable-stream@^3.4.0, readable-stream@^3.5.0, readable-stream@^3.6.0:
string_decoder "^1.1.1"
util-deprecate "^1.0.1"
-readdirp@~3.5.0:
- version "3.5.0"
- resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.5.0.tgz#9ba74c019b15d365278d2e91bb8c48d7b4d42c9e"
- integrity sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==
- dependencies:
- picomatch "^2.2.1"
-
readdirp@~3.6.0:
version "3.6.0"
resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7"
@@ -9432,9 +9112,9 @@ readdirp@~3.6.0:
picomatch "^2.2.1"
rechoir@^0.7.0:
- version "0.7.0"
- resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.0.tgz#32650fd52c21ab252aa5d65b19310441c7e03aca"
- integrity sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==
+ version "0.7.1"
+ resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686"
+ integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==
dependencies:
resolve "^1.9.0"
@@ -9468,9 +9148,9 @@ regenerator-runtime@^0.11.0:
integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
regenerator-runtime@^0.13.4:
- version "0.13.7"
- resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55"
- integrity sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==
+ version "0.13.9"
+ resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
+ integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
regenerator-transform@^0.14.2:
version "0.14.5"
@@ -9488,9 +9168,9 @@ regexp.prototype.flags@^1.3.1:
define-properties "^1.1.3"
regexpp@^3.1.0:
- version "3.1.0"
- resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.1.0.tgz#206d0ad0a5648cffbdb8ae46438f3dc51c9f78e2"
- integrity sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==
+ version "3.2.0"
+ resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2"
+ integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==
regexpu-core@^4.7.1:
version "4.7.1"
@@ -9632,16 +9312,6 @@ rfdc@^1.3.0:
resolved "https://registry.yarnpkg.com/rfdc/-/rfdc-1.3.0.tgz#d0b7c441ab2720d05dc4cf26e01c89631d9da08b"
integrity sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==
-rgb-regex@^1.0.1:
- version "1.0.1"
- resolved "https://registry.yarnpkg.com/rgb-regex/-/rgb-regex-1.0.1.tgz#c0e0d6882df0e23be254a475e8edd41915feaeb1"
- integrity sha1-wODWiC3w4jviVKR16O3UGRX+rrE=
-
-rgba-regex@^1.0.0:
- version "1.0.0"
- resolved "https://registry.yarnpkg.com/rgba-regex/-/rgba-regex-1.0.0.tgz#43374e2e2ca0968b0ef1523460b7d730ff22eeb3"
- integrity sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=
-
rifm@^0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/rifm/-/rifm-0.7.0.tgz#debe951a9c83549ca6b33e5919f716044c2230be"
@@ -9710,9 +9380,9 @@ sass-loader@^11.0.0:
neo-async "^2.6.2"
sass-resources-loader@^2.2.1:
- version "2.2.1"
- resolved "https://registry.yarnpkg.com/sass-resources-loader/-/sass-resources-loader-2.2.1.tgz#d7dbc36ccb25b2d8ffa508b1b8630b987df1e5c3"
- integrity sha512-WlofxbWOVnxad874IHZdWbP9eW1pbyqsTJKBsMbeB+YELvLSrZQNDTpH70s6F19BwtanR3NEFnyGwJ9WyotJTQ==
+ version "2.2.4"
+ resolved "https://registry.yarnpkg.com/sass-resources-loader/-/sass-resources-loader-2.2.4.tgz#1a86fba499e74a88cb7ce95f0c98449f348d360e"
+ integrity sha512-hIQhBygYky+rLf+4cuoGYONZ623CEH4Swo1fs1WRJkukbqdvN1VIu2KCL59du6vX92bNELzNkGPLx+NorN73xA==
dependencies:
async "^3.2.0"
chalk "^4.1.0"
@@ -9720,11 +9390,11 @@ sass-resources-loader@^2.2.1:
loader-utils "^2.0.0"
sass@^1.24.4:
- version "1.32.8"
- resolved "https://registry.yarnpkg.com/sass/-/sass-1.32.8.tgz#f16a9abd8dc530add8834e506878a2808c037bdc"
- integrity sha512-Sl6mIeGpzjIUZqvKnKETfMf0iDAswD9TNlv13A7aAF3XZlRPMq4VvJWBC2N2DXbp94MQVdNSFG6LfF/iOXrPHQ==
+ version "1.43.4"
+ resolved "https://registry.yarnpkg.com/sass/-/sass-1.43.4.tgz#68c7d6a1b004bef49af0d9caf750e9b252105d1f"
+ integrity sha512-/ptG7KE9lxpGSYiXn7Ar+lKOv37xfWsZRtFYal2QHNigyVQDx685VFT/h7ejVr+R8w7H4tmUgtulsKl5YpveOg==
dependencies:
- chokidar ">=2.0.0 <4.0.0"
+ chokidar ">=3.0.0 <4.0.0"
sax@^1.2.4, sax@~1.2.4:
version "1.2.4"
@@ -9772,12 +9442,12 @@ schema-utils@^2.6.5:
ajv "^6.12.4"
ajv-keywords "^3.5.2"
-schema-utils@^3.0.0:
- version "3.0.0"
- resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef"
- integrity sha512-6D82/xSzO094ajanoOSbe4YvXWMfn2A//8Y1+MUqFAJul5Bs+yn36xbK9OtNDcRVSBJ9jjeoXftM6CfztsjOAA==
+schema-utils@^3.0.0, schema-utils@^3.1.0, schema-utils@^3.1.1:
+ version "3.1.1"
+ resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.1.1.tgz#bc74c4b6b6995c1d88f76a8b77bea7219e0c8281"
+ integrity sha512-Y5PQxS4ITlC+EahLuXaY86TXfR7Dc5lw294alXOq86JAHCihAIZfqv8nNCWvaEJvaC51uN9hbLGeV0cFBdH+Fw==
dependencies:
- "@types/json-schema" "^7.0.6"
+ "@types/json-schema" "^7.0.8"
ajv "^6.12.5"
ajv-keywords "^3.5.2"
@@ -9820,14 +9490,7 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
-semver@^7.2.1, semver@^7.3.4:
- version "7.3.4"
- resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97"
- integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==
- dependencies:
- lru-cache "^6.0.0"
-
-semver@^7.3.5:
+semver@^7.2.1, semver@^7.3.4, semver@^7.3.5:
version "7.3.5"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
@@ -9841,6 +9504,13 @@ serialize-javascript@^5.0.1:
dependencies:
randombytes "^2.1.0"
+serialize-javascript@^6.0.0:
+ version "6.0.0"
+ resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8"
+ integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag==
+ dependencies:
+ randombytes "^2.1.0"
+
set-blocking@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
@@ -9903,9 +9573,9 @@ shebang-regex@^3.0.0:
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
shell-quote@^1.6.1:
- version "1.7.2"
- resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.2.tgz#67a7d02c76c9da24f99d20808fcaded0e0e04be2"
- integrity sha512-mRz/m/JVscCrkMyPqHc/bczi3OQHkLTqXHEFu0zDhK/qfv3UcOA4SVmRCLmos4bhjr9ekVQubj/R7waKapmiQg==
+ version "1.7.3"
+ resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.3.tgz#aa40edac170445b9a431e17bb62c0b881b9c4123"
+ integrity sha512-Vpfqwm4EnqGdlsBFNmHhxhElJYrdfcxPThu+ryKS5J8L/fhAwLazFZtq+S+TWZ9ANj2piSQLGj6NQg+lKPmxrw==
shim-loader@^1.0.1:
version "1.0.1"
@@ -9927,9 +9597,9 @@ side-channel@^1.0.4:
object-inspect "^1.9.0"
signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
- integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
+ version "3.0.5"
+ resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.5.tgz#9e3e8cc0c75a99472b44321033a7702e7738252f"
+ integrity sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ==
simple-concat@^1.0.0:
version "1.0.1"
@@ -9937,11 +9607,11 @@ simple-concat@^1.0.0:
integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==
sirv@^1.0.7:
- version "1.0.12"
- resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.12.tgz#d816c882b35489b3c63290e2f455ae3eccd5f652"
- integrity sha512-+jQoCxndz7L2tqQL4ZyzfDhky0W/4ZJip3XoOuxyQWnAwMxindLl3Xv1qT4x1YX/re0leShvTm8Uk0kQspGhBg==
+ version "1.0.18"
+ resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.18.tgz#105fab52fb656ce8a2bebbf36b11052005952899"
+ integrity sha512-f2AOPogZmXgJ9Ma2M22ZEhc1dNtRIzcEkiflMFeVTRq+OViOZMvH1IPMVOwrKaxpSaHioBJiDR0SluRqGa7atA==
dependencies:
- "@polka/url" "^1.0.0-next.15"
+ "@polka/url" "^1.0.0-next.20"
mime "^2.3.1"
totalist "^1.0.0"
@@ -9991,17 +9661,16 @@ socket.io-adapter@~2.3.3:
integrity sha512-Qd/iwn3VskrpNO60BeRyCyr8ZWw9CPZyitW4AQwmRZ8zCiyDiL+znRnWX6tDHXnWn1sJrM1+b6Mn6wEDJJ4aYQ==
socket.io-client@^4.0.0:
- version "4.1.2"
- resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-4.1.2.tgz#95ad7113318ea01fba0860237b96d71e1b1fd2eb"
- integrity sha512-RDpWJP4DQT1XeexmeDyDkm0vrFc0+bUsHDKiVGaNISJvJonhQQOMqV9Vwfg0ZpPJ27LCdan7iqTI92FRSOkFWQ==
+ version "4.3.2"
+ resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-4.3.2.tgz#9cfdb8fecac8a24d5723daf8c8749e70c8fdeb25"
+ integrity sha512-2B9LqSunN60yV8F7S84CCEEcgbYNfrn7ejIInZtLZ7ppWtiX8rGZAjvdCvbnC8bqo/9RlCNOUsORLyskxSFP1g==
dependencies:
- "@types/component-emitter" "^1.2.10"
+ "@socket.io/component-emitter" "~3.0.0"
backo2 "~1.0.2"
- component-emitter "~1.3.0"
- debug "~4.3.1"
- engine.io-client "~5.1.1"
+ debug "~4.3.2"
+ engine.io-client "~6.0.1"
parseuri "0.0.6"
- socket.io-parser "~4.0.4"
+ socket.io-parser "~4.1.1"
socket.io-parser@~4.0.4:
version "4.0.4"
@@ -10012,6 +9681,14 @@ socket.io-parser@~4.0.4:
component-emitter "~1.3.0"
debug "~4.3.1"
+socket.io-parser@~4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.1.1.tgz#0ad53d980781cab1eabe320417d8480c0133e62d"
+ integrity sha512-USQVLSkDWE5nbcY760ExdKaJxCE65kcsG/8k5FDGZVVxpD1pA7hABYXYkCUvxUuYYh/+uQw0N/fvBzfT8o07KA==
+ dependencies:
+ "@socket.io/component-emitter" "~3.0.0"
+ debug "~4.3.1"
+
socket.io@^4.2.0:
version "4.4.1"
resolved "https://registry.yarnpkg.com/socket.io/-/socket.io-4.4.1.tgz#cd6de29e277a161d176832bb24f64ee045c56ab8"
@@ -10067,15 +9744,20 @@ source-list-map@^1.1.1:
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-1.1.2.tgz#9889019d1024cce55cdc069498337ef6186a11a1"
integrity sha1-mIkBnRAkzOVc3AaUmDN+9hhqEaE=
-source-list-map@^2.0.0, source-list-map@^2.0.1:
+source-list-map@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34"
integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==
-source-map-support@^0.5.5, source-map-support@~0.5.19:
- version "0.5.19"
- resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
- integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==
+source-map-js@^0.6.2:
+ version "0.6.2"
+ resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e"
+ integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug==
+
+source-map-support@^0.5.5, source-map-support@~0.5.20:
+ version "0.5.20"
+ resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9"
+ integrity sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==
dependencies:
buffer-from "^1.0.0"
source-map "^0.6.0"
@@ -10169,7 +9851,7 @@ stream-splicer@^2.0.0:
streamroller@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/streamroller/-/streamroller-3.0.2.tgz#30418d0eee3d6c93ec897f892ed098e3a81e68b7"
- integrity "sha1-MEGNDu49bJPsiX+JLtCY46geaLc= sha512-ur6y5S5dopOaRXBuRIZ1u6GC5bcEXHRZKgfBjfCglMhmIf+roVCECjvkEYzNQOXIN2/JPnkMPW/8B3CZoKaEPA=="
+ integrity sha512-ur6y5S5dopOaRXBuRIZ1u6GC5bcEXHRZKgfBjfCglMhmIf+roVCECjvkEYzNQOXIN2/JPnkMPW/8B3CZoKaEPA==
dependencies:
date-format "^4.0.3"
debug "^4.1.1"
@@ -10189,14 +9871,14 @@ string-width@^1.0.1:
is-fullwidth-code-point "^1.0.0"
strip-ansi "^3.0.0"
-"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0:
- version "4.2.2"
- resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5"
- integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==
+"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
+ version "4.2.3"
+ resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
+ integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
- strip-ansi "^6.0.0"
+ strip-ansi "^6.0.1"
string.fromcodepoint@^0.2.1:
version "0.2.1"
@@ -10208,14 +9890,14 @@ string.prototype.codepointat@^0.2.1:
resolved "https://registry.yarnpkg.com/string.prototype.codepointat/-/string.prototype.codepointat-0.2.1.tgz#004ad44c8afc727527b108cd462b4d971cd469bc"
integrity sha512-2cBVCj6I4IOvEnjgO/hWqXjqBGsY+zwPmHl12Srk9IXSZ56Jwwmy+66XO5Iut/oQVR7t5ihYdLB0GMa4alEUcg==
-string.prototype.matchall@^4.0.4:
- version "4.0.5"
- resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz#59370644e1db7e4c0c045277690cf7b01203c4da"
- integrity sha512-Z5ZaXO0svs0M2xd/6By3qpeKpLKd9mO4v4q3oMEQrk8Ck4xOD5d5XeBOOjGrmVZZ/AHB1S0CgG4N5r1G9N3E2Q==
+string.prototype.matchall@^4.0.5:
+ version "4.0.6"
+ resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.6.tgz#5abb5dabc94c7b0ea2380f65ba610b3a544b15fa"
+ integrity sha512-6WgDX8HmQqvEd7J+G6VtAahhsQIssiZ8zl7zKh1VDMFyL3hRTJP4FTNA3RbIp2TOQ9AYNDcc7e3fH0Qbup+DBg==
dependencies:
call-bind "^1.0.2"
define-properties "^1.1.3"
- es-abstract "^1.18.2"
+ es-abstract "^1.19.1"
get-intrinsic "^1.1.1"
has-symbols "^1.0.2"
internal-slot "^1.0.3"
@@ -10223,13 +9905,13 @@ string.prototype.matchall@^4.0.4:
side-channel "^1.0.4"
string.prototype.trim@^1.2.1:
- version "1.2.4"
- resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.4.tgz#6014689baf5efaf106ad031a5fa45157666ed1bd"
- integrity sha512-hWCk/iqf7lp0/AgTF7/ddO1IWtSNPASjlzCicV5irAVdE1grjsneK26YG6xACMBEdCvO8fUST0UzDMh/2Qy+9Q==
+ version "1.2.5"
+ resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.5.tgz#a587bcc8bfad8cb9829a577f5de30dd170c1682c"
+ integrity sha512-Lnh17webJVsD6ECeovpVN17RlAKjmz4rF9S+8Y45CkMc/ufVpTkU3vZIyIC7sllQ1FCvObZnnCdNs/HXTUOTlg==
dependencies:
call-bind "^1.0.2"
define-properties "^1.1.3"
- es-abstract "^1.18.0-next.2"
+ es-abstract "^1.19.1"
string.prototype.trimend@^1.0.4:
version "1.0.4"
@@ -10273,12 +9955,12 @@ strip-ansi@^3.0.0, strip-ansi@^3.0.1:
dependencies:
ansi-regex "^2.0.0"
-strip-ansi@^6.0.0:
- version "6.0.0"
- resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532"
- integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==
+strip-ansi@^6.0.0, strip-ansi@^6.0.1:
+ version "6.0.1"
+ resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
+ integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
dependencies:
- ansi-regex "^5.0.0"
+ ansi-regex "^5.0.1"
strip-comments@^2.0.1:
version "2.0.1"
@@ -10314,6 +9996,11 @@ strip-outer@^1.0.0:
dependencies:
escape-string-regexp "^1.0.2"
+strnum@^1.0.4:
+ version "1.0.4"
+ resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.0.4.tgz#e97e36a7d6ba9f93d0d6b496b2ed0678d422832b"
+ integrity sha512-lMzNMfDpaQOLt4B2mEbfzYS0+T7dvCXeojnlGf6f1AygvWDMcWyXYaLbyICfjVu29sErR8fnRagQfBW/N/hGgw==
+
style-loader@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-2.0.0.tgz#9669602fd4690740eaaec137799a03addbbc393c"
@@ -10337,16 +10024,16 @@ style-to-object@0.3.0:
inline-style-parser "0.1.1"
styled-components@^5.2.1:
- version "5.2.1"
- resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.2.1.tgz#6ed7fad2dc233825f64c719ffbdedd84ad79101a"
- integrity sha512-sBdgLWrCFTKtmZm/9x7jkIabjFNVzCUeKfoQsM6R3saImkUnjx0QYdLwJHBjY9ifEcmjDamJDVfknWm1yxZPxQ==
+ version "5.3.3"
+ resolved "https://registry.yarnpkg.com/styled-components/-/styled-components-5.3.3.tgz#312a3d9a549f4708f0fb0edc829eb34bde032743"
+ integrity sha512-++4iHwBM7ZN+x6DtPPWkCI4vdtwumQ+inA/DdAsqYd4SVgUKJie5vXyzotA00ttcFdQkCng7zc6grwlfIfw+lw==
dependencies:
"@babel/helper-module-imports" "^7.0.0"
"@babel/traverse" "^7.4.5"
"@emotion/is-prop-valid" "^0.8.8"
"@emotion/stylis" "^0.8.4"
"@emotion/unitless" "^0.7.4"
- babel-plugin-styled-components ">= 1"
+ babel-plugin-styled-components ">= 1.12.0"
css-to-react-native "^3.0.0"
hoist-non-react-statics "^3.0.0"
shallowequal "^1.1.0"
@@ -10365,7 +10052,7 @@ stylis@4.0.13:
resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.13.tgz#f5db332e376d13cc84ecfe5dace9a2a51d954c91"
integrity sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==
-stylis@^4.0.3, stylis@^4.0.7:
+stylis@^4.0.10, stylis@^4.0.7:
version "4.0.10"
resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.10.tgz#446512d1097197ab3f02fb3c258358c3f7a14240"
integrity sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg==
@@ -10389,13 +10076,20 @@ supports-color@^5.3.0, supports-color@^5.5.0:
dependencies:
has-flag "^3.0.0"
-supports-color@^7.0.0, supports-color@^7.1.0:
+supports-color@^7.1.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
dependencies:
has-flag "^4.0.0"
+supports-color@^8.0.0:
+ version "8.1.1"
+ resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c"
+ integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==
+ dependencies:
+ has-flag "^4.0.0"
+
svg-parser@^2.0.2:
version "2.0.4"
resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5"
@@ -10461,19 +10155,6 @@ svgo@^1.2.2, svgo@^1.3.2:
unquote "~1.1.1"
util.promisify "~1.0.0"
-svgo@^2.3.0:
- version "2.7.0"
- resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.7.0.tgz#e164cded22f4408fe4978f082be80159caea1e2d"
- integrity sha512-aDLsGkre4fTDCWvolyW+fs8ZJFABpzLXbtdK1y71CKnHzAnpDxKXPj2mNKj+pyOXUCzFHzuxRJ94XOFygOWV3w==
- dependencies:
- "@trysound/sax" "0.2.0"
- commander "^7.2.0"
- css-select "^4.1.3"
- css-tree "^1.1.3"
- csso "^4.2.0"
- nanocolors "^0.1.12"
- stable "^0.1.8"
-
svgo@^2.7.0:
version "2.8.0"
resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24"
@@ -10492,11 +10173,6 @@ svgpath@^2.1.5:
resolved "https://registry.yarnpkg.com/svgpath/-/svgpath-2.3.1.tgz#b102334bebd2244b4818460ba2ebad52716a0d43"
integrity sha512-wNz6lCoj+99GMoyU7SozTfPqiLHz6WcJYZ30Z+F4lF/gPtxWHBCpZ4DhoDI0+oZ0dObKyYsJdSPGbL2mJq/qCg==
-symbol-observable@1.2.0:
- version "1.2.0"
- resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
- integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==
-
syntax-error@^1.1.1:
version "1.4.0"
resolved "https://registry.yarnpkg.com/syntax-error/-/syntax-error-1.4.0.tgz#2d9d4ff5c064acb711594a3e3b95054ad51d907c"
@@ -10504,17 +10180,16 @@ syntax-error@^1.1.1:
dependencies:
acorn-node "^1.2.0"
-table@^6.0.4:
- version "6.7.1"
- resolved "https://registry.yarnpkg.com/table/-/table-6.7.1.tgz#ee05592b7143831a8c94f3cee6aae4c1ccef33e2"
- integrity sha512-ZGum47Yi6KOOFDE8m223td53ath2enHcYLgOCjGr5ngu8bdIARQk6mN/wRMv4yMRcHnCSnHbCEha4sobQx5yWg==
+table@^6.0.9:
+ version "6.7.3"
+ resolved "https://registry.yarnpkg.com/table/-/table-6.7.3.tgz#255388439715a738391bd2ee4cbca89a4d05a9b7"
+ integrity sha512-5DkIxeA7XERBqMwJq0aHZOdMadBx4e6eDoFRuyT5VR82J0Ycg2DwM6GfA/EQAhJ+toRTaS1lIdSQCqgrmhPnlw==
dependencies:
ajv "^8.0.1"
- lodash.clonedeep "^4.5.0"
lodash.truncate "^4.4.2"
slice-ansi "^4.0.0"
- string-width "^4.2.0"
- strip-ansi "^6.0.0"
+ string-width "^4.2.3"
+ strip-ansi "^6.0.1"
tablesorter@^2.31.2:
version "2.31.3"
@@ -10524,9 +10199,9 @@ tablesorter@^2.31.2:
jquery ">=1.2.6"
tapable@^2.1.1, tapable@^2.2.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.0.tgz#5c373d281d9c672848213d0e037d1c4165ab426b"
- integrity sha512-FBk4IesMV1rBxX2tfiK8RAmogtWn53puLOQlvO8XuwlgxcYbP4mVPS9Ph4aeamSyyVjOl24aYWAuc8U5kCVwMw==
+ version "2.2.1"
+ resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0"
+ integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==
tar-stream@^1.5.2:
version "1.6.2"
@@ -10586,26 +10261,33 @@ tempusdominus-core@^5.0.3:
moment "~2.24.0"
moment-timezone "^0.5.28"
-terser-webpack-plugin@^5.1.1:
- version "5.1.2"
- resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.1.2.tgz#51d295eb7cc56785a67a372575fdc46e42d5c20c"
- integrity sha512-6QhDaAiVHIQr5Ab3XUWZyDmrIPCHMiqJVljMF91YKyqwKkL5QHnYMkrMBy96v9Z7ev1hGhSEw1HQZc2p/s5Z8Q==
+terser-webpack-plugin@^5.1.1, terser-webpack-plugin@^5.1.3:
+ version "5.2.4"
+ resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.2.4.tgz#ad1be7639b1cbe3ea49fab995cbe7224b31747a1"
+ integrity sha512-E2CkNMN+1cho04YpdANyRrn8CyN4yMy+WdFKZIySFZrGXZxJwJP6PMNGGc/Mcr6qygQHUUqRxnAPmi0M9f00XA==
dependencies:
- jest-worker "^26.6.2"
+ jest-worker "^27.0.6"
p-limit "^3.1.0"
- schema-utils "^3.0.0"
- serialize-javascript "^5.0.1"
+ schema-utils "^3.1.1"
+ serialize-javascript "^6.0.0"
source-map "^0.6.1"
- terser "^5.7.0"
+ terser "^5.7.2"
-terser@^5.7.0:
- version "5.7.0"
- resolved "https://registry.yarnpkg.com/terser/-/terser-5.7.0.tgz#a761eeec206bc87b605ab13029876ead938ae693"
- integrity sha512-HP5/9hp2UaZt5fYkuhNBR8YyRcT8juw8+uFbAme53iN9hblvKnLUTKkmwJG6ocWpIKf8UK4DoeWG4ty0J6S6/g==
+terser@^5.7.2:
+ version "5.9.0"
+ resolved "https://registry.yarnpkg.com/terser/-/terser-5.9.0.tgz#47d6e629a522963240f2b55fcaa3c99083d2c351"
+ integrity sha512-h5hxa23sCdpzcye/7b8YqbE5OwKca/ni0RQz1uRX3tGh8haaGHqcuSqbGRybuAKNdntZ0mDgFNXPJ48xQ2RXKQ==
dependencies:
commander "^2.20.0"
source-map "~0.7.2"
- source-map-support "~0.5.19"
+ source-map-support "~0.5.20"
+
+text-segmentation@^1.0.2:
+ version "1.0.2"
+ resolved "https://registry.yarnpkg.com/text-segmentation/-/text-segmentation-1.0.2.tgz#1f828fa14aa101c114ded1bda35ba7dcc17c9858"
+ integrity sha512-uTqvLxdBrVnx/CFQOtnf8tfzSXFm+1Qxau7Xi54j4OPTZokuDOX8qncQzrg2G8ZicAMOM8TgzFAYTb+AqNO4Cw==
+ dependencies:
+ utrie "^1.0.1"
text-table@^0.2.0:
version "0.2.0"
@@ -10653,11 +10335,11 @@ tiny-warning@^1.0.2:
integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
tippy.js@^6.3.1:
- version "6.3.1"
- resolved "https://registry.yarnpkg.com/tippy.js/-/tippy.js-6.3.1.tgz#3788a007be7015eee0fd589a66b98fb3f8f10181"
- integrity sha512-JnFncCq+rF1dTURupoJ4yPie5Cof978inW6/4S6kmWV7LL9YOSEVMifED3KdrVPEG+Z/TFH2CDNJcQEfaeuQww==
+ version "6.3.5"
+ resolved "https://registry.yarnpkg.com/tippy.js/-/tippy.js-6.3.5.tgz#cbc99d34f87ccc127e6460032b86c8d47971d38f"
+ integrity sha512-B9hAQ5KNF+jDJRg6cRysV6Y3J+5fiNfD60GuXR5TP0sfrcltpgdzVc7f1wMtjQ3W0+Xsy80CDvk0Z+Vr0cM4sQ==
dependencies:
- "@popperjs/core" "^2.8.3"
+ "@popperjs/core" "^2.9.0"
tmp@^0.2.1:
version "0.2.1"
@@ -10688,11 +10370,6 @@ to-regex-range@^5.0.1:
dependencies:
is-number "^7.0.0"
-toggle-selection@^1.0.6:
- version "1.0.6"
- resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32"
- integrity sha1-bkWxJj8gF/oKzH2J14sVuL932jI=
-
toidentifier@1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
@@ -10721,9 +10398,9 @@ tslib@2.3.0:
integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==
tslib@^2.2.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c"
- integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w==
+ version "2.3.1"
+ resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01"
+ integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==
ttf2eot@^2.0.0:
version "2.0.0"
@@ -10776,10 +10453,10 @@ type-fest@^0.11.0:
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.11.0.tgz#97abf0872310fed88a5c466b25681576145e33f1"
integrity sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==
-type-fest@^0.8.1:
- version "0.8.1"
- resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
- integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
+type-fest@^0.20.2:
+ version "0.20.2"
+ resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"
+ integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
type-is@~1.6.17:
version "1.6.18"
@@ -10805,9 +10482,9 @@ ua-parser-js@^0.7.30:
integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==
uglify-js@^3.1.4:
- version "3.14.2"
- resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.2.tgz#d7dd6a46ca57214f54a2d0a43cad0f35db82ac99"
- integrity sha512-rtPMlmcO4agTUfz10CbgJ1k6UAoXM2gWb3GoMPPZB/+/Ackf8lNWk11K4rYi2D0apgoFRLtQOZhb+/iGNJq26A==
+ version "3.14.3"
+ resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.14.3.tgz#c0f25dfea1e8e5323eccf59610be08b6043c15cf"
+ integrity sha512-mic3aOdiq01DuSVx0TseaEzMIVqebMZ0Z3vaeDhFEh9bsc24hV1TFvN74reA2vs08D0ZWfNjAcJ3UbVLaBss+g==
umd@^3.0.0:
version "3.0.3"
@@ -10921,7 +10598,7 @@ unique-slug@^2.0.0:
universalify@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717"
- integrity "sha1-daSYTv7cSwiXXFrrc/Uw0C3yVxc= sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ=="
+ integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==
unpipe@1.0.0, unpipe@~1.0.0:
version "1.0.0"
@@ -11004,9 +10681,9 @@ util@0.10.3:
inherits "2.0.1"
util@~0.12.0:
- version "0.12.3"
- resolved "https://registry.yarnpkg.com/util/-/util-0.12.3.tgz#971bb0292d2cc0c892dab7c6a5d37c2bec707888"
- integrity sha512-I8XkoQwE+fPQEhy9v012V+TSdH2kp9ts29i20TaaDUXsg7x/onePbhFJUExBfv/2ay1ZOp/Vsm3nDlmnFGSAog==
+ version "0.12.4"
+ resolved "https://registry.yarnpkg.com/util/-/util-0.12.4.tgz#66121a31420df8f01ca0c464be15dfa1d1850253"
+ integrity sha512-bxZ9qtSlGUWSOy9Qa9Xgk11kSslpuZwaxCg4sNIDj6FLucDab2JxnHwyNTCpHMtK1MjoQiWQ6DiUMZYbSrO+Sw==
dependencies:
inherits "^2.0.3"
is-arguments "^1.0.4"
@@ -11020,12 +10697,19 @@ utils-merge@1.0.1:
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
+utrie@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/utrie/-/utrie-1.0.1.tgz#e155235ebcbddc89ae09261ab6e773ce61401b2f"
+ integrity sha512-JPaDXF3vzgZxfeEwutdGzlrNoVFL5UvZcbO6Qo9D4GoahrieUPoMU8GCpVpR7MQqcKhmShIh8VlbEN3PLM3EBg==
+ dependencies:
+ base64-arraybuffer "^1.0.1"
+
uuid@^3.0.1:
version "3.4.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
-v8-compile-cache@^2.0.3, v8-compile-cache@^2.2.0:
+v8-compile-cache@^2.0.3:
version "2.3.0"
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
@@ -11038,9 +10722,9 @@ valid-filename@^2.0.1:
filename-reserved-regex "^2.0.0"
vanilla-picker@^2.11.2:
- version "2.11.2"
- resolved "https://registry.yarnpkg.com/vanilla-picker/-/vanilla-picker-2.11.2.tgz#eaa24efa68c27e7ee9e0776df55d6913b855f133"
- integrity sha512-2cP7LlUnxHxwOf06ReUVtd2RFJMnJGaxN2s0p8wzBH3In5b00Le7fFZ9VrIoBE0svZkSq/BC/Pwq/k/9n+AA2g==
+ version "2.12.1"
+ resolved "https://registry.yarnpkg.com/vanilla-picker/-/vanilla-picker-2.12.1.tgz#6e619eecf553891b8d2d042b745a23c91f19f34c"
+ integrity sha512-2qrEP9VYylKXbyzXKsbu2dferBTvqnlsr29XjHwFE+/MEp0VNj6oEUESLDtKZ7DWzGdSv1x/+ujqFZF+KsO3cg==
dependencies:
"@sphinxxxx/color-conversion" "^2.2.2"
@@ -11071,7 +10755,7 @@ void-elements@^2.0.0:
resolved "https://registry.yarnpkg.com/void-elements/-/void-elements-2.0.1.tgz#c066afb582bb1cb4128d60ea92392e94d5e9dbec"
integrity sha1-wGavtYK7HLQSjWDqkjkulNXp2+w=
-watchpack@^2.0.0:
+watchpack@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.2.0.tgz#47d78f5415fe550ecd740f99fe2882323a58b1ce"
integrity sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA==
@@ -11098,14 +10782,14 @@ webfonts-loader@^7.3.0:
loader-utils "^2.0.0"
webpack-bundle-analyzer@^4.4.0:
- version "4.4.2"
- resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.4.2.tgz#39898cf6200178240910d629705f0f3493f7d666"
- integrity sha512-PIagMYhlEzFfhMYOzs5gFT55DkUdkyrJi/SxJp8EF3YMWhS+T9vvs2EoTetpk5qb6VsCq02eXTlRDOydRhDFAQ==
+ version "4.5.0"
+ resolved "https://registry.yarnpkg.com/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.5.0.tgz#1b0eea2947e73528754a6f9af3e91b2b6e0f79d5"
+ integrity sha512-GUMZlM3SKwS8Z+CKeIFx7CVoHn3dXFcUAjT/dcZQQmfSZGvitPfMob2ipjai7ovFFqPvTqkEZ/leL4O0YOdAYQ==
dependencies:
acorn "^8.0.4"
acorn-walk "^8.0.0"
chalk "^4.1.0"
- commander "^6.2.0"
+ commander "^7.2.0"
gzip-size "^6.0.0"
lodash "^4.17.20"
opener "^1.5.2"
@@ -11113,22 +10797,21 @@ webpack-bundle-analyzer@^4.4.0:
ws "^7.3.1"
webpack-cli@^4.5.0:
- version "4.7.0"
- resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.7.0.tgz#3195a777f1f802ecda732f6c95d24c0004bc5a35"
- integrity sha512-7bKr9182/sGfjFm+xdZSwgQuFjgEcy0iCTIBxRUeteJ2Kr8/Wz0qNJX+jw60LU36jApt4nmMkep6+W5AKhok6g==
+ version "4.9.1"
+ resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.9.1.tgz#b64be825e2d1b130f285c314caa3b1ba9a4632b3"
+ integrity sha512-JYRFVuyFpzDxMDB+v/nanUdQYcZtqFPGzmlW4s+UkPMFhSpfRNmf1z4AwYcHJVdvEFAM7FFCQdNTpsBYhDLusQ==
dependencies:
"@discoveryjs/json-ext" "^0.5.0"
- "@webpack-cli/configtest" "^1.0.3"
- "@webpack-cli/info" "^1.2.4"
- "@webpack-cli/serve" "^1.4.0"
- colorette "^1.2.1"
+ "@webpack-cli/configtest" "^1.1.0"
+ "@webpack-cli/info" "^1.4.0"
+ "@webpack-cli/serve" "^1.6.0"
+ colorette "^2.0.14"
commander "^7.0.0"
execa "^5.0.0"
fastest-levenshtein "^1.0.12"
import-local "^3.0.2"
interpret "^2.2.0"
rechoir "^0.7.0"
- v8-compile-cache "^2.2.0"
webpack-merge "^5.7.3"
webpack-merge@^4.1.5:
@@ -11139,9 +10822,9 @@ webpack-merge@^4.1.5:
lodash "^4.17.15"
webpack-merge@^5.7.3:
- version "5.7.3"
- resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.7.3.tgz#2a0754e1877a25a8bbab3d2475ca70a052708213"
- integrity sha512-6/JUQv0ELQ1igjGDzHkXbVDRxkfA57Zw7PfiupdLFJYrgFqY5ZP8xxbpp2lU3EPwYx89ht5Z/aDkD40hFCm5AA==
+ version "5.8.0"
+ resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.8.0.tgz#2b39dbf22af87776ad744c390223731d30a68f61"
+ integrity sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==
dependencies:
clone-deep "^4.0.1"
wildcard "^2.0.0"
@@ -11162,30 +10845,28 @@ webpack-sources@^1.1.0:
source-list-map "^2.0.0"
source-map "~0.6.1"
-webpack-sources@^2.1.1:
- version "2.3.0"
- resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-2.3.0.tgz#9ed2de69b25143a4c18847586ad9eccb19278cfa"
- integrity sha512-WyOdtwSvOML1kbgtXbTDnEW0jkJ7hZr/bDByIwszhWd/4XX1A3XMkrbFMsuH4+/MfLlZCUzlAdg4r7jaGKEIgQ==
- dependencies:
- source-list-map "^2.0.1"
- source-map "^0.6.1"
+webpack-sources@^3.2.0:
+ version "3.2.1"
+ resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.1.tgz#251a7d9720d75ada1469ca07dbb62f3641a05b6d"
+ integrity sha512-t6BMVLQ0AkjBOoRTZgqrWm7xbXMBzD+XDq2EZ96+vMfn3qKgsvdXZhbPZ4ElUOpdv4u+iiGe+w3+J75iy/bYGA==
webpack@^5.21.2:
- version "5.24.3"
- resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.24.3.tgz#6ec0f5059f8d7c7961075fa553cfce7b7928acb3"
- integrity sha512-x7lrWZ7wlWAdyKdML6YPvfVZkhD1ICuIZGODE5SzKJjqI9A4SpqGTjGJTc6CwaHqn19gGaoOR3ONJ46nYsn9rw==
+ version "5.61.0"
+ resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.61.0.tgz#fa827f0ee9bdfd141dd73c3e891e955ebd52fe7f"
+ integrity sha512-fPdTuaYZ/GMGFm4WrPi2KRCqS1vDp773kj9S0iI5Uc//5cszsFEDgHNaX4Rj1vobUiU1dFIV3mA9k1eHeluFpw==
dependencies:
"@types/eslint-scope" "^3.7.0"
- "@types/estree" "^0.0.46"
- "@webassemblyjs/ast" "1.11.0"
- "@webassemblyjs/wasm-edit" "1.11.0"
- "@webassemblyjs/wasm-parser" "1.11.0"
- acorn "^8.0.4"
+ "@types/estree" "^0.0.50"
+ "@webassemblyjs/ast" "1.11.1"
+ "@webassemblyjs/wasm-edit" "1.11.1"
+ "@webassemblyjs/wasm-parser" "1.11.1"
+ acorn "^8.4.1"
+ acorn-import-assertions "^1.7.6"
browserslist "^4.14.5"
chrome-trace-event "^1.0.2"
- enhanced-resolve "^5.7.0"
- es-module-lexer "^0.4.0"
- eslint-scope "^5.1.1"
+ enhanced-resolve "^5.8.3"
+ es-module-lexer "^0.9.0"
+ eslint-scope "5.1.1"
events "^3.2.0"
glob-to-regexp "^0.4.1"
graceful-fs "^4.2.4"
@@ -11193,11 +10874,11 @@ webpack@^5.21.2:
loader-runner "^4.2.0"
mime-types "^2.1.27"
neo-async "^2.6.2"
- schema-utils "^3.0.0"
+ schema-utils "^3.1.0"
tapable "^2.1.1"
- terser-webpack-plugin "^5.1.1"
- watchpack "^2.0.0"
- webpack-sources "^2.1.1"
+ terser-webpack-plugin "^5.1.3"
+ watchpack "^2.2.0"
+ webpack-sources "^3.2.0"
which-boxed-primitive@^1.0.2:
version "1.0.2"
@@ -11211,17 +10892,16 @@ which-boxed-primitive@^1.0.2:
is-symbol "^1.0.3"
which-typed-array@^1.1.2:
- version "1.1.4"
- resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.4.tgz#8fcb7d3ee5adf2d771066fba7cf37e32fe8711ff"
- integrity sha512-49E0SpUe90cjpoc7BOJwyPHRqSAd12c10Qm2amdEZrJPCY2NDxaW01zHITrem+rnETY3dwrbH3UUrUwagfCYDA==
+ version "1.1.7"
+ resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.7.tgz#2761799b9a22d4b8660b3c1b40abaa7739691793"
+ integrity sha512-vjxaB4nfDqwKI0ws7wZpxIlde1XrLX5uB0ZjpfshgmapJMD7jJWhZI+yToJTqaFByF0eNBcYxbjmCzoRP7CfEw==
dependencies:
- available-typed-arrays "^1.0.2"
- call-bind "^1.0.0"
- es-abstract "^1.18.0-next.1"
+ available-typed-arrays "^1.0.5"
+ call-bind "^1.0.2"
+ es-abstract "^1.18.5"
foreach "^2.0.5"
- function-bind "^1.1.1"
- has-symbols "^1.0.1"
- is-typed-array "^1.1.3"
+ has-tostringtag "^1.0.0"
+ is-typed-array "^1.1.7"
which@^1.2.1, which@^1.2.9:
version "1.3.1"
@@ -11280,10 +10960,10 @@ wrappy@1:
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
-ws@^7.3.1, ws@~7.4.2:
- version "7.4.6"
- resolved "https://registry.yarnpkg.com/ws/-/ws-7.4.6.tgz#5654ca8ecdeee47c33a9a4bf6d28e2be2980377c"
- integrity sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==
+ws@^7.3.1:
+ version "7.5.5"
+ resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.5.tgz#8b4bc4af518cfabd0473ae4f99144287b33eb881"
+ integrity sha512-BAkMFcAzl8as1G/hArkxOxq3G7pjUqQ3gzYbLL0/5zNkph70e+lCoxBGnm6AW1+/aiNeV4fnKqZ8m4GZewmH2w==
ws@~8.2.3:
version "8.2.3"
@@ -11295,6 +10975,11 @@ xmldom@~0.5.0:
resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.5.0.tgz#193cb96b84aa3486127ea6272c4596354cb4962e"
integrity sha512-Foaj5FXVzgn7xFzsKeNIde9g6aFBxTPi37iwsno8QvApmtg7KYrr+OPyRHcJF7dud2a5nGRBXK3n0dL62Gf7PA==
+xmlhttprequest-ssl@~2.0.0:
+ version "2.0.0"
+ resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz#91360c86b914e67f44dce769180027c0da618c67"
+ integrity sha512-QKxVRxiRACQcVuQEYFsI1hhkrMlrXHPegbbd1yn9UHOmRxY+si12nQYzri3vbzt8VdTTRviqcKxcyllFas5z2A==
+
xtend@^4.0.0, xtend@^4.0.1, xtend@^4.0.2, xtend@~4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
@@ -11306,9 +10991,9 @@ xterm-addon-fit@^0.5.0:
integrity sha512-DsS9fqhXHacEmsPxBJZvfj2la30Iz9xk+UKjhQgnYNkrUIN5CYLbw7WEfz117c7+S86S/tpHPfvNxJsF5/G8wQ==
xterm-addon-search@^0.8.0:
- version "0.8.0"
- resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.8.0.tgz#e33eab918df7eac7e7baf95dd2b3d14133754881"
- integrity sha512-MPJGPVPpHRUw9cLIuqQbrVepmENMOybVUSxIALz5h1ryyQBrVqVujq2hL5aroX5/dZJoHx9lGHQTVLQ07SKgKA==
+ version "0.8.1"
+ resolved "https://registry.yarnpkg.com/xterm-addon-search/-/xterm-addon-search-0.8.1.tgz#dfc557e9bcf5fd8ed96292c0d271aa865bc545d5"
+ integrity sha512-OtOaC9gxD2Q4ZnjZrCSRZmKLwwUjXX3gP7mIzq8Rs50317DGRDqgTLuHTYv/Nx/LvI5ceVFRYCxK36Ixs1nXNw==
xterm-addon-web-links@^0.4.0:
version "0.4.0"
@@ -11316,9 +11001,9 @@ xterm-addon-web-links@^0.4.0:
integrity sha512-xv8GeiINmx0zENO9hf5k+5bnkaE8mRzF+OBAr9WeFq2eLaQSudioQSiT34M1ofKbzcdjSsKiZm19Rw3i4eXamg==
xterm@^4.11.0:
- version "4.12.0"
- resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.12.0.tgz#db09b425b4dcae5b96f8cbbaaa93b3bc60997ca9"
- integrity sha512-K5mF/p3txUV18mjiZFlElagoHFpqXrm5OYHeoymeXSu8GG/nMaOO/+NRcNCwfdjzAbdQ5VLF32hEHiWWKKm0bw==
+ version "4.14.1"
+ resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.14.1.tgz#6884cb8fb3b83353b1a98139ea23daedf8e35796"
+ integrity sha512-jgzNg5BuGPwq5/M4dGnmbghZvHx2jaj+9crSEt15bV34Za49VziBmCu7zIy88zUKKiGTxeo7aVzirFSJArIMFw==
y18n@^5.0.5:
version "5.0.8"
@@ -11335,15 +11020,15 @@ yallist@^4.0.0:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
-yaml@^1.10.0, yaml@^1.7.2:
+yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2:
version "1.10.2"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
yargs-parser@^20.2.2:
- version "20.2.6"
- resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.6.tgz#69f920addf61aafc0b8b89002f5d66e28f2d8b20"
- integrity sha512-AP1+fQIWSM/sMiET8fyayjx/J+JmTPt2Mr0FkrgqB4todtfa53sOsrSAcIrJRD5XS20bKUwaDIuMkWKCEiQLKA==
+ version "20.2.9"
+ resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee"
+ integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==
yargs@^16.1.1:
version "16.2.0"