diff --git a/docs/en_US/release_notes_6_0.rst b/docs/en_US/release_notes_6_0.rst index 17d45a4d4..64837f853 100644 --- a/docs/en_US/release_notes_6_0.rst +++ b/docs/en_US/release_notes_6_0.rst @@ -15,6 +15,7 @@ Housekeeping ************ | `Issue #5741 `_ - Revisit all the CREATE and DROP DDL's to add appropriate 'IF EXISTS', 'CASCADE' and 'CREATE OR REPLACE'. +| `Issue #6129 `_ - Port browser tree to React. | `Issue #6588 `_ - Port object nodes and properties dialogs to React. | `Issue #6687 `_ - Port Grant Wizard to react. | `Issue #6692 `_ - Remove GPDB support completely. diff --git a/web/package.json b/web/package.json index 0299a208a..7d9031791 100644 --- a/web/package.json +++ b/web/package.json @@ -66,7 +66,12 @@ "webpack": "^5.21.2", "webpack-bundle-analyzer": "^4.4.0", "webpack-cli": "^4.5.0", - "yarn-audit-html": "^2.0.0" + "yarn-audit-html": "^2.0.0", + "@babel/preset-typescript": "^7.8.3", + "@babel/plugin-proposal-object-rest-spread": "^7.10.1", + "typescript": "^3.2.2", + "svgo": "^1.1.1", + "svgo-loader": "^2.2.0" }, "dependencies": { "@babel/plugin-proposal-class-properties": "^7.10.4", @@ -144,7 +149,21 @@ "xterm": "^4.11.0", "xterm-addon-fit": "^0.5.0", "xterm-addon-search": "^0.8.0", - "xterm-addon-web-links": "^0.4.0" + "xterm-addon-web-links": "^0.4.0", + "pgadmin4-tree": "git+https://github.com/EnterpriseDB/pgadmin4-treeview/#b09740eb89595f99a925aaca9be5afa4be0fa3cc", + "react-aspen": "^1.1.0", + "@types/classnames": "^2.2.6", + "@types/react": "^16.7.18", + "@types/react-dom": "^16.0.11", + "aspen-decorations": "^1.0.2", + "browserfs": "^1.4.3", + "classnames": "^2.2.6", + "context-menu": "^2.0.0", + "insert-if": "^1.1.0", + "notificar": "^1.0.1", + "path-fx": "^2.0.0", + "valid-filename": "^2.0.1", + "url-loader": "^1.1.2" }, "scripts": { "linter": "yarn eslint --no-eslintrc -c .eslintrc.js --ext .js --ext .jsx .", diff --git a/web/pgadmin/browser/__init__.py b/web/pgadmin/browser/__init__.py index 7fe8fed80..084fb178a 100644 --- a/web/pgadmin/browser/__init__.py +++ b/web/pgadmin/browser/__init__.py @@ -487,7 +487,7 @@ class BrowserPluginModule(PgAdminModule): browser tree. """ obj = { - "id": "%s/%s" % (node_type, node_id), + "id": "%s_%s" % (node_type, node_id), "label": label, "icon": icon, "inode": inode, diff --git a/web/pgadmin/browser/collection.py b/web/pgadmin/browser/collection.py index 4155061a3..5b29b9b54 100644 --- a/web/pgadmin/browser/collection.py +++ b/web/pgadmin/browser/collection.py @@ -90,7 +90,7 @@ class CollectionNodeModule(PgAdminModule, PGChildModule): self, node_id, parent_id, label, icon, **kwargs ): obj = { - "id": "%s/%s" % (self.node_type, node_id), + "id": "%s_%s" % (self.node_type, node_id), "label": label, "icon": self.node_icon if not icon else icon, "inode": self.node_inode @@ -107,7 +107,7 @@ class CollectionNodeModule(PgAdminModule, PGChildModule): def generate_browser_collection_node(self, parent_id, **kwargs): obj = { - "id": "coll-%s/%d" % (self.node_type, parent_id), + "id": "coll-%s_%d" % (self.node_type, parent_id), "label": self.collection_label, "icon": self.collection_icon, "inode": True, diff --git a/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js b/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js index 30b2705a9..9820711c9 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js +++ b/web/pgadmin/browser/server_groups/servers/databases/publications/static/js/publication.js @@ -134,7 +134,7 @@ define('pgadmin.node.publication', [ canCreate: function(itemData, item) { - var treeData = this.getTreeNodeHierarchy(item), + var treeData = pgBrowser.tree.getTreeNodeHierarchy(item), server = treeData['server']; // If server is less than 10 then do not allow 'create' menu diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/static/js/collation.ui.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/static/js/collation.ui.js index 34ce98f74..b6227c137 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/static/js/collation.ui.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/collations/static/js/collation.ui.js @@ -48,7 +48,7 @@ export default class CollationSchema extends BaseUISchema { { id: 'owner', label: gettext('Owner'), type: 'select', mode: ['properties', 'create', 'edit'], - options: obj.ownerList + options: obj.ownerList, controlProps: { allowClear: false }, }, { id: 'schema', label: gettext('Schema'), @@ -65,7 +65,7 @@ export default class CollationSchema extends BaseUISchema { res.push(d); }); return res; - } + }, allowClear: false, } }; } diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js index ad9d9a46f..b83401c4c 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/procedure.js @@ -80,7 +80,7 @@ define('pgadmin.node.procedure', [ ]); }, canCreateProc: function(itemData, item) { - var node_hierarchy = this.getTreeNodeHierarchy.apply(this, [item]); + var node_hierarchy = pgBrowser.tree.getTreeNodeHierarchy(item); // Do not provide Create option in catalog if ('catalog' in node_hierarchy) diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/trigger_function.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/trigger_function.js index e70b17956..95a3c5e63 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/trigger_function.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/functions/static/js/trigger_function.js @@ -43,7 +43,7 @@ define('pgadmin.node.trigger_function', [ label: gettext('Trigger function'), collection_type: 'coll-trigger_function', canEdit: function(itemData, item) { - let node = pgBrowser.treeMenu.findNodeByDomElement(item); + let node = pgBrowser.tree.findNodeByDomElement(item); if (!node || node.parentNode.getData()._type === 'trigger') return false; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.js index 94c34b29a..811a76745 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/packages/static/js/package.js @@ -78,7 +78,7 @@ define('pgadmin.node.package', [ if (data && data.check == false) return true; - var treeData = this.getTreeNodeHierarchy(item), + var treeData = pgBrowser.tree.getTreeNodeHierarchy(item), server = treeData['server']; if (server && server.server_type === 'pg') diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/schema.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/schema.js index 46e01185d..dbc1e86d7 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/schema.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/schema.js @@ -409,7 +409,7 @@ define('pgadmin.node.schema', [ }); pgBrowser.tableChildTreeNodeHierarchy = function(i) { - return this.getTreeNodeHierarchy(i); + return pgBrowser.tree.getTreeNodeHierarchy(i); }; } diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/schema_child_tree_node.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/schema_child_tree_node.js index d62c7f297..f4e107234 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/schema_child_tree_node.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/static/js/schema_child_tree_node.js @@ -7,7 +7,9 @@ // ///////////////////////////////////////////////////////////// -import * as pgBrowser from 'pgbrowser/browser'; +import pgAdmin from 'sources/pgadmin'; + +let pgBrowser = pgAdmin.Browser; export function childCreateMenuEnabled(itemData, item, data) { // If check is false then , we will allow create menu @@ -15,7 +17,7 @@ export function childCreateMenuEnabled(itemData, item, data) { return true; } - let node = pgBrowser.treeMenu.findNodeByDomElement(item); + let node = pgBrowser.tree.findNodeByDomElement(item); if (node) return node.anyFamilyMember( @@ -26,7 +28,7 @@ export function childCreateMenuEnabled(itemData, item, data) { } export function isTreeItemOfChildOfSchema(itemData, item) { - let node = pgBrowser.treeMenu.findNodeByDomElement(item); + let node = pgBrowser.tree.findNodeByDomElement(item); if (node) return isTreeNodeOfSchemaChild(node); diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/static/js/synonym.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/static/js/synonym.js index 36749506f..5fd3b3283 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/static/js/synonym.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/synonyms/static/js/synonym.js @@ -152,7 +152,7 @@ define('pgadmin.node.synonym', [ if (data && data.check == false) return true; - var treeData = this.getTreeNodeHierarchy(item), + var treeData = pgBrowser.tree.getTreeNodeHierarchy(item), server = treeData['server']; if (server && server.server_type === 'pg') diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/columns/static/js/column.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/columns/static/js/column.js index e526302ff..ef27c57fd 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/columns/static/js/column.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/columns/static/js/column.js @@ -41,7 +41,7 @@ define('pgadmin.node.column', [ sqlCreateHelp: 'sql-altertable.html', dialogHelp: url_for('help.static', {'filename': 'column_dialog.html'}), canDrop: function(itemData, item){ - let node = pgBrowser.treeMenu.findNodeByDomElement(item); + let node = pgBrowser.tree.findNodeByDomElement(item); if (!node) return false; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/static/js/compound_trigger.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/static/js/compound_trigger.js index 783af99d0..cac03d252 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/static/js/compound_trigger.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/compound_triggers/static/js/compound_trigger.js @@ -108,7 +108,7 @@ define('pgadmin.node.compound_trigger', [ obj = this, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (!d) return false; @@ -146,7 +146,7 @@ define('pgadmin.node.compound_trigger', [ obj = this, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (!d) return false; @@ -206,7 +206,7 @@ define('pgadmin.node.compound_trigger', [ if (data && data.check == false) return true; - var treeData = this.getTreeNodeHierarchy(item), + var treeData = pgBrowser.tree.getTreeNodeHierarchy(item), server = treeData['server']; if (server && (server.server_type === 'pg' || server.version < 120000)) @@ -221,7 +221,7 @@ define('pgadmin.node.compound_trigger', [ }, // Check to whether trigger is disable ? canCreate_with_compound_trigger_enable: function(itemData, item, data) { - var treeData = this.getTreeNodeHierarchy(item); + var treeData = pgBrowser.tree.getTreeNodeHierarchy(item); if ('view' in treeData) { return false; } @@ -231,7 +231,7 @@ define('pgadmin.node.compound_trigger', [ }, // Check to whether trigger is enable ? canCreate_with_compound_trigger_disable: function(itemData, item, data) { - var treeData = this.getTreeNodeHierarchy(item); + var treeData = pgBrowser.tree.getTreeNodeHierarchy(item); if ('view' in treeData) { return false; } diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/static/js/check_constraint.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/static/js/check_constraint.js index 1e1454c7d..d10eace47 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/static/js/check_constraint.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/check_constraint/static/js/check_constraint.js @@ -64,7 +64,7 @@ define('pgadmin.node.check_constraint', [ obj = this, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (d) { var data = d; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/static/js/foreign_key.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/static/js/foreign_key.js index 75007f685..2d8bb6076 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/static/js/foreign_key.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/foreign_key/static/js/foreign_key.js @@ -61,7 +61,7 @@ define('pgadmin.node.foreign_key', [ obj = this, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (d) { var data = d; @@ -99,7 +99,7 @@ define('pgadmin.node.foreign_key', [ var t = pgBrowser.tree, i = item, d = itemData, parents = [], immediate_parent_table_found = false, is_immediate_parent_table_partitioned = false, - s_version = this.getTreeNodeHierarchy(i).server.version; + s_version = t.getTreeNodeHierarchy(i).server.version; // To iterate over tree to check parent node while (i) { diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/primary_key.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/primary_key.js index 0a44e7958..742f767cf 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/primary_key.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/primary_key.js @@ -58,7 +58,7 @@ define('pgadmin.node.primary_key', [ var t = pgBrowser.tree, i = item, d = itemData, parents = [], immediate_parent_table_found = false, is_immediate_parent_table_partitioned = false, - s_version = this.getTreeNodeHierarchy(i).server.version; + s_version = t.getTreeNodeHierarchy(i).server.version; // To iterate over tree to check parent node while (i) { @@ -81,7 +81,7 @@ define('pgadmin.node.primary_key', [ primary_key_found = false; _.each(children, function(child){ - data = pgBrowser.tree.itemData($(child)); + data = pgBrowser.tree.itemData(child); if (!primary_key_found && data._type == 'primary_key') { primary_key_found = true; } diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/unique_constraint.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/unique_constraint.js index d018959ed..7b2a8fe87 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/unique_constraint.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/constraints/index_constraint/static/js/unique_constraint.js @@ -57,7 +57,7 @@ define('pgadmin.node.unique_constraint', [ var t = pgBrowser.tree, i = item, d = itemData, parents = [], immediate_parent_table_found = false, is_immediate_parent_table_partitioned = false, - s_version = this.getTreeNodeHierarchy(i).server.version; + s_version = pgBrowser.tree.getTreeNodeHierarchy(i).server.version; // To iterate over tree to check parent node while (i) { diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js index e2c43c627..2d1348305 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/indexes/static/js/index.js @@ -124,7 +124,7 @@ define('pgadmin.node.index', [ var t = pgBrowser.tree, i = item, d = itemData, parents = [], immediate_parent_table_found = false, is_immediate_parent_table_partitioned = false, - s_version = this.getTreeNodeHierarchy(i).server.version; + s_version = t.getTreeNodeHierarchy(i).server.version; // To iterate over tree to check parent node while (i) { // Do not allow creating index on partitioned tables. diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.js index c8980f031..210c333d2 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/partitions/static/js/partition.js @@ -116,7 +116,7 @@ function( } info = (_.isUndefined(item) || _.isNull(item)) ? - info || {} : this.getTreeNodeHierarchy(item); + info || {} : pgBrowser.tree.getTreeNodeHierarchy(item); return pgadminUtils.sprintf('table/%s/%s/%s/%s/%s/%s', encodeURIComponent(type), encodeURIComponent(info['server_group']._id), @@ -146,7 +146,7 @@ function( obj = this, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (!d) return false; @@ -188,7 +188,7 @@ function( obj = this, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (!d) return false; @@ -232,7 +232,7 @@ function( obj = this, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (!d) return false; @@ -276,7 +276,7 @@ function( obj = this, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (!d) return false; @@ -294,15 +294,14 @@ function( if (res.success == 1) { Alertify.success(res.info); var n = t.next(i); - if (!n || !n.length) { + if (!n) { n = t.prev(i); - if (!n || !n.length) { + if (!n) { n = t.parent(i); - t.setInode(n, true); } } t.remove(i); - if (n.length) { + if (n) { t.select(n); } } diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/row_security_policies/static/js/row_security_policy.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/row_security_policies/static/js/row_security_policy.js index c7162cc35..06e3b978b 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/row_security_policies/static/js/row_security_policy.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/row_security_policies/static/js/row_security_policy.js @@ -148,7 +148,7 @@ define('pgadmin.node.row_security_policy', [ }), canCreate: function(itemData, item) { - var treeData = this.getTreeNodeHierarchy(item), + var treeData = pgBrowser.tree.getTreeNodeHierarchy(item), server = treeData['server']; // If node is under catalog then do not allow 'create' menu diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js index 87e6299c1..963400145 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/table.js @@ -140,7 +140,7 @@ define('pgadmin.node.table', [ /* Enable trigger(s) on table */ enable_triggers_on_table: function(args) { tableFunctions.enableTriggers( - pgBrowser.treeMenu, + pgBrowser.tree, Alertify, this.generate_url.bind(this), args @@ -149,7 +149,7 @@ define('pgadmin.node.table', [ /* Disable trigger(s) on table */ disable_triggers_on_table: function(args) { tableFunctions.disableTriggers( - pgBrowser.treeMenu, + pgBrowser.tree, Alertify, this.generate_url.bind(this), args @@ -174,7 +174,7 @@ define('pgadmin.node.table', [ obj = this, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (!d) return false; @@ -219,7 +219,7 @@ define('pgadmin.node.table', [ obj = this, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (!d) return false; @@ -263,7 +263,7 @@ define('pgadmin.node.table', [ obj = this, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (!d) return false; diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/static/js/trigger.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/static/js/trigger.js index 2b9904e0d..2067ce267 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/static/js/trigger.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/tables/triggers/static/js/trigger.js @@ -102,7 +102,7 @@ define('pgadmin.node.trigger', [ obj = this, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (!d) return false; @@ -140,7 +140,7 @@ define('pgadmin.node.trigger', [ obj = this, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (!d) return false; @@ -653,7 +653,7 @@ define('pgadmin.node.trigger', [ canCreate: SchemaChildTreeNode.isTreeItemOfChildOfSchema, // Check to whether trigger is disable ? canCreate_with_trigger_enable: function(itemData, item, data) { - var treeData = this.getTreeNodeHierarchy(item); + var treeData = pgBrowser.tree.getTreeNodeHierarchy(item); if ('view' in treeData) { return false; } @@ -663,7 +663,7 @@ define('pgadmin.node.trigger', [ }, // Check to whether trigger is enable ? canCreate_with_trigger_disable: function(itemData, item, data) { - var treeData = this.getTreeNodeHierarchy(item); + var treeData = pgBrowser.tree.getTreeNodeHierarchy(item); if ('view' in treeData) { return false; } diff --git a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/mview.js b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/mview.js index abff525b4..a5e31967d 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/mview.js +++ b/web/pgadmin/browser/server_groups/servers/databases/schemas/views/static/js/mview.js @@ -238,7 +238,7 @@ define('pgadmin.node.mview', [ obj = this, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined, + d = i ? t.itemData(i) : undefined, server_data = null; if (!d) @@ -253,7 +253,7 @@ define('pgadmin.node.mview', [ } if (pgBrowser.tree.hasParent(j)) { - j = $(pgBrowser.tree.parent(j)); + j = pgBrowser.tree.parent(j); } else { Alertify.alert(gettext('Please select server or child node from tree.')); break; @@ -316,9 +316,7 @@ define('pgadmin.node.mview', [ is_version_supported: function(data, item) { var t = pgAdmin.Browser.tree, i = item || t.selected(), - d = data || (i && i.length == 1 ? t.itemData(i): undefined), - node = this || (d && pgAdmin.Browser.Nodes[d._type]), - info = node && node.getTreeNodeHierarchy.apply(node, [i]), + info = t && t.getTreeNodeHierarchy(i), version = _.isUndefined(info) ? 0 : info.server.version; // disable refresh concurrently if server version is 9.3 diff --git a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js index 02e2cbdd7..628799eaf 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js +++ b/web/pgadmin/browser/server_groups/servers/databases/static/js/database.js @@ -106,13 +106,13 @@ define('pgadmin.node.database', [ ); }, can_create_database: function(node, item) { - var treeData = this.getTreeNodeHierarchy(item), + var treeData = pgBrowser.tree.getTreeNodeHierarchy(item), server = treeData['server']; return server.connected && server.user.can_create_db; }, canCreate: function(itemData, item) { - var treeData = this.getTreeNodeHierarchy(item), + var treeData = pgBrowser.tree.getTreeNodeHierarchy(item), server = treeData['server']; // If server is less than 10 then do not allow 'create' menu @@ -201,7 +201,7 @@ define('pgadmin.node.database', [ obj = this, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (d && d.label != 'template0') { connect_to_database(obj, d, t, i, true); @@ -214,7 +214,7 @@ define('pgadmin.node.database', [ obj = this, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (d) { Alertify.confirm( @@ -238,7 +238,6 @@ define('pgadmin.node.database', [ data.icon = 'icon-database-not-connected'; t.addIcon(i, {icon: data.icon}); t.unload(i); - t.setInode(i); setTimeout(function() { t.select(prv_i); }, 10); @@ -272,7 +271,7 @@ define('pgadmin.node.database', [ var input = args || {}, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; pgBrowser.erd.showErdTool(d, i, true); }, diff --git a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.js b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.js index 0b684ee42..e05002944 100644 --- a/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.js +++ b/web/pgadmin/browser/server_groups/servers/databases/subscriptions/static/js/subscription.js @@ -158,7 +158,7 @@ define('pgadmin.node.subscription', [ return pgBrowser.DataModel.prototype.sessChanged.apply(this); }, canCreate: function(itemData, item) { - var treeData = this.getTreeNodeHierarchy(item), + var treeData = pgBrowser.tree.getTreeNodeHierarchy(item), server = treeData['server']; // If server is less than 10 then do not allow 'create' menu diff --git a/web/pgadmin/browser/server_groups/servers/pgagent/static/js/pga_job.js b/web/pgadmin/browser/server_groups/servers/pgagent/static/js/pga_job.js index 8d0641855..083a18074 100644 --- a/web/pgadmin/browser/server_groups/servers/pgagent/static/js/pga_job.js +++ b/web/pgadmin/browser/server_groups/servers/pgagent/static/js/pga_job.js @@ -114,7 +114,7 @@ define('pgadmin.node.pga_job', [ obj = this, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (d) { $.ajax({ diff --git a/web/pgadmin/browser/server_groups/servers/resource_groups/static/js/resource_group.js b/web/pgadmin/browser/server_groups/servers/resource_groups/static/js/resource_group.js index bfb32bfec..95a53b03a 100644 --- a/web/pgadmin/browser/server_groups/servers/resource_groups/static/js/resource_group.js +++ b/web/pgadmin/browser/server_groups/servers/resource_groups/static/js/resource_group.js @@ -56,7 +56,7 @@ define('pgadmin.node.resource_group', [ * Resource Group only supported in PPAS 9.4 and above. */ enable: function(node, item) { - var treeData = this.getTreeNodeHierarchy(item), + var treeData = pgBrowser.tree.getTreeNodeHierarchy(item), server = treeData['server']; return server.connected && node.server_type === 'ppas' && node.version >= 90400; diff --git a/web/pgadmin/browser/server_groups/servers/roles/static/js/role.js b/web/pgadmin/browser/server_groups/servers/roles/static/js/role.js index 279371ecc..c18e7c2c1 100644 --- a/web/pgadmin/browser/server_groups/servers/roles/static/js/role.js +++ b/web/pgadmin/browser/server_groups/servers/roles/static/js/role.js @@ -46,7 +46,7 @@ define('pgadmin.node.role', [ hasSQL: true, width: '550px', canDrop: function(node, item) { - var treeData = this.getTreeNodeHierarchy(item), + var treeData = pgBrowser.tree.getTreeNodeHierarchy(item), server = treeData['server']; /* To Drop a role: @@ -114,13 +114,13 @@ define('pgadmin.node.role', [ }]); }, can_create_role: function(node, item) { - var treeData = this.getTreeNodeHierarchy(item), + var treeData = pgBrowser.tree.getTreeNodeHierarchy(item), server = treeData['server']; return server.connected && server.user.can_create_role; }, can_reassign_role: function(node, item) { - var treeData = this.getTreeNodeHierarchy(item), + var treeData = pgBrowser.tree.getTreeNodeHierarchy(item), server = treeData['server']; return server.connected && node.can_login; @@ -444,7 +444,7 @@ define('pgadmin.node.role', [ if (!_d) return; // Create treeInfo - var treeInfo = node.getTreeNodeHierarchy.apply(node, [_i]); + var treeInfo = pgBrowser.tree.getTreeNodeHierarchy(_i); // Instance of backbone model var newModel = new RoleReassignObjectModel({}, {node_info: treeInfo}), fields = Backform.generateViewSchema( diff --git a/web/pgadmin/browser/server_groups/servers/static/js/server.js b/web/pgadmin/browser/server_groups/servers/static/js/server.js index 0111eb286..bd0f5191b 100644 --- a/web/pgadmin/browser/server_groups/servers/static/js/server.js +++ b/web/pgadmin/browser/server_groups/servers/static/js/server.js @@ -227,7 +227,7 @@ define('pgadmin.node.server', [ obj = this, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (d) { connect_to_server(obj, d, t, i, false); @@ -240,7 +240,7 @@ define('pgadmin.node.server', [ obj = this, t = pgBrowser.tree, i = 'item' in input ? input.item : t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (d) { notify = notify || _.isUndefined(notify) || _.isNull(notify); @@ -263,6 +263,7 @@ define('pgadmin.node.server', [ } t.addIcon(i, {icon: d.icon}); obj.callbacks.refresh.apply(obj, [null, i]); + t.close(i); if (pgBrowser.serverInfo && d._id in pgBrowser.serverInfo) { delete pgBrowser.serverInfo[d._id]; } @@ -332,7 +333,7 @@ define('pgadmin.node.server', [ obj = this, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (d) { Alertify.confirm( @@ -368,7 +369,7 @@ define('pgadmin.node.server', [ obj = this, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (!d) return false; @@ -409,7 +410,7 @@ define('pgadmin.node.server', [ obj = this, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined, + d = i ? t.itemData(i) : undefined, url = obj.generate_url(i, 'change_password', d, true), is_pgpass_file_used = false, check_pgpass_url = obj.generate_url(i, 'check_pgpass', d, true); @@ -591,7 +592,7 @@ define('pgadmin.node.server', [ obj = this, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (!d) return false; @@ -626,7 +627,7 @@ define('pgadmin.node.server', [ obj = this, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (!d) return false; @@ -661,7 +662,7 @@ define('pgadmin.node.server', [ obj = this, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (d) { Alertify.confirm( @@ -698,7 +699,7 @@ define('pgadmin.node.server', [ obj = this, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (d) { Alertify.confirm( @@ -733,7 +734,7 @@ define('pgadmin.node.server', [ var input = args || {}, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; pgBrowser.psql.psql_tool(d, i, true); } }, @@ -848,7 +849,7 @@ define('pgadmin.node.server', [ // It should be attempt to reconnect. // Let's not change the status of the tree node now. if (!_wasConnected) { - tree.setInode(_item); + tree.close(_item); if (_data.shared && pgAdmin.server_mode == 'True'){ tree.addIcon(_item, {icon: 'icon-shared-server-not-connected'}); }else{ @@ -922,7 +923,6 @@ define('pgadmin.node.server', [ // We're not reconnecting if (!_wasConnected) { _tree.setInode(_item); - _tree.deselect(_item); setTimeout(function() { _tree.select(_item); diff --git a/web/pgadmin/browser/server_groups/servers/tablespaces/static/js/tablespace.js b/web/pgadmin/browser/server_groups/servers/tablespaces/static/js/tablespace.js index e5c0a8a76..80ff07685 100644 --- a/web/pgadmin/browser/server_groups/servers/tablespaces/static/js/tablespace.js +++ b/web/pgadmin/browser/server_groups/servers/tablespaces/static/js/tablespace.js @@ -84,13 +84,13 @@ define('pgadmin.node.tablespace', [ ]); }, can_create_tablespace: function(node, item) { - var treeData = this.getTreeNodeHierarchy(item), + var treeData = pgBrowser.tree.getTreeNodeHierarchy(item), server = treeData['server']; return server.connected && server.user.is_superuser; }, can_move_objects: function(node, item) { - var treeData = this.getTreeNodeHierarchy(item), + var treeData = pgBrowser.tree.getTreeNodeHierarchy(item), server = treeData['server']; // Only supported PG9.4 and above version return server.connected && @@ -104,7 +104,7 @@ define('pgadmin.node.tablespace', [ obj = this, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined, + d = i ? t.itemData(i) : undefined, url = obj.generate_url(i, 'move_objects', d, true), msql_url = obj.generate_url(i, 'move_objects_sql', d, true); @@ -243,7 +243,7 @@ define('pgadmin.node.tablespace', [ if (!_d) return; // Create treeInfo - var treeInfo = node.getTreeNodeHierarchy.apply(node, [_i]); + var treeInfo = pgAdmin.tree.getTreeNodeHierarchy.apply(node, [_i]); // Instance of backbone model var newModel = new objModel({}, {node_info: treeInfo, selected_ts: _d.label}), fields = Backform.generateViewSchema( diff --git a/web/pgadmin/browser/static/js/browser.js b/web/pgadmin/browser/static/js/browser.js index bdab52993..90398e3a8 100644 --- a/web/pgadmin/browser/static/js/browser.js +++ b/web/pgadmin/browser/static/js/browser.js @@ -8,11 +8,11 @@ ////////////////////////////////////////////////////////////// define('pgadmin.browser', [ - 'sources/tree/tree', 'sources/gettext', 'sources/url_for', 'require', 'jquery', 'underscore', 'bootstrap', 'sources/pgadmin', 'pgadmin.alertifyjs', 'bundled_codemirror', 'sources/check_node_visibility', './toolbar', 'pgadmin.help', 'sources/csrf', 'sources/utils', 'sources/window', 'pgadmin.authenticate.kerberos', + 'sources/tree/tree_init', 'pgadmin.browser.utils', 'wcdocker', 'jquery.contextmenu', 'jquery.aciplugin', 'jquery.acitree', 'pgadmin.browser.preferences', 'pgadmin.browser.messages', @@ -23,11 +23,10 @@ define('pgadmin.browser', [ 'pgadmin.browser.keyboard', 'sources/tree/pgadmin_tree_save_state','jquery.acisortable', 'jquery.acifragment', ], function( - tree, gettext, url_for, require, $, _, Bootstrap, pgAdmin, Alertify, codemirror, checkNodeVisibility, toolBar, help, csrfToken, pgadminUtils, pgWindow, - Kerberos + Kerberos, InitTree, ) { window.jQuery = window.$ = $; // Some scripts do export their object in the window only. @@ -48,7 +47,7 @@ define('pgadmin.browser', [ if (this.isVisible()) { var obj = pgAdmin.Browser, i = obj.tree ? obj.tree.selected() : undefined, - d = i && i.length == 1 ? obj.tree.itemData(i) : undefined; + d = i ? obj.tree.itemData(i) : undefined; if (d && obj.Nodes[d._type].callbacks['selected'] && _.isFunction(obj.Nodes[d._type].callbacks['selected'])) { @@ -58,98 +57,52 @@ define('pgadmin.browser', [ } }; - var processTreeData = function(payload) { - var data = JSON.parse(payload).data; - if (data.length && data[0]._type !== 'column' && - data[0]._type !== 'catalog_object_column') { - data.sort(function(a, b) { - return pgAdmin.natural_sort(a.label, b.label); - }); - } - _.each(data, function(d){ - d._label = d.label; - d.label = _.escape(d.label); - }); - return data; - }; - var initializeBrowserTree = pgAdmin.Browser.initializeBrowserTree = function(b) { - $('#tree').aciTree({ - ajax: { - url: url_for('browser.nodes'), - converters: { - 'text json': processTreeData, + InitTree.initBrowserTree(b).then(() => { + b.tree.registerDraggableType({ + 'collation domain domain_constraints fts_configuration fts_dictionary fts_parser fts_template synonym table partition type sequence package view mview foreign_table edbvar' : (data, item)=>{ + return pgadminUtils.fully_qualify(b, data, item); }, - }, - ajaxHook: function(item, settings) { - if (item != null) { - var d = this.itemData(item); - var n = b.Nodes[d._type]; - if (n) - settings.url = n.generate_url(item, 'children', d, true); - } - }, - loaderDelay: 100, - show: { - duration: 75, - }, - hide: { - duration: 75, - }, - view: { - duration: 75, - }, - animateRoot: true, - unanimated: false, - fullRow: true, - }); + 'schema column database cast event_trigger extension language foreign_data_wrapper foreign_server user_mapping compound_trigger index index_constraint primary_key unique_constraint check_constraint exclusion_constraint foreign_key rule' : (data)=>{ + return pgadminUtils.quote_ident(data._label); + }, + 'trigger trigger_function' : (data)=>{ + return data._label; + }, + 'edbfunc function edbproc procedure' : (data, item)=>{ + let newData = {...data}, + parsedFunc = null, + dropVal = '', + curPos = {from: 0, to: 0}; - b.tree = $('#tree').aciTree('api'); - b.treeMenu.register($('#tree')); + parsedFunc = pgadminUtils.parseFuncParams(newData._label); + newData._label = parsedFunc.func_name; + dropVal = pgadminUtils.fully_qualify(b, newData, item); - b.treeMenu.registerDraggableType({ - 'collation domain domain_constraints fts_configuration fts_dictionary fts_parser fts_template synonym table partition type sequence package view mview foreign_table edbvar' : (data, item)=>{ - return pgadminUtils.fully_qualify(b, data, item); - }, - 'schema column database cast event_trigger extension language foreign_data_wrapper foreign_server user_mapping compound_trigger index index_constraint primary_key unique_constraint check_constraint exclusion_constraint foreign_key rule' : (data)=>{ - return pgadminUtils.quote_ident(data._label); - }, - 'trigger trigger_function' : (data)=>{ - return data._label; - }, - 'edbfunc function edbproc procedure' : (data, item)=>{ - let newData = {...data}, - parsedFunc = null, - dropVal = '', - curPos = {from: 0, to: 0}; + if(parsedFunc.params.length > 0) { + dropVal = dropVal + '('; + curPos.from = dropVal.length; + dropVal = dropVal + parsedFunc.params[0][0]; + curPos.to = dropVal.length; - parsedFunc = pgadminUtils.parseFuncParams(newData._label); - newData._label = parsedFunc.func_name; - dropVal = pgadminUtils.fully_qualify(b, newData, item); + for(let i=1; i 0) { - dropVal = dropVal + '('; - curPos.from = dropVal.length; - dropVal = dropVal + parsedFunc.params[0][0]; - curPos.to = dropVal.length; - - for(let i=1; i {console.warn('Tree Load Error');}); }; // Extend the browser class attributes @@ -164,7 +117,6 @@ define('pgadmin.browser', [ editor:null, // Left hand browser tree tree:null, - treeMenu: new tree.Tree(), // list of script to be loaded, when a certain type of node is loaded // It will be used to register extensions, tools, child node scripts, // etc. @@ -232,8 +184,9 @@ define('pgadmin.browser', [ icon: '', limit: 1, content: '
', - onCreate: function(panel) { + onCreate: function(panel, $container) { toolBar.initializeToolbar(panel, wcDocker); + $container.addClass('pg-no-overflow'); }, }), // Properties of the object node @@ -387,7 +340,7 @@ define('pgadmin.browser', [ // Drop down menu for objects $obj_mnu = navbar.find('li#mnu_obj .dropdown-menu').first(), // data for current selected object - d = obj.tree.itemData(item), + d = item ? obj.tree.itemData(item) : undefined, update_menuitem = function(m) { if (m instanceof pgAdmin.Browser.MenuItem) { m.update(d, item); @@ -473,6 +426,8 @@ define('pgadmin.browser', [ }); } + initializeBrowserTree(obj); + // Syntax highlight the SQL Pane obj.editor = CodeMirror.fromTextArea( document.getElementById('sql-textarea'), { @@ -503,12 +458,9 @@ define('pgadmin.browser', [ obj.editor.refresh(); }, 10); - // Initialise the treeview - initializeBrowserTree(obj); - // Build the treeview context menu $('#tree').contextMenu({ - selector: '.aciTreeLine', + selector: '.file-entry', autoHide: false, build: function(element) { var item = obj.tree.itemFrom(element), @@ -534,47 +486,6 @@ define('pgadmin.browser', [ }, }); - // Treeview event handler - $('#tree').on('acitree', function(event, api, item, eventName, options) { - var d = item ? obj.tree.itemData(item) : null; - var node; - - if (d && obj.Nodes[d._type]) { - node = obj.Nodes[d._type]; - - /* If the node specific callback returns false, we will also return - * false for further processing. - */ - if (_.isObject(node.callbacks) && - eventName in node.callbacks && - typeof node.callbacks[eventName] == 'function' && - !node.callbacks[eventName].apply( - node, [item, d, obj, options, eventName])) { - return false; - } - /* Raise tree events for the nodes */ - try { - node.trigger( - 'browser-node.' + eventName, node, item, d - ); - } catch (e) { - console.warn(e.stack || e); - } - } - - try { - obj.Events.trigger( - 'pgadmin-browser:tree', eventName, item, d - ); - obj.Events.trigger( - 'pgadmin-browser:tree:' + eventName, item, d, node - ); - } catch (e) { - console.warn(e.stack || e); - } - return true; - }); - // Register scripts and add menus pgBrowser.utils.registerScripts(this); pgBrowser.utils.addMenus(obj); @@ -597,7 +508,7 @@ define('pgadmin.browser', [ obj.check_corrupted_db_file(); obj.Events.on('pgadmin:browser:tree:add', obj.onAddTreeNode, obj); obj.Events.on('pgadmin:browser:tree:update', obj.onUpdateTreeNode, obj); - obj.Events.on('pgadmin:browser:tree:refresh', obj.onRefreshTreeNode, obj); + obj.Events.on('pgadmin:browser:tree:refresh', obj.onRefreshTreeNodeReact, obj); obj.Events.on('pgadmin-browser:tree:loadfail', obj.onLoadFailNode, obj); obj.bind_beforeunload(); @@ -937,7 +848,7 @@ define('pgadmin.browser', [ showHelp: function(type, url, node, item) { if (type == 'object_help') { // Construct the URL - var server = node.getTreeNodeHierarchy(item).server; + var server = pgBrowser.tree.getTreeNodeHierarchy(item).server; var baseUrl = pgBrowser.utils.pg_help_path; if (server.server_type == 'ppas') { baseUrl = pgBrowser.utils.edbas_help_path; @@ -962,7 +873,7 @@ define('pgadmin.browser', [ var items = _o.t.children(_i), i, d, n, idx = 0, size = items.length; for (; idx < size; idx++) { - i = items.eq(idx); + i = items[idx]; d = _o.t.itemData(i); if (d._type === _d._type) { if (!_o.hasId || d._id == _d._id) { @@ -998,19 +909,17 @@ define('pgadmin.browser', [ }; if (!loaded && _o.load) { - _o.t.open(_i, { - success: onLoad, - unanimated: true, - fail: function() { + _o.t.open(_i).then( + () => { + onLoad(); + }, + () => { var fail = _o && _o.o && _o.o.fail; - - if ( - fail && typeof(fail) == 'function' - ) { + if (fail && typeof(fail) == 'function') { fail.apply(_o.t, []); } - }, - }); + } + ); } else if (loaded) { onLoad(); } else { @@ -1089,7 +998,7 @@ define('pgadmin.browser', [ s = 0, e = items.length - 1, i, linearSearch = function() { while (e >= s) { - i = items.eq(s); + i = items[s]; var d = __ctx.t.itemData(i); if (d._type === 'column') { if (pgAdmin.numeric_comparator(d._id, _data._id) == 1) @@ -1102,7 +1011,7 @@ define('pgadmin.browser', [ } //when the current element is greater than the end element if (e != items.length - 1) { - i = items.eq(e+1); + i = items[e+1]; return true; } i = null; @@ -1116,7 +1025,7 @@ define('pgadmin.browser', [ // // We will try until it's half. while (e - s > 22) { - i = items.eq(s); + i = items[s]; d = __ctx.t.itemData(i); if (d._type === 'column') { if (pgAdmin.numeric_comparator(d._id, _data._id) != -1) @@ -1125,7 +1034,7 @@ define('pgadmin.browser', [ if (pgAdmin.natural_sort(d._label, _data._label) != -1) return true; } - i = items.eq(e); + i = items[e]; d = __ctx.t.itemData(i); let result; if (d._type === 'column') { @@ -1135,14 +1044,14 @@ define('pgadmin.browser', [ } if (result !=1) { if (e != items.length - 1) { - i = items.eq(e+1); + i = items[e+1]; return true; } i = null; return false; } m = s + Math.round((e - s) / 2); - i = items.eq(m); + i = items[m]; d = __ctx.t.itemData(i); if(d._type === 'column'){ result = pgAdmin.numeric_comparator(d._id, _data._id); @@ -1190,10 +1099,8 @@ define('pgadmin.browser', [ is_parent_loaded_before = ___ctx.t.wasLoad(___ctx.i), _parent_data = ___ctx.t.itemData(___ctx.i); - ___ctx.t.append(___ctx.i, { - itemData: _data, - success: function(item, options) { - var _i = $(options.items[0]); + ___ctx.t.append(___ctx.i, _data).then( + (_i) => { // Open the item path only if its parent is loaded // or parent type is same as nodes if( @@ -1202,18 +1109,17 @@ define('pgadmin.browser', [ _data._type ) > -1 ) { - ___ctx.t.openPath(_i); + ___ctx.t.open(___ctx.i); ___ctx.t.select(_i); } else { if (_parent_data) { // Unload the parent node so that we'll get // latest data when we try to expand it - ___ctx.t.unload(___ctx.i, { - success: function (_item) { - // Lets try to load it now - ___ctx.t.open(_item); - }, - }); + ___ctx.t.unload(___ctx.i).then( + () => { + ___ctx.t.open(___ctx.i); + } + ); } } if ( @@ -1223,7 +1129,7 @@ define('pgadmin.browser', [ ___ctx.o.success.apply(___ctx.t, [_i, _data]); } }, - fail: function() { + () => { console.warn('Failed to append...', arguments); if ( ___ctx.o && ___ctx.o.fail && @@ -1231,12 +1137,16 @@ define('pgadmin.browser', [ ) { ___ctx.o.fail.apply(___ctx.t, [___ctx.i, _data]); } - }, - }); + } + ); }.bind(__ctx); if (__ctx.i && !__ctx.t.isInode(__ctx.i)) { - __ctx.t.setInode(__ctx.i, {success: _append}); + __ctx.t.setInode(__ctx.i).then( + () => { + _append(); + } + ); } else { // Handle case for node without parent i.e. server-group // or if parent node's inode is true. @@ -1247,28 +1157,26 @@ define('pgadmin.browser', [ // Parent node do not have any children, let me unload it. if (!first && _ctx.t.wasLoad(_ctx.i)) { - _ctx.t.unload(_ctx.i, { - success: function() { - findChildNode( - selectNode, - function() { - var o = this && this.o; - if ( - o && o.fail && typeof(o.fail) == 'function' - ) { - o.fail.apply(this.t, [this.i, _data]); - } - }.bind(this) - ); - }.bind(this), - fail: function() { - var o = this && this.o; - if ( - o && o.fail && typeof(o.fail) == 'function' - ) { - o.fail.apply(this.t, [this.i, _data]); - } - }.bind(this), + _ctx.t.unload(_ctx.i).then(() => { + findChildNode( + selectNode, + function() { + var o = this && this.o; + if ( + o && o.fail && typeof(o.fail) == 'function' + ) { + o.fail.apply(this.t, [this.i, _data]); + } + }.bind(this) + ); + }, + () => { + var o = this && this.o; + if ( + o && o.fail && typeof(o.fail) == 'function' + ) { + o.fail.apply(this.t, [this.i, _data]); + } }); return; } @@ -1342,7 +1250,8 @@ define('pgadmin.browser', [ && this.t.parent(this.i)) || null, _item_grand_parent = _item_parent ? (this.t.hasParent(_item_parent) - && this.t.parent(_item_parent)) + && this.t.parent(_item_parent) && + _item_parent.root != this.t.parent(_item_parent)) : null; // Remove the current node first. @@ -1358,13 +1267,13 @@ define('pgadmin.browser', [ } else { var postRemove = function() { // If item has parent but no grand parent - if (_item_parent && !_item_grand_parent) { + if (_item_parent.path !== '/browser' && !_item_grand_parent) { var parent = null; // We need to search in all parent siblings (eg: server groups) var parents = this.t.siblings(this.i) || []; - parents.push(this.i[0]); + parents.push(this.i); _.each(parents, function (p) { - var d = self.t.itemData($(p)); + var d = self.t.itemData(p); // If new server group found then assign it parent if(d._id == self.new._pid) { parent = p; @@ -1383,7 +1292,6 @@ define('pgadmin.browser', [ this.notFound = errorOut; // var _d = {_id: this.new._pid, _type: self.d._type}; - parent = $(parent); var loaded = this.t.wasLoad(parent), onLoad = function() { self.i = parent; @@ -1393,19 +1301,19 @@ define('pgadmin.browser', [ }; if (!loaded && self.load) { - self.t.open(parent, { - success: onLoad, - unanimated: true, - fail: function() { + self.t.open(parent).then( + () => { + onLoad(); + }, + () => { var fail = self && self.o && self.o.fail; - if ( fail && typeof(fail) == 'function' ) { fail.apply(self.t, []); } - }, - }); + } + ); } else { onLoad(); } @@ -1438,30 +1346,17 @@ define('pgadmin.browser', [ } }.bind(this); - // If there is a parent then we can remove the node - this.t.remove(this.i, { - success: function() { - // Find the parent - findParent(); - // If server group have no children then close it and set inode - // and unload it so it can fetch new data on next expand - if (_item_parent && !_item_grand_parent && _parent + this.t.remove(this.i).then(() => { + findParent(); + if (_item_parent && !_item_grand_parent && _parent && self.t.children(_parent).length == 0) { - self.t.setInode(_parent, { - success: function() { - self.t.unload(_parent, {success: function() { - setTimeout(postRemove); - }} - ); - }, - }); - } else { - setTimeout(postRemove); - } - return true; - }, - } - ); + self.t.unload(_parent).then( () => { setTimeout(postRemove); }); + } + else { + setTimeout(postRemove); + } + return true; + }); } } @@ -1605,7 +1500,7 @@ define('pgadmin.browser', [ s = 0, e = items.length - 1, i, linearSearch = function() { while (e >= s) { - i = items.eq(s); + i = items[s]; var d = __ctx.t.itemData(i); if (d._type === 'column') { if (pgAdmin.numeric_comparator(d._id, _new._id) == 1) @@ -1617,7 +1512,7 @@ define('pgadmin.browser', [ s++; } if (e != items.length - 1) { - i = items.eq(e+1); + i = items[e+1]; return true; } i = null; @@ -1625,7 +1520,7 @@ define('pgadmin.browser', [ }, binarySearch = function() { while (e - s > 22) { - i = items.eq(s); + i = items[s]; var d = __ctx.t.itemData(i); if (d._type === 'column') { if (pgAdmin.numeric_comparator(d._id, _new._id) != -1) @@ -1634,7 +1529,7 @@ define('pgadmin.browser', [ if (pgAdmin.natural_sort(d._label, _new._label) != -1) return true; } - i = items.eq(e); + i = items[e]; d = __ctx.t.itemData(i); let result; if (d._type === 'column') { @@ -1644,14 +1539,14 @@ define('pgadmin.browser', [ } if (result !=1) { if (e != items.length - 1) { - i = items.eq(e+1); + i = items[e+1]; return true; } i = null; return false; } var m = s + Math.round((e - s) / 2); - i = items.eq(m); + i = items[m]; d = __ctx.t.itemData(i); if(d._type === 'column'){ result = pgAdmin.numeric_comparator(d._id, _new._id); @@ -1698,9 +1593,8 @@ define('pgadmin.browser', [ }); } else { var _appendNode = function() { - __ctx.t.append(__ctx.i, { - itemData: _new, - success: function() { + __ctx.t.append(__ctx.i, _new).then( + () => { var new_item = $(arguments[1].items[0]); __ctx.t.openPath(new_item); __ctx.t.select(new_item); @@ -1710,7 +1604,7 @@ define('pgadmin.browser', [ __ctx.o.success.apply(__ctx.t, [__ctx.i, _old, _new]); } }, - fail: function() { + () => { console.warn('Failed to append...', arguments); if ( __ctx.o && __ctx.o.fail && typeof(__ctx.o.fail) == 'function' @@ -1718,7 +1612,7 @@ define('pgadmin.browser', [ __ctx.o.fail.apply(__ctx.t, [__ctx.i, _old, _new]); } }, - }); + ); }; // If the current node's inode is false @@ -1735,29 +1629,28 @@ define('pgadmin.browser', [ // Parent node do not have any children, let me unload it. if (!first && _ctx.t.wasLoad(_ctx.i)) { - _ctx.t.unload(_ctx.i, { - success: function() { - findChildNode( - selectNode, - function() { - var o = this && this.o; - if ( - o && o.fail && typeof(o.fail) == 'function' - ) { - o.fail.apply(this.t, [this.i, _old, _new]); - } - }.bind(this) - ); - }.bind(this), - fail: function() { - var o = this && this.o; - if ( - o && o.fail && typeof(o.fail) == 'function' - ) { - o.fail.apply(this.t, [this.i, _old, _new]); + _ctx.t.unload(_ctx.i).then( () => { + findChildNode( + selectNode, + function() { + var o = this && this.o; + if ( + o && o.fail && typeof(o.fail) == 'function' + ) { + o.fail.apply(this.t, [this.i, _old, _new]); + } } - }.bind(this), - }); + ); + }, + () => { + var o = this && this.o; + if ( + o && o.fail && typeof(o.fail) == 'function' + ) { + o.fail.apply(this.t, [this.i, _old, _new]); + } + } + ); return; } @@ -1799,6 +1692,11 @@ define('pgadmin.browser', [ } }, + onRefreshTreeNodeReact: function(_i) { + this.tree.refresh(_i); + return; + }, + onRefreshTreeNode: function(_i, _opts) { var _d = _i && this.tree.itemData(_i), n = _d && _d._type && this.Nodes[_d._type], @@ -2034,10 +1932,10 @@ define('pgadmin.browser', [ if (_selectNext) { nodeToSelect = tree_local.next(_node); - if (!nodeToSelect || !nodeToSelect.length) { + if (!nodeToSelect) { nodeToSelect = tree_local.prev(_node); - if (!nodeToSelect || !nodeToSelect.length) { + if (!nodeToSelect) { if (!_parentNode) { nodeToSelect = tree_local.parent(_node); } else { @@ -2048,6 +1946,7 @@ define('pgadmin.browser', [ if (nodeToSelect) tree_local.select(nodeToSelect); } + tree_local.remove(_node); return true; }, diff --git a/web/pgadmin/browser/static/js/collection.js b/web/pgadmin/browser/static/js/collection.js index 812b93b64..39c2e772f 100644 --- a/web/pgadmin/browser/static/js/collection.js +++ b/web/pgadmin/browser/static/js/collection.js @@ -99,7 +99,7 @@ define([ $msgContainer = '', // This will be the URL, used for object manipulation. urlBase = this.generate_url(item, 'properties', data), - info = this.getTreeNodeHierarchy.apply(this, [item]), + info = pgBrowser.tree.getTreeNodeHierarchy(item), gridSchema = Backform.generateGridColumnsFromModel( info, node.model, 'properties', that.columns ), @@ -496,7 +496,7 @@ define([ var collectionPickFunction = function (treeInfoValue, treeInfoKey) { return (treeInfoKey != self.type); }; - var treeInfo = this.getTreeNodeHierarchy(item); + var treeInfo = pgBrowser.tree.getTreeNodeHierarchy(item); var actionType = type in opURL ? opURL[type] : type; return generateUrl.generate_url( pgAdmin.Browser.URL, treeInfo, actionType, self.node, @@ -517,7 +517,7 @@ define([ var input = args || {}, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; pgBrowser.psql.psql_tool(d, i, true); }, }); diff --git a/web/pgadmin/browser/static/js/keyboard.js b/web/pgadmin/browser/static/js/keyboard.js index a69c7009f..7040b5e25 100644 --- a/web/pgadmin/browser/static/js/keyboard.js +++ b/web/pgadmin/browser/static/js/keyboard.js @@ -244,7 +244,7 @@ _.extend(pgBrowser.keyboardNavigation, { const tree = this.getTreeDetails(); $('#tree').trigger('focus'); - tree.t.focus(tree.i); + // tree.t.focus(tree.i); tree.t.select(tree.i); }, bindSubMenuQueryTool: function() { @@ -370,8 +370,8 @@ _.extend(pgBrowser.keyboardNavigation, { }, getTreeDetails: function() { const aciTree = pgAdmin.Browser.tree; - const selectedTreeNode = aciTree.selected().length > 0 ? aciTree.selected() : aciTree.first(); - const selectedTreeNodeData = selectedTreeNode && selectedTreeNode.length === 1 ? aciTree.itemData(selectedTreeNode) : undefined; + const selectedTreeNode = aciTree.selected() ? aciTree.selected() : aciTree.first(); + const selectedTreeNodeData = selectedTreeNode ? aciTree.itemData(selectedTreeNode) : undefined; return { t: aciTree, diff --git a/web/pgadmin/browser/static/js/layout.js b/web/pgadmin/browser/static/js/layout.js index 54046bf2b..5f3138675 100644 --- a/web/pgadmin/browser/static/js/layout.js +++ b/web/pgadmin/browser/static/js/layout.js @@ -89,7 +89,7 @@ _.extend(pgBrowser, { browser.reflectLocklayoutChange(docker); }); } - }, 500); + }, 5000); }, reflectLocklayoutChange: function(docker) { diff --git a/web/pgadmin/browser/static/js/node.js b/web/pgadmin/browser/static/js/node.js index d1626c8f2..f886802bd 100644 --- a/web/pgadmin/browser/static/js/node.js +++ b/web/pgadmin/browser/static/js/node.js @@ -10,13 +10,13 @@ import {getNodeView, removeNodeView} from './node_view'; define('pgadmin.browser.node', [ - 'sources/tree/pgadmin_tree_node', 'sources/url_for', + 'sources/url_for', 'sources/gettext', 'jquery', 'underscore', 'sources/pgadmin', 'pgadmin.browser.menu', 'backbone', 'pgadmin.alertifyjs', 'pgadmin.browser.datamodel', 'backform', 'sources/browser/generate_url', 'pgadmin.help', 'sources/utils', 'pgadmin.browser.utils', 'pgadmin.backform', ], function( - pgadminTreeNode, url_for, + url_for, gettext, $, _, pgAdmin, Menu, Backbone, Alertify, pgBrowser, Backform, generateUrl, help, @@ -269,8 +269,7 @@ define('pgadmin.browser.node', [ if (itemData._type == 'database' && !itemData.allowConn) return false; - var node = pgBrowser.Nodes[itemData._type], - parentData = node.getTreeNodeHierarchy(item); + var parentData = pgBrowser.tree.getTreeNodeHierarchy(item); if (_.indexOf(['create', 'insert', 'update', 'delete'], data.script) != -1) { if (itemData.type == 'role' && parentData.server.user.can_create_role) { @@ -325,7 +324,7 @@ define('pgadmin.browser.node', [ } // We know - which data model to be used for this object. - var info = this.getTreeNodeHierarchy.apply(this, [item]), + var info = pgBrowser.tree.getTreeNodeHierarchy(item), newModel = new(this.model.extend({ urlRoot: urlBase, }))( @@ -450,7 +449,7 @@ define('pgadmin.browser.node', [ }, error: function(model, xhr, options) { var _label = that && item ? - that.getTreeNodeHierarchy( + pgBrowser.tree.getTreeNodeHierarchy( item )[that.type].label : ''; pgBrowser.Events.trigger( @@ -594,7 +593,7 @@ define('pgadmin.browser.node', [ show_obj_properties: function(args, item) { var t = pgBrowser.tree, i = (args && args.item) || item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined, + d = i ? t.itemData(i) : undefined, o = this, l = o.title.apply(this, [d]); @@ -786,7 +785,7 @@ define('pgadmin.browser.node', [ obj = this, t = pgBrowser.tree, i = input.item || item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (!d) return; @@ -882,7 +881,7 @@ define('pgadmin.browser.node', [ obj, t = pgBrowser.tree, i = item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (!d) return; @@ -920,7 +919,7 @@ define('pgadmin.browser.node', [ var preference = pgBrowser.get_preference('sqleditor', 'copy_sql_to_query_tool'); var t = pgBrowser.tree, i = item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; if (!d) return; @@ -944,7 +943,7 @@ define('pgadmin.browser.node', [ var input = args || {}, t = pgBrowser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; pgBrowser.psql.psql_tool(d, i, true); }, @@ -988,32 +987,7 @@ define('pgadmin.browser.node', [ } } }, - added: function(item, data, browser) { - var b = browser || pgBrowser, - t = b.tree, - pItem = t.parent(item), - pData = pItem && t.itemData(pItem), - pNode = pData && pgBrowser.Nodes[pData._type]; - - // Check node is a collection or not. - if (pNode && pNode.is_collection) { - /* If 'collection_count' is not present in data - * it means tree node expanded first time, so we will - * kept collection count and label in data itself. - */ - if (!('collection_count' in pData)) { - pData.collection_count = 0; - } - pData.collection_count++; - t.setLabel( - pItem, { - label: ( - _.escape(pData._label) + ' (' + pData.collection_count + ')' - ), - } - ); - } - + added: function(item, data) { pgBrowser.Events.trigger('pgadmin:browser:tree:expand-from-previous-tree-state', item); pgBrowser.Node.callbacks.change_server_background(item, data); @@ -1050,43 +1024,11 @@ define('pgadmin.browser.node', [ return true; }, removed: function(item) { - var self = this, - t = pgBrowser.tree, - pItem = t.parent(item), - pData = pItem && t.itemData(pItem), - pNode = pData && pgBrowser.Nodes[pData._type]; - - // Check node is a collection or not. - if ( - pNode && pNode.is_collection && 'collection_count' in pData - ) { - pData.collection_count--; - t.setLabel( - pItem, { - label: ( - _.escape(pData._label) + ' (' + pData.collection_count + ')' - ), - } - ); - } - + var self = this; setTimeout(function() { self.clear_cache.apply(self, item); }, 0); }, - unloaded: function(item) { - var self = this, - t = pgBrowser.tree, - data = item && t.itemData(item); - - // In case of unload remove the collection counter - if (self.is_collection && data === Object(data) &&'collection_count' in data) { - delete data.collection_count; - t.setLabel(item, { - label: _.escape(data._label), - }); - } - }, refresh: function(cmd, _item) { var self = this, t = pgBrowser.tree, @@ -1232,8 +1174,7 @@ define('pgadmin.browser.node', [ // Avoid unnecessary reloads var i = tree.selected(), d = i && tree.itemData(i), - n = i && d && pgBrowser.Nodes[d._type], - treeHierarchy = n.getTreeNodeHierarchy(i); + treeHierarchy = tree.getTreeNodeHierarchy(i); if (_.isEqual($(this).data('node-prop'), treeHierarchy)) { return; @@ -1246,7 +1187,7 @@ define('pgadmin.browser.node', [ removeNodeView(j[0]); /* getSchema is a schema for React. Get the react node view */ if(that.getSchema) { - let treeNodeInfo = that.getTreeNodeHierarchy.apply(this, [item]); + let treeNodeInfo = pgBrowser.tree.getTreeNodeHierarchy(item); getNodeView( that.type, treeNodeInfo, 'properties', data, 'tab', j[0], this, onEdit ); @@ -1323,7 +1264,7 @@ define('pgadmin.browser.node', [ }.bind(panel), onSqlHelp = function() { // Construct the URL - var server = that.getTreeNodeHierarchy(item).server; + var server = pgBrowser.tree.getTreeNodeHierarchy(item).server; var url = pgBrowser.utils.pg_help_path; if (server.server_type == 'ppas') { @@ -1507,7 +1448,7 @@ define('pgadmin.browser.node', [ removeNodeView(j[0]); /* getSchema is a schema for React. Get the react node view */ if(that.getSchema) { - let treeNodeInfo = that.getTreeNodeHierarchy.apply(this, [item]); + let treeNodeInfo = pgBrowser.tree.getTreeNodeHierarchy(item); getNodeView( that.type, treeNodeInfo, action, data, 'dialog', j[0], this, onEdit, (nodeData)=>{ @@ -1884,7 +1825,7 @@ define('pgadmin.browser.node', [ self = this, priority = -Infinity; var treeInfo = (_.isUndefined(item) || _.isNull(item)) ? - info || {} : this.getTreeNodeHierarchy(item); + info || {} : pgBrowser.tree.getTreeNodeHierarchy(item); var actionType = type in opURL ? opURL[type] : type; var itemID = with_id && d._type == self.type ? encodeURIComponent(d._id) : ''; @@ -1921,7 +1862,6 @@ define('pgadmin.browser.node', [ Collection: pgBrowser.DataCollection, // Base class for Node Data Model Model: pgBrowser.DataModel, - getTreeNodeHierarchy: pgadminTreeNode.getTreeNodeHierarchyFromIdentifier.bind(pgBrowser), cache: function(url, node_info, level, data) { var cached = this.cached = this.cached || {}, hash = url, @@ -1938,7 +1878,7 @@ define('pgadmin.browser.node', [ )), function(o) { return o.priority; }), function(o) { - hash = commonUtils.sprintf('%s/%s', hash, encodeURI(o._id)); + hash = commonUtils.sprintf('%s_%s', hash, encodeURI(o._id)); }); } diff --git a/web/pgadmin/browser/static/js/preferences.js b/web/pgadmin/browser/static/js/preferences.js index c5eafacd2..98b006fc5 100644 --- a/web/pgadmin/browser/static/js/preferences.js +++ b/web/pgadmin/browser/static/js/preferences.js @@ -14,7 +14,7 @@ import * as Alertify from 'pgadmin.alertifyjs'; import * as SqlEditorUtils from 'sources/sqleditor_utils'; import pgWindow from 'sources/window'; -var modifyAnimation = require('sources/modify_animation'); +//var modifyAnimation = require('sources/modify_animation'); const pgBrowser = pgAdmin.Browser = pgAdmin.Browser || {}; @@ -91,10 +91,10 @@ _.extend(pgBrowser, { self.preference_version(self.generate_preference_version()); pgBrowser.keyboardNavigation.init(); - if(pgBrowser.tree) { - modifyAnimation.modifyAcitreeAnimation(self); - modifyAnimation.modifyAlertifyAnimation(self); - } + // if(pgBrowser.tree) { + // modifyAnimation.modifyAcitreeAnimation(self); + // modifyAnimation.modifyAlertifyAnimation(self); + // } // Initialize Tree saving/reloading pgBrowser.browserTreeState.init(); diff --git a/web/pgadmin/browser/static/js/toolbar.js b/web/pgadmin/browser/static/js/toolbar.js index bc9c13a3d..9920cd629 100644 --- a/web/pgadmin/browser/static/js/toolbar.js +++ b/web/pgadmin/browser/static/js/toolbar.js @@ -123,7 +123,7 @@ export function initializeToolbar(panel, wcDocker) { var input = {}, t = pgAdmin.Browser.tree, i = input.item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; pgAdmin.Browser.psql.psql_tool(d, i, true); } }); diff --git a/web/pgadmin/dashboard/static/js/dashboard.js b/web/pgadmin/dashboard/static/js/dashboard.js index 529ba3b5f..6e6228304 100644 --- a/web/pgadmin/dashboard/static/js/dashboard.js +++ b/web/pgadmin/dashboard/static/js/dashboard.js @@ -272,16 +272,16 @@ define('pgadmin.dashboard', [ // The server connected may not be the same one, which was selected, and // we do care out the current selected one only. if (item.length != 0) { - this.object_selected(item, itemData, pgBrowser.Nodes[itemData._type]); + this.object_selected(item, itemData); } }, // Handle treeview clicks - object_selected: function(item, itemData, node) { + object_selected: function(item, itemData) { let self = this; if (itemData && itemData._type) { - var treeHierarchy = node.getTreeNodeHierarchy(item), + var treeHierarchy = pgBrowser.tree.getTreeNodeHierarchy(item), url = NodesDashboard.url(itemData, item, treeHierarchy); if (url === null) { @@ -1142,11 +1142,10 @@ define('pgadmin.dashboard', [ } else { var t = pgBrowser.tree, i = t.selected(), - d = i && t.itemData(i), - n = i && d && pgBrowser.Nodes[d._type]; + d = i && t.itemData(i); this.chartsDomObj && this.chartsDomObj.setPageVisible(dashboardVisible); - this.object_selected(i, d, n); + this.object_selected(i, d); } }, can_take_action: function(m) { diff --git a/web/pgadmin/misc/dependencies/static/js/dependencies.js b/web/pgadmin/misc/dependencies/static/js/dependencies.js index 67377c9a5..2098b035f 100644 --- a/web/pgadmin/misc/dependencies/static/js/dependencies.js +++ b/web/pgadmin/misc/dependencies/static/js/dependencies.js @@ -168,7 +168,7 @@ define('misc.dependencies', [ $container = panel.layout().scene().find('.pg-panel-content'), $msgContainer = $container.find('.pg-panel-depends-message'), $gridContainer = $container.find('.pg-panel-dependencies-container'), - treeHierarchy = node.getTreeNodeHierarchy(item); + treeHierarchy = pgBrowser.tree.getTreeNodeHierarchy(item); if (node) { /* We fetch the Dependencies and Dependencies tab only for @@ -294,6 +294,128 @@ define('misc.dependencies', [ } } }, + showReactDependencies: function(item, data, node) { + let self = this, + msg = gettext('Please select an object in the tree view.'), + panel = this.dependenciesPanel, + $container = panel.layout().scene().find('.pg-panel-content'), + $msgContainer = $container.find('.pg-panel-depends-message'), + $gridContainer = $container.find('.pg-panel-dependencies-container'), + treeHierarchy = pgBrowser.tree.getTreeNodeHierarchy(item), + n_type = data._type, + url = node.generate_url_react(item, 'dependency'); + + if (node) { + /* We fetch the Dependencies and Dependencies tab only for + * those node who set the parameter hasDepends to true. + */ + msg = gettext('No dependency information is available for the selected object.'); + if (node.hasDepends) { + /* Updating the label for the 'field' type of the backbone model. + * Label should be "Database" if the node type is tablespace or role + * and dependencies tab is selected. For other nodes and dependencies tab + * it should be 'Restriction'. + */ + + this.dependenciesGrid.columns.models[2].set({ + 'label': gettext('Restriction'), + }); + + // Hide message container and show grid container. + $msgContainer.addClass('d-none'); + $gridContainer.removeClass('d-none'); + + var timer = ''; + $.ajax({ + url: url, + type: 'GET', + beforeSend: function(xhr) { + xhr.setRequestHeader(pgAdmin.csrf_token_header, pgAdmin.csrf_token); + // Generate a timer for the request + timer = setTimeout(function() { + // notify user if request is taking longer than 1 second + + $msgContainer.text(gettext('Fetching dependency information from the server...')); + $msgContainer.removeClass('d-none'); + msg = ''; + + }, 1000); + }, + }) + .done(function(res) { + clearTimeout(timer); + + if (res.length > 0) { + + if (!$msgContainer.hasClass('d-none')) { + $msgContainer.addClass('d-none'); + } + $gridContainer.removeClass('d-none'); + + self.dependenciesData = res; + + // Load only 100 rows + self.dependenciesCollection.reset(self.dependenciesData.splice(0, 100), {parse: true}); + + // Load more rows on scroll down + pgBrowser.Events.on( + 'pgadmin-browser:panel-dependencies:' + + wcDocker.EVENT.SCROLLED, + self.__loadMoreRows + ); + + } else { + // Do not listen the scroll event + pgBrowser.Events.off( + 'pgadmin-browser:panel-dependencies:' + + wcDocker.EVENT.SCROLLED + ); + + self.dependenciesCollection.reset({silent: true}); + $msgContainer.text(msg); + $msgContainer.removeClass('d-none'); + + if (!$gridContainer.hasClass('d-none')) { + $gridContainer.addClass('d-none'); + } + } + + + }) + .fail(function(xhr, error, message) { + var _label = treeHierarchy[n_type].label; + pgBrowser.Events.trigger( + 'pgadmin:node:retrieval:error', 'depends', xhr, error, message + ); + if (!Alertify.pgHandleItemError(xhr, error, message, { + item: item, + info: treeHierarchy, + })) { + Alertify.pgNotifier( + error, xhr, + gettext('Error retrieving data from the server: %s', message || _label), + function(alertMsg) { + if(alertMsg === 'CRYPTKEY_SET') { + self.showDependencies(item, data, node); + } else { + console.warn(arguments); + } + }); + } + // show failed message. + $msgContainer.text(gettext('Failed to retrieve data from the server.')); + }); + } + } + if (msg != '') { + $msgContainer.text(msg); + $msgContainer.removeClass('d-none'); + if (!$gridContainer.hasClass('d-none')) { + $gridContainer.addClass('d-none'); + } + } + }, + __loadMoreRows: function() { if (this.dependenciesPanel.length < 1) return ; diff --git a/web/pgadmin/misc/dependents/static/js/dependents.js b/web/pgadmin/misc/dependents/static/js/dependents.js index 6564979d7..370de8682 100644 --- a/web/pgadmin/misc/dependents/static/js/dependents.js +++ b/web/pgadmin/misc/dependents/static/js/dependents.js @@ -71,7 +71,7 @@ define('misc.dependents', [ if (visible) { this.dependentsPanel = pgBrowser.docker.findPanels('dependents')[0]; var t = pgBrowser.tree, - i = t.selected(), + i = t && t.selected(), d = i && t.itemData(i), n = i && d && pgBrowser.Nodes[d._type]; @@ -168,7 +168,7 @@ define('misc.dependents', [ $container = panel.layout().scene().find('.pg-panel-content'), $msgContainer = $container.find('.pg-panel-depends-message'), $gridContainer = $container.find('.pg-panel-dependents-container'), - treeHierarchy = node.getTreeNodeHierarchy(item); + treeHierarchy = pgBrowser.tree.getTreeNodeHierarchy(item); if (node) { /* We fetch the Dependencies and Dependents tab only for diff --git a/web/pgadmin/misc/sql/static/js/sql.js b/web/pgadmin/misc/sql/static/js/sql.js index 4abd054fa..c1722bee6 100644 --- a/web/pgadmin/misc/sql/static/js/sql.js +++ b/web/pgadmin/misc/sql/static/js/sql.js @@ -57,6 +57,9 @@ define('misc.sql', [ pgBrowser.Events.on( 'pgadmin-browser:tree:selected', this.showSQL ); + pgBrowser.Events.on( + 'pgadmin-browser:tree:reactSelected', this.reactShowSQL + ); pgBrowser.Events.on( 'pgadmin-browser:tree:refreshing', this.refreshSQL, this ); @@ -66,6 +69,7 @@ define('misc.sql', [ } else { if ((sqlPanels[0].isVisible()) || sqlPanels.length != 1) { pgBrowser.Events.on('pgadmin-browser:tree:selected', this.showSQL); + pgBrowser.Events.on('pgadmin-browser:tree:reactSelected', this.reactShowSQL); pgBrowser.Events.on( 'pgadmin-browser:tree:refreshing', this.refreshSQL, this ); @@ -92,6 +96,7 @@ define('misc.sql', [ * through. We will wait for some time before fetching the Reversed * Engineering SQL. **/ + this.timeout && clearTimeout(this.timeout); var that = this; @@ -102,7 +107,7 @@ define('misc.sql', [ sql = '-- ' + gettext('No SQL could be generated for the selected object.'); var n_type = data._type, url = node.generate_url(item, 'sql', data, true), - treeHierarchy = node.getTreeNodeHierarchy(item), + treeHierarchy = pgBrowser.tree.getTreeNodeHierarchy(item), cache_flag = { node_type: n_type, url: url, diff --git a/web/pgadmin/misc/statistics/static/js/statistics.js b/web/pgadmin/misc/statistics/static/js/statistics.js index f0dbc6a3b..6298caef3 100644 --- a/web/pgadmin/misc/statistics/static/js/statistics.js +++ b/web/pgadmin/misc/statistics/static/js/statistics.js @@ -199,7 +199,7 @@ define('misc.statistics', [ */ // Avoid unnecessary reloads - var treeHierarchy = node.getTreeNodeHierarchy(item); + var treeHierarchy = pgBrowser.tree.getTreeNodeHierarchy(item); var cache_flag = { node_type: node_type, url: url, @@ -210,7 +210,7 @@ define('misc.statistics', [ // Cache the current IDs for next time $(panel[0]).data('node-prop', cache_flag); - if (statisticsHelper.nodeHasStatistics(node, item)) { + if (statisticsHelper.nodeHasStatistics(pgBrowser, node, item)) { msg = ''; var timer; // Set the url, fetch the data and update the collection diff --git a/web/pgadmin/preferences/static/js/preferences.js b/web/pgadmin/preferences/static/js/preferences.js index 6dd88151f..5b5d1087a 100644 --- a/web/pgadmin/preferences/static/js/preferences.js +++ b/web/pgadmin/preferences/static/js/preferences.js @@ -495,7 +495,7 @@ define('pgadmin.preferences', [ view: {duration: 75}, }); - modifyAnimation.modifyAcitreeAnimation(pgBrowser, jTree.aciTree('api')); + if (jTree.aciTree('api')) modifyAnimation.modifyAcitreeAnimation(pgBrowser, jTree.aciTree('api')); this.show(); }, diff --git a/web/pgadmin/static/bundle/app.js b/web/pgadmin/static/bundle/app.js index c8bd8f74b..6b11fefea 100644 --- a/web/pgadmin/static/bundle/app.js +++ b/web/pgadmin/static/bundle/app.js @@ -13,11 +13,22 @@ define('app', [ var initializeModules = function(Object) { for (var key in Object) { var module = Object[key]; - if (module.init && typeof module.init == 'function') { - module.init(); + + if (module && module.init && typeof module.init == 'function') { + try { + module.init(); + } + catch (e) { + console.warn(e.stack || e); + } } - else if (module.Init && typeof module.Init == 'function') { - module.Init(); + else if (module && module.Init && typeof module.Init == 'function') { + try { + module.init(); + } + catch (e) { + console.warn(e.stack || e); + } } } }; diff --git a/web/pgadmin/static/js/alertify/dialog.js b/web/pgadmin/static/js/alertify/dialog.js index 6b7c41c50..27ba62a5f 100644 --- a/web/pgadmin/static/js/alertify/dialog.js +++ b/web/pgadmin/static/js/alertify/dialog.js @@ -10,7 +10,6 @@ import gettext from '../gettext'; import {DialogFactory} from './dialog_factory'; import Backform from '../backform.pgadmin'; -import {getTreeNodeHierarchyFromIdentifier} from '../tree/pgadmin_tree_node'; /** * This class can be extended to create new dialog boxes. @@ -35,8 +34,8 @@ export class Dialog { retrieveAncestorOfTypeServer(item) { let serverInformation = null; - let aciTreeItem = item || this.pgBrowser.treeMenu.selected(); - let treeNode = this.pgBrowser.treeMenu.findNodeByDomElement(aciTreeItem); + let aciTreeItem = item || this.pgBrowser.tree.selected(); + let treeNode = this.pgBrowser.tree.findNodeByDomElement(aciTreeItem); if (treeNode) { let nodeData; @@ -107,7 +106,7 @@ export class Dialog { } canExecuteOnCurrentDatabase(aciTreeItem) { - const treeInfo = getTreeNodeHierarchyFromIdentifier.apply(this.pgBrowser, [aciTreeItem]); + const treeInfo = this.pgBrowser.tree.getTreeNodeHierarchy(aciTreeItem); if (treeInfo.database && treeInfo.database._label.indexOf('=') >= 0) { this.alertify.alert( diff --git a/web/pgadmin/static/js/misc/statistics/statistics.js b/web/pgadmin/static/js/misc/statistics/statistics.js index a004a61bd..1549db990 100644 --- a/web/pgadmin/static/js/misc/statistics/statistics.js +++ b/web/pgadmin/static/js/misc/statistics/statistics.js @@ -7,9 +7,9 @@ // ////////////////////////////////////////////////////////////////////////// -export function nodeHasStatistics(node, item) { +export function nodeHasStatistics(pgBrowser, node, item) { if(typeof(node.hasStatistics) === 'function') { - const treeHierarchy = node.getTreeNodeHierarchy(item); + const treeHierarchy = pgBrowser.tree.getTreeNodeHierarchy(item); return node.hasStatistics(treeHierarchy); } return node.hasStatistics; diff --git a/web/pgadmin/static/js/nodes/dashboard.js b/web/pgadmin/static/js/nodes/dashboard.js index 137fde684..f4688cd10 100644 --- a/web/pgadmin/static/js/nodes/dashboard.js +++ b/web/pgadmin/static/js/nodes/dashboard.js @@ -12,7 +12,7 @@ import pgBrowser from 'pgadmin.browser'; export function url(itemData, item, treeHierarchy) { - let treeNode = pgBrowser.treeMenu.findNodeByDomElement(item); + let treeNode = pgBrowser.tree.findNodeByDomElement(item); let return_url = null; if (treeNode) { diff --git a/web/pgadmin/static/js/nodes/supported_database_node.js b/web/pgadmin/static/js/nodes/supported_database_node.js index e174363ad..469ac47b3 100644 --- a/web/pgadmin/static/js/nodes/supported_database_node.js +++ b/web/pgadmin/static/js/nodes/supported_database_node.js @@ -8,6 +8,7 @@ ////////////////////////////////////////////////////////////// import {isValidTreeNodeData} from 'sources/tree/tree'; +import pgAdmin from 'sources/pgadmin'; function checkAllowConnIfDatabaseNode(treeNodeData) { return (treeNodeData._type === 'database' && treeNodeData.allowConn) @@ -24,7 +25,8 @@ export function enabled(tree, supportedNodes, treeNodeData, domTreeNode) { if (!isValidTreeNodeData(treeNodeData)) return false; - let treeNode = tree.findNodeByDomElement(domTreeNode); + let _tree = tree ? tree : pgAdmin.Browser.tree; + let treeNode = _tree.findNodeByDomElement(domTreeNode); if (!treeNode) { return false; } diff --git a/web/pgadmin/static/js/tree/pgadmin_tree_node.js b/web/pgadmin/static/js/tree/pgadmin_tree_node.js deleted file mode 100644 index 55c35e374..000000000 --- a/web/pgadmin/static/js/tree/pgadmin_tree_node.js +++ /dev/null @@ -1,75 +0,0 @@ -////////////////////////////////////////////////////////////////////////// -// -// pgAdmin 4 - PostgreSQL Tools -// -// Copyright (C) 2013 - 2021, The pgAdmin Development Team -// This software is released under the PostgreSQL Licence -// -////////////////////////////////////////////////////////////////////////// - -/** - * This method received pgBrowser and new TreeNode object - * - * This method retrieves all the data that exists in the tree node and in - * `pgBrowser.Nodes` for all the parent node of the provided node. - * - * The 2 condition to get the information from pgBrowser.Nodes are: - * 1 - the variable _type of the tree node - * 2 - the presence of hasId in the pgBrowser.Nodes for the specific node - * - * Number 2 is used to ignore coll-* nodes as they do not add any useful - * information - */ -export function getTreeNodeHierarchyFromElement(pgBrowser, treeNode) { - return getTreeNodeHierarchy.call(pgBrowser, treeNode); -} - -/** - * This method received an ACI Tree JQuery node - * - * NOTE: this function need to be called on pgBrowser instance. - * getTreeNodeHierarchyFromIdentifier.apply(pgBrowser, [aciTreeNodeIdentifier]) - * - * This method retrieves all the data that exists in the tree node and in - * `pgBrowser.Nodes` for all the parent node of the provided node. - * - * The 2 condition to get the information from pgBrowser.Nodes are: - * 1 - the variable _type of the tree node - * 2 - the presence of hasId in the pgBrowser.Nodes for the specific node - * - * Number 2 is used to ignore coll-* nodes as they do not add any useful - * information - */ -export function getTreeNodeHierarchyFromIdentifier(aciTreeNodeIdentifier) { - let identifier = this.treeMenu.translateTreeNodeIdFromACITree(aciTreeNodeIdentifier); - let currentNode = this.treeMenu.findNode(identifier); - if (currentNode === null) return null; - return getTreeNodeHierarchy.call(this, currentNode); -} - -export function getTreeNodeHierarchy(currentNode) { - let idx = 0; - let node_cnt = 0; - let result = {}; - - do { - const currentNodeData = currentNode.getData(); - if (currentNodeData._type in this.Nodes && this.Nodes[currentNodeData._type].hasId) { - const nodeType = mapType(currentNodeData._type, node_cnt); - if (result[nodeType] === undefined) { - result[nodeType] = _.extend({}, currentNodeData, { - 'priority': idx, - }); - idx -= 1; - } - } - node_cnt += 1; - currentNode = currentNode.hasParent() ? currentNode.parent() : null; - } while (currentNode); - - return result; -} - -function mapType(type, idx) { - return (type === 'partition' && idx > 0) ? 'table' : type; -} diff --git a/web/pgadmin/static/js/tree/pgadmin_tree_save_state.js b/web/pgadmin/static/js/tree/pgadmin_tree_save_state.js index 1a1ac11fc..950d00528 100644 --- a/web/pgadmin/static/js/tree/pgadmin_tree_save_state.js +++ b/web/pgadmin/static/js/tree/pgadmin_tree_save_state.js @@ -150,12 +150,10 @@ _.extend(pgBrowser.browserTreeState, { }); }, update_cache: function(item) { - let data = item && pgBrowser.tree.itemData(item), - node = data && pgBrowser.Nodes[data._type], - treeHierarchy = node.getTreeNodeHierarchy(item), + treeHierarchy = pgBrowser.tree.getTreeNodeHierarchy(item), topParent = undefined, - pathIDs = pgBrowser.tree.pathId(item), + pathIDs = pgBrowser.tree.pathId(pgBrowser.tree.parent(item)), oldPath = pathIDs.join(), path = [], tmpIndex = -1; @@ -208,8 +206,7 @@ _.extend(pgBrowser.browserTreeState, { let self= this, treeData = self.stored_state || {}, data = item && pgBrowser.tree.itemData(item), - node = data && pgBrowser.Nodes[data._type], - treeHierarchy = node && node.getTreeNodeHierarchy(item); + treeHierarchy = pgBrowser.tree.getTreeNodeHierarchy(item); if (treeHierarchy === null || !pgBrowser.tree.hasParent(item) || !(treeHierarchy.hasOwnProperty(self.parent))) return; @@ -265,8 +262,7 @@ _.extend(pgBrowser.browserTreeState, { let self = this, treeData = self.stored_state || {}, data = item && pgBrowser.tree.itemData(item), - node = data && pgBrowser.Nodes[data._type], - treeHierarchy = node && node.getTreeNodeHierarchy(item); + treeHierarchy = pgBrowser.tree.getTreeNodeHierarchy(item); if (treeHierarchy === null || !pgBrowser.tree.hasParent(item) || !(treeHierarchy.hasOwnProperty(self.parent))) @@ -305,7 +301,7 @@ _.extend(pgBrowser.browserTreeState, { let index = tmpItemData.indexOf(data.id); - pgBrowser.tree.toggle(item); + pgBrowser.tree.open(item); if (index == (tmpItemData.length - 1 )) { let tIndex = treeData[treeHierarchy[self.parent]['_id']]['paths'].indexOf(tData); @@ -322,8 +318,7 @@ _.extend(pgBrowser.browserTreeState, { }, update_database_status: function(item) { let data = item && pgBrowser.tree.itemData(item), - node = data && pgBrowser.Nodes[data._type], - treeHierarchy = node.getTreeNodeHierarchy(item); + treeHierarchy = pgBrowser.tree.getTreeNodeHierarchy(item); if (treeHierarchy.hasOwnProperty('database')) { let databaseItem = treeHierarchy['database']['id'], @@ -374,8 +369,7 @@ _.extend(pgBrowser.browserTreeState, { select_tree_item(item) { let treeData = this.stored_state || {}, data = item && pgBrowser.tree.itemData(item), - node = data && pgBrowser.Nodes[data._type], - treeHierarchy = node && node.getTreeNodeHierarchy(item), + treeHierarchy = pgBrowser.tree.getTreeNodeHierarchy(item), tmpTreeData = treeData[treeHierarchy[this.parent]['_id']]; diff --git a/web/pgadmin/static/js/tree/tree.js b/web/pgadmin/static/js/tree/tree.js index 68ade0715..1885f6d5d 100644 --- a/web/pgadmin/static/js/tree/tree.js +++ b/web/pgadmin/static/js/tree/tree.js @@ -7,132 +7,408 @@ // ////////////////////////////////////////////////////////////////////////// -import {isValidData} from 'sources/utils'; +import _ from 'lodash'; import $ from 'jquery'; -import Alertify from 'pgadmin.alertifyjs'; +import pgAdmin from 'sources/pgadmin'; -export class TreeNode { - constructor(id, data, domNode, parent) { - this.id = id; - this.data = data; - this.setParent(parent); - this.children = []; - this.domNode = domNode; +import { FileType } from 'react-aspen'; +import { TreeNode } from './tree_nodes'; + +import {isValidData} from 'sources/utils'; + +function manageTreeEvents(event, eventName, item) { + let d = item ? item._metadata.data: []; + let node; + let obj = pgAdmin.Browser; + + if (d && obj.Nodes[d._type]) { + node = obj.Nodes[d._type]; + + // If the Browser tree is not initialised yet + if (obj.tree === null) return; + + if (eventName == 'dragstart') { + obj.tree.handleDraggable(event, item); + } + if (eventName == 'added' || eventName == 'beforeopen' || eventName == 'loaded') { + obj.tree.addNewNode(item.getMetadata('data').id, item.getMetadata('data') ,item), item.parent.path; + } + if (_.isObject(node.callbacks) && + eventName in node.callbacks && + typeof node.callbacks[eventName] == 'function' && + !node.callbacks[eventName].apply( + node, [item, d, obj, [], eventName])) { + return true; + } + /* Raise tree events for the nodes */ + try { + node.trigger( + 'browser-node.' + eventName, node, item, d + ); + obj.Events.trigger( + 'pgadmin-browser:tree:' + eventName, item, d, node + ); + } catch (e) { + console.warn(e.stack || e); + return false; + } + } + return true; +} + + +export class Tree { + constructor(tree, manageTree, pgBrowser) { + this.tree = tree; + this.tree.onTreeEvents(manageTreeEvents); + + this.rootNode = manageTree.tempTree; + this.Nodes = pgBrowser ? pgBrowser.Nodes : pgAdmin.Browser.Nodes; + + this.draggableTypes = {}; } - hasParent() { - return this.parentNode !== null && this.parentNode !== undefined; + async refresh(item) { + await this.tree.refresh(item); } - parent() { - return this.parentNode; + async add(item, data) { + await this.tree.create(item.parent, data.itemData); } - setParent(parent) { - this.parentNode = parent; - this.path = this.id; - if (parent !== null && parent !== undefined && parent.path !== undefined) { - this.path = parent.path + '.' + this.id; + async before(item, data) { + await this.tree.create(item.parent, data.itemData); + } + + async update(item, data) { + await this.tree.update(item, data.itemData); + } + + async remove(item) { + return await this.tree.remove(item); + } + + async append(item, data) { + return await this.tree.create(item, data); + } + + next(item) { + if(item) { + let parent = this.parent(item); + if(parent && parent.children.length > 0) { + let idx = parent.children.indexOf(item); + if(idx !== -1 && parent.children.length !== idx+1) { + return parent.children[idx+1]; + } + } + } + return null; + } + + prev(item) { + if(item) { + let parent = this.parent(item); + if(parent && parent.children.length > 0) { + let idx = parent.children.indexOf(item); + if(idx !== -1 && idx !== 0) { + return parent.children[idx-1]; + } + } + } + return null; + } + + async open(item) { + if (this.isOpen(item)) { return true; } + await this.tree.toggleDirectory(item); + } + + async ensureVisible(item){ + await this.tree.ensureVisible(item); + } + + async openPath(item) { + parent = item.parent; + await this.tree.openDirectory(parent); + } + + async close(item) { + await this.tree.closeDirectory(item); + } + + async toggle(item) { + await this.tree.toggleDirectory(item); + } + + async select(item) { + await this.tree.setActiveFile(item); + } + + async selectNode(item) { + this.tree.setActiveFile(item); + } + + async unload(item) { + await this.tree.unload(item); + } + + async addIcon(item, icon) { + if (item !== undefined && item.getMetadata('data') !== undefined) { + item.getMetadata('data').icon = icon.icon; + } + await this.tree.addIcon(item, icon); + } + + removeIcon() { + // TBD + } + + setLeaf() { + // TBD + } + async setLabel(item, label) { + if(item) { + await this.tree.setLabel(item, label); } } - getData() { - if (this.data === undefined) { - return undefined; - } else if (this.data === null) { - return null; + async setInode(item) { + if(item._children) item._children = null; + await this.tree.closeDirectory(item); + } + + deselect(item) { + this.tree.deSelectActiveFile(item); + } + + wasInit() { + // TBD + return true; + } + + wasLoad(item) { + if (item && item.type === FileType.Directory) { + return item.isExpanded; } - return Object.assign({}, this.data); + return true; } - getHtmlIdentifier() { - return this.domNode; + parent(item) { + return item.parent; } - reload(tree) { - return new Promise((resolve)=>{ - this.unload(tree) - .then(()=>{ - tree.aciTreeApi.setInode(this.domNode); - tree.aciTreeApi.deselect(this.domNode); - setTimeout(() => { - tree.selectNode(this.domNode); - }, 0); - resolve(); - }); - }); - } + first(item) { + const model = this.tree.getModel(); + if (item === undefined || item === null) { + return model.root.children[0]; + } - unload(tree) { - return new Promise((resolve, reject)=>{ - this.children = []; - tree.aciTreeApi.unload(this.domNode, { - success: ()=>{ - resolve(true); - }, - fail: ()=>{ - reject(); - }, - }); - }); - } - - open(tree, suppressNoDom) { - return new Promise((resolve, reject)=>{ - if(suppressNoDom && (this.domNode == null || typeof(this.domNode) === 'undefined')) { - resolve(true); - } else if(tree.aciTreeApi.isOpen(this.domNode)) { - resolve(true); - } else { - tree.aciTreeApi.open(this.domNode, { - success: ()=>{ - resolve(true); - }, - fail: ()=>{ - reject(true); - }, - }); - } - }); - } - - /* - * Find the ancestor with matches this condition - */ - ancestorNode(condition) { - let node = this; - - while (node.hasParent()) { - node = node.parent(); - if (condition(node)) { - return node; - } + if (item.branchSize > 0) { + return item.children[0]; } return null; } - /** - * Given a condition returns true if the current node - * or any of the parent nodes condition result is true - */ - anyFamilyMember(condition) { - if(condition(this)) { - return true; + children(item) { + const model = this.tree.getModel(); + return item ? (item.children !== null ? item.children : []) : model.root.children; + } + + itemFrom(domElem) { + return this.tree.getItemFromDOM(domElem[0]); + } + + path(item) { + if (item) return item.path; + } + + pathId(item) { + if (item) { + let pathIds = item.path.split('/'); + pathIds.splice(0, 1); + return pathIds; + } + return []; + } + + itemFromDOM(domElem) { + return this.tree.getItemFromDOM(domElem[0]); + } + + siblings(item) { + if (this.hasParent(item)) { + let _siblings = this.parent(item).children.filter((_item) => _item.path !== item.path); + if (typeof(_siblings) !== 'object') return [_siblings]; + else _siblings; + } + return []; + } + + hasParent(item) { + return item && item.parent ? true : false; + } + + isOpen(item) { + if (item.type === FileType.Directory) { + return item.isExpanded; + } + return false; + } + + isClosed(item) { + if (item.type === FileType.Directory) { + return !item.isExpanded; + } + return false; + } + + itemData(item) { + return (item !== undefined && item.getMetadata('data') !== undefined) ? item._metadata.data : []; + } + + getData(item) { + return (item !== undefined && item.getMetadata('data') !== undefined) ? item._metadata.data : []; + } + + isInode(item) { + const children = this.children(item); + if (children === null || children === undefined) return false; + return children.length > 0 ? true : false; + } + + selected() { + return this.tree.getActiveFile(); + } + + + findNodeWithToggle(path) { + let tree = this; + + if(path == null || !Array.isArray(path)) { + return Promise.reject(); + } + path = '/browser/' + path.join('/'); + + let onCorrectPath = function(matchPath) { + return (matchPath !== undefined && path !== undefined + && (path.startsWith(matchPath) || path === matchPath)); + }; + + return (function findInNode(currentNode) { + return new Promise((resolve, reject)=>{ + if (path === null || path === undefined || path.length === 0) { + resolve(null); + } + /* No point in checking the children if + * the path for currentNode itself is not matching + */ + if (currentNode.path !== undefined && !onCorrectPath(currentNode.path)) { + reject(null); + } else if (currentNode.path === path) { + resolve(currentNode); + } else { + tree.open(currentNode) + .then(()=>{ + let children = currentNode.children; + for (let i = 0, length = children.length; i < length; i++) { + let childNode = children[i]; + if(onCorrectPath(childNode.path)) { + resolve(findInNode(childNode)); + return; + } + } + reject(null); + }) + .catch(()=>{ + reject(null); + }); + } + }); + })(tree.tree.getModel().root); + } + + findNodeByDomElement(domElement) { + const path = domElement.path; + if(!path || !path[0]) { + return undefined; } - return this.ancestorNode(condition) !== null; + return this.findNode(path); } - anyParent(condition) { - return this.ancestorNode(condition) !== null; - } -} -export class Tree { - constructor() { - this.rootNode = new TreeNode(undefined, {}); - this.aciTreeApi = undefined; - this.draggableTypes = {}; + addNewNode(id, data, item, parentPath) { + let parent; + parent = this.findNode(parentPath); + return this.createOrUpdateNode(id, data, parent, item); + } + + findNode(path) { + if (path === null || path === undefined || path.length === 0) { + return this.rootNode; + } + return findInTree(this.rootNode, path); + } + + createOrUpdateNode(id, data, parent, domNode) { + let oldNodePath = id; + if(parent !== null && parent !== undefined && parent.path !== undefined && parent.path != '/browser') { + oldNodePath = parent.path + '/' + id; + } + const oldNode = this.findNode(oldNodePath); + if (oldNode !== null) { + oldNode.data = data; + oldNode.domNode = domNode; + return oldNode; + } + + const node = new TreeNode(id, data, domNode, parent); + if (parent === this.rootNode) { + node.parentNode = null; + } + + if (parent !== null && parent !== undefined) + parent.children.push(node); + return node; + } + + translateTreeNodeIdFromReactTree(aciTreeNode) { + let currentTreeNode = aciTreeNode; + let path = []; + while (currentTreeNode !== null && currentTreeNode !== undefined) { + if (currentTreeNode.path !== '/browser') path.unshift(currentTreeNode.path); + if (this.hasParent(currentTreeNode)) { + currentTreeNode = this.parent(currentTreeNode); + } else { + break; + } + } + return path; + } + + getTreeNodeHierarchy(identifier) { + let idx = 0; + let node_cnt = 0; + let result = {}; + if (identifier === undefined) return; + let item = TreeNode.prototype.isPrototypeOf(identifier) ? identifier : this.findNode(identifier.path); + if (item === undefined) return; + do { + const currentNodeData = item.getData(); + if (currentNodeData._type in this.Nodes && this.Nodes[currentNodeData._type].hasId) { + const nodeType = mapType(currentNodeData._type, node_cnt); + if (result[nodeType] === undefined) { + result[nodeType] = _.extend({}, currentNodeData, { + 'priority': idx, + }); + idx -= 1; + } + } + node_cnt += 1; + item = item.hasParent() ? item.parent() : null; + } while (item); + + return result; } /* @@ -164,7 +440,8 @@ export class Tree { } } - prepareDraggable(data, item) { + handleDraggable(e, item) { + let data = item.getMetadata('data'); let dropDetailsFunc = this.getDraggable(data._type); if(dropDetailsFunc != null) { @@ -173,265 +450,67 @@ export class Tree { * overrides the dragstart event set using element.on('dragstart') * This will avoid conflict. */ - item.find('.aciTreeItem') - .attr('draggable', true)[0] - .addEventListener('dragstart', (e)=> { - let dropDetails = dropDetailsFunc(data, item); + let dropDetails = dropDetailsFunc(data, item); - if(typeof dropDetails == 'string') { - dropDetails = { - text:dropDetails, - cur:{ - from:dropDetails.length, - to: dropDetails.length, - }, - }; - } else { - if(!dropDetails.cur) { - dropDetails = { - ...dropDetails, - cur:{ - from:dropDetails.text.length, - to: dropDetails.text.length, - }, - }; - } - } - - e.dataTransfer.setData('text', JSON.stringify(dropDetails)); - /* Required by Firefox */ - if(e.dataTransfer.dropEffect) { - e.dataTransfer.dropEffect = 'move'; - } - - /* setDragImage is not supported in IE. We leave it to - * its default look and feel - */ - if(e.dataTransfer.setDragImage) { - let dragItem = $(` -
- ${_.escape(dropDetails.text)} -
` - ); - - $('body .drag-tree-node').remove(); - $('body').append(dragItem); - - e.dataTransfer.setDragImage(dragItem[0], 0, 0); - } - }); - } - } - - addNewNode(id, data, domNode, parentPath) { - const parent = this.findNode(parentPath); - return this.createOrUpdateNode(id, data, parent, domNode); - } - - findNode(path) { - if (path === null || path === undefined || path.length === 0) { - return this.rootNode; - } - return findInTree(this.rootNode, path.join('.')); - } - - findNodeWithToggle(path) { - let tree = this; - - if(path == null || !Array.isArray(path)) { - return Promise.reject(); - } - path = path.join('.'); - - let onCorrectPath = function(matchPath) { - return (matchPath !== undefined && path !== undefined - && (path.startsWith(matchPath + '.') || path === matchPath)); - }; - - return (function findInNode(currentNode) { - return new Promise((resolve, reject)=>{ - if (path === null || path === undefined || path.length === 0) { - resolve(null); - } - /* No point in checking the children if - * the path for currentNode itself is not matching - */ - if (currentNode.path !== undefined && !onCorrectPath(currentNode.path)) { - reject(null); - } else if (currentNode.path === path) { - resolve(currentNode); - } else { - currentNode.open(tree, true) - .then(()=>{ - for (let i = 0, length = currentNode.children.length; i < length; i++) { - let childNode = currentNode.children[i]; - if(onCorrectPath(childNode.path)) { - resolve(findInNode(childNode)); - return; - } - } - reject(null); - }) - .catch(()=>{ - reject(null); - }); - } - }); - })(this.rootNode); - } - - findNodeByDomElement(domElement) { - const path = this.translateTreeNodeIdFromACITree(domElement); - if(!path || !path[0]) { - return undefined; - } - - return this.findNode(path); - } - - selected() { - return this.aciTreeApi.selected(); - } - - /* scrollIntoView will scroll only to top and bottom - * Logic can be added for scroll to middle - */ - scrollTo(domElement) { - domElement.scrollIntoView(); - } - - selectNode(aciTreeIdentifier, scrollOnSelect) { - this.aciTreeApi.select(aciTreeIdentifier); - - if(scrollOnSelect) { - this.scrollTo(aciTreeIdentifier[0]); - } - } - - createOrUpdateNode(id, data, parent, domNode) { - let oldNodePath = [id]; - if(parent !== null && parent !== undefined) { - oldNodePath = [parent.path, id]; - } - const oldNode = this.findNode(oldNodePath); - if (oldNode !== null) { - oldNode.data = data; - oldNode.domNode = domNode; - return oldNode; - } - - const node = new TreeNode(id, data, domNode, parent); - if (parent === this.rootNode) { - node.parentNode = null; - } - - if (parent !== null && parent !== undefined) - parent.children.push(node); - return node; - } - - unloadNode(id, data, domNode, parentPath) { - let oldNodePath = [id]; - const parent = this.findNode(parentPath); - if(parent !== null && parent !== undefined) { - oldNodePath = [parent.path, id]; - } - const oldNode = this.findNode(oldNodePath); - if(oldNode) { - oldNode.children = []; - } - } - - /** - * Given the JQuery object that contains the ACI Tree - * this method is responsible for registering this tree class - * to listen to all the events that happen in the ACI Tree. - * - * At this point in time the only event that we care about is - * the addition of a new node. - * The function will create a new tree node to store the information - * that exist in the ACI for it. - */ - register($treeJQuery) { - $treeJQuery.on('acitree', function (event, api, item, eventName) { - if (api.isItem(item)) { - /* If the id of node is changed, the path should also be changed */ - if (['added', 'idset', 'beforeunload'].indexOf(eventName) != -1) { - const id = api.getId(item); - const data = api.itemData(item); - const parentId = this.translateTreeNodeIdFromACITree(api.parent(item)); - - if(eventName === 'beforeunload') { - this.unloadNode(id, data, item, parentId); - } else { - if(eventName === 'added') { - this.prepareDraggable(data, item); - } - - this.addNewNode(id, data, item, parentId); - } - if(data.errmsg) { - Alertify.error(data.errmsg); - } - } - } - }.bind(this)); - this.aciTreeApi = $treeJQuery.aciTree('api'); - - /* Ctrl + Click will trigger context menu. Select the node when Ctrl+Clicked. - * When the context menu is visible, the tree should lose focus - * to use context menu with keyboard. Otherwise, the tree functions - * overrides the keyboard events. - */ - let contextHandler = (ev)=>{ - let treeItem = this.aciTreeApi.itemFrom(ev.target); - if(treeItem.length) { - if(ev.ctrlKey) { - this.aciTreeApi.select(treeItem); - } - $(treeItem).on('contextmenu:visible', ()=>{ - $(treeItem).trigger('blur'); - $(treeItem).off('contextmenu:visible'); - }); - } - }; - $treeJQuery - .off('mousedown', contextHandler) - .on('mousedown', contextHandler); - } - - /** - * As the name hints this functions works as a layer in between ACI and - * the adaptor. Given a ACITree JQuery node find the location of it in the - * Tree and then returns and array with the path to the Tree Node in - * question - * - * This is not optimized and will always go through the full tree - */ - translateTreeNodeIdFromACITree(aciTreeNode) { - let currentTreeNode = aciTreeNode; - let path = []; - while (currentTreeNode !== null && currentTreeNode !== undefined && currentTreeNode.length > 0) { - path.unshift(this.aciTreeApi.getId(currentTreeNode)); - if (this.aciTreeApi.hasParent(currentTreeNode)) { - currentTreeNode = this.aciTreeApi.parent(currentTreeNode); + if(typeof dropDetails == 'string') { + dropDetails = { + text:dropDetails, + cur:{ + from:dropDetails.length, + to: dropDetails.length, + }, + }; } else { - break; + if(!dropDetails.cur) { + dropDetails = { + ...dropDetails, + cur:{ + from:dropDetails.text.length, + to: dropDetails.text.length, + }, + }; + } + } + + e.dataTransfer.setData('text', JSON.stringify(dropDetails)); + /* Required by Firefox */ + if(e.dataTransfer.dropEffect) { + e.dataTransfer.dropEffect = 'move'; + } + + /* setDragImage is not supported in IE. We leave it to + * its default look and feel + */ + if(e.dataTransfer.setDragImage) { + let dragItem = $(` +
+ ${_.escape(dropDetails.text)} +
` + ); + + $('body .drag-tree-node').remove(); + $('body').append(dragItem); + + e.dataTransfer.setDragImage(dragItem[0], 0, 0); } } - return path; } } +function mapType(type, idx) { + return (type === 'partition' && idx > 0) ? 'table' : type; +} + + + /** * Given an initial node and a path, it will navigate through * the new tree to find the node that matches the path */ -function findInTree(rootNode, path) { +export function findInTree(rootNode, path) { if (path === null) { return rootNode; } - return (function findInNode(currentNode) { /* No point in checking the children if diff --git a/web/pgadmin/static/js/tree/tree_init.tsx b/web/pgadmin/static/js/tree/tree_init.tsx new file mode 100644 index 000000000..4d67ecf21 --- /dev/null +++ b/web/pgadmin/static/js/tree/tree_init.tsx @@ -0,0 +1,87 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2021, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import * as React from 'react'; +import { render } from 'react-dom'; +import { FileTreeX, TreeModelX } from 'pgadmin4-tree'; +import {Tree} from './tree'; + +import { IBasicFileSystemHost } from 'react-aspen'; +import { ManageTreeNodes } from './tree_nodes' + +var initBrowserTree = async (pgBrowser) => { + const MOUNT_POINT = '/browser' + + // Setup host + let mtree = new ManageTreeNodes(); + + // Init Tree with the Tree Parent node '/browser' + mtree.init(MOUNT_POINT); + + const host: IBasicFileSystemHost = { + pathStyle: 'unix', + getItems: async (path) => { + let nodes = await mtree.readNode(path); + return nodes; + }, + } + + // Create Node + const create = async (parentPath, _data): Promise => { + try { + let _node_path = parentPath + "/" + _data.id + return mtree.addNode(parentPath, _node_path, _data) + } catch (error) { + return null // or throw error as you see fit + } + } + + + // Remove Node + const remove = async (path: string, _removeOnlyChild): Promise => { + try { + await mtree.removeNode(path, _removeOnlyChild); + return true + } catch (error) { + return false // or throw error as you see fit + } + } + + // Update Node + const update = async (path: string, data): Promise => { + try { + await mtree.updateNode(path, data); + return true + } catch (error) { + return false // or throw error as you see fit + } + } + + const treeModelX = new TreeModelX(host, MOUNT_POINT) + + const itemHandle = function onReady(handler) { + // Initialize pgBrowser Tree + pgBrowser.tree = new Tree(handler, mtree, pgBrowser); + return true; + } + + await treeModelX.root.ensureLoaded() + + // Render Browser Tree + await render( +
+ +
, document.getElementById('tree')); +} + +module.exports = { + initBrowserTree: initBrowserTree, +}; + diff --git a/web/pgadmin/static/js/tree/tree_nodes.ts b/web/pgadmin/static/js/tree/tree_nodes.ts new file mode 100644 index 000000000..d1a40e6c8 --- /dev/null +++ b/web/pgadmin/static/js/tree/tree_nodes.ts @@ -0,0 +1,298 @@ +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2021, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + +import * as BrowserFS from 'browserfs' +import url_for from 'sources/url_for'; +import pgAdmin from 'sources/pgadmin'; +import _ from 'underscore'; +import { FileType } from 'react-aspen' +import { findInTree } from './tree'; + +import { dirname } from 'path-fx'; + +export class ManageTreeNodes { + constructor(fs) { + this.tree = {} + this.tempTree = new TreeNode(undefined, {}); + } + + public init = (_root: string) => new Promise((res, rej) => { + let node = {parent: null, children: [], data: null}; + this.tree = {}; + this.tree[_root] = {name: 'root', type: FileType.Directory, metadata: node}; + res(); + }) + + public updateNode = (_path, _data) => new Promise((res, rej) => { + if (_path in this.tree) { + const item = this.tree[_path]; + item.name = _data.label; + item.metadata.data = _data; + } + res(true); + }) + + public removeNode = async (_path, _removeOnlyChild) => { + const item = this.findNode(_path); + + if (item && item.parentNode) { + item.children = []; + item.parentNode.children.splice(item.parentNode.children.indexOf(item), 1); + } + return true; + }; + + findNode(path) { + if (path === null || path === undefined || path.length === 0 || path == '/browser') { + return this.tempTree; + } + return findInTree(this.tempTree, path); + } + + public addNode = (_parent: string, _path: string, _data: []) => new Promise((res, rej) => { + _data.type = _data.inode ? FileType.Directory : FileType.File; + _data._label = _data.label; + _data.label = _.escape(_data.label); + + _data.is_collection = isCollectionNode(_data._type); + let nodeData = {parent: _parent, children: [], data: _data}; + + let tmpParentNode = this.findNode(_parent); + let treeNode = new TreeNode(_data.id, _data, {}, tmpParentNode, nodeData, _data.type); + + if (tmpParentNode !== null && tmpParentNode !== undefined) tmpParentNode.children.push(treeNode); + + res(treeNode); + }) + + public readNode = (_path: string) => new Promise((res, rej) => { + let temp_tree_path = _path; + let node = this.findNode(_path); + + if (node && node.children.length > 0) { + if (!node.type === FileType.File) { + rej("It's a leaf node") + } + else { + if (node.children.length != 0) res(node.children) + } + } + + var self = this; + + async function loadData() { + let url = ''; + if (_path == '/browser') { + url = url_for('browser.nodes'); + } else { + let _parent_url = self.generate_url(_path); + if (node.metadata.data._pid == null ) { + url = node.metadata.data._type + '/children/' + node.metadata.data._id; + } + else { + if (node.metadata.data._type.includes("coll-")) { + let _type = node.metadata.data._type.replace("coll-", "") + url = _type + '/nodes/' + _parent_url; + } + else { + url = node.metadata.data._type + '/children/' + _parent_url + '/' + node.metadata.data._id; + } + } + + temp_tree_path = node.path; + + if (node.metadata.data._type == 'server' && !node.metadata.data.connected) { + url = null; + } + } + + async function jsonData(url) { + let res = await fetch(url, { + headers: { + 'X-Requested-With': 'XMLHttpRequest', + 'X-pgA-CSRFToken': pgAdmin.csrf_token + }, + }); + + if (res.status == 200) { + try { + let json = await res.json(); + return json.data; + } catch (e) { + console.warn(e); + } + } + throw new Error("Node Load Error..."); + return []; + } + + let treeData = null; + if (url) treeData = await jsonData(url); + + const Path = BrowserFS.BFSRequire('path') + const fill = async (tree) => { + for (let idx in tree) { + const _node = tree[idx] + const _pathl = Path.join(_path, _node.id) + await self.addNode(temp_tree_path, _pathl, _node); + } + } + + let d = await fill(treeData); + if (node.children.length > 0) res(node.children); + else res(null); + + } + loadData(); + }) + + public generate_url = (path: string) => { + let _path = path; + let _parent_path = []; + while(_path != '/') { + let node = this.findNode(_path); + let _parent = dirname(_path); + if(node.parentNode && node.parentNode.path == _parent) { + if (node.parentNode.metadata.data !== null && !node.parentNode.metadata.data._type.includes('coll-')) + _parent_path.push(node.parentNode.metadata.data._id); + } + _path = _parent; + } + let _rev_arr = _parent_path.reverse(); + return _rev_arr.join("/"); + } +} + + + +export class TreeNode { + constructor(id, data, domNode, parent, metadata, type) { + this.id = id; + this.data = data; + this.setParent(parent); + this.children = []; + this.domNode = domNode; + this.metadata = metadata; + this.name = metadata ? metadata.data.label : ""; + this.type = type ? type : undefined; + } + + hasParent() { + return this.parentNode !== null && this.parentNode !== undefined; + } + + parent() { + return this.parentNode; + } + + setParent(parent) { + this.parentNode = parent; + this.path = this.id; + if (this.id) + if (parent !== null && parent !== undefined && parent.path !== undefined) { + this.path = parent.path + '/' + this.id; + } else { + this.path = '/browser/' + this.id; + } + } + + getData() { + if (this.data === undefined) { + return undefined; + } else if (this.data === null) { + return null; + } + return Object.assign({}, this.data); + } + + getHtmlIdentifier() { + return this.domNode; + } + + /* + * Find the ancestor with matches this condition + */ + ancestorNode(condition) { + let node = this; + + while (node.hasParent()) { + node = node.parent(); + if (condition(node)) { + return node; + } + } + + return null; + } + + /** + * Given a condition returns true if the current node + * or any of the parent nodes condition result is true + */ + anyFamilyMember(condition) { + if(condition(this)) { + return true; + } + + return this.ancestorNode(condition) !== null; + } + anyParent(condition) { + return this.ancestorNode(condition) !== null; + } + + reload(tree) { + return new Promise((resolve)=>{ + this.unload(tree) + .then(()=>{ + tree.setInode(this.domNode); + tree.deselect(this.domNode); + setTimeout(() => { + tree.selectNode(this.domNode); + }, 0); + resolve(); + }); + }); + } + + unload(tree) { + return new Promise((resolve, reject)=>{ + this.children = []; + tree.unload(this.domNode) + .then( + ()=>{ + resolve(true); + }, + ()=>{ + reject(); + }); + }); + } + + + open(tree, suppressNoDom) { + return new Promise((resolve, reject)=>{ + if(suppressNoDom && (this.domNode == null || typeof(this.domNode) === 'undefined')) { + resolve(true); + } else if(tree.isOpen(this.domNode)) { + resolve(true); + } else { + tree.open(this.domNode).then(val => resolve(true), err => reject(true)); + } + }); + } + +} + +export function isCollectionNode(node) { + if (pgAdmin.Browser.Nodes && node in pgAdmin.Browser.Nodes) { + if (pgAdmin.Browser.Nodes[node].is_collection !== undefined) return pgAdmin.Browser.Nodes[node].is_collection; + else return false; + } + return false; +} diff --git a/web/pgadmin/static/js/tree/tree_utils.js b/web/pgadmin/static/js/tree/tree_utils.js index be6ca6df0..97b009ab4 100644 --- a/web/pgadmin/static/js/tree/tree_utils.js +++ b/web/pgadmin/static/js/tree/tree_utils.js @@ -11,8 +11,8 @@ import gettext from 'sources/gettext'; export function retrieveAncestorOfTypeServer(pgBrowser, item, errorAlertTitle, alertify) { let serverInformation = null; - let aciTreeItem = item || pgBrowser.treeMenu.selected(); - let treeNode = pgBrowser.treeMenu.findNodeByDomElement(aciTreeItem); + let aciTreeItem = item || pgBrowser.tree.selected(); + let treeNode = pgBrowser.tree.findNodeByDomElement(aciTreeItem); if (treeNode) { let nodeData; @@ -58,9 +58,8 @@ export function retrieveAncestorOfTypeServer(pgBrowser, item, errorAlertTitle, a export function retrieveAncestorOfTypeDatabase(pgBrowser, item, errorAlertTitle, alertify) { let databaseInfo = null; - let aciTreeItem = item || pgBrowser.treeMenu.selected(); - let treeNode = pgBrowser.treeMenu.findNodeByDomElement(aciTreeItem); - + let aciTreeItem = item || pgBrowser.tree.selected(); + let treeNode = pgBrowser.tree.findNodeByDomElement(aciTreeItem); if (treeNode) { if(treeNode.getData()._type === 'database') { databaseInfo = treeNode.getData(); diff --git a/web/pgadmin/static/js/utils.js b/web/pgadmin/static/js/utils.js index 63186edf5..bd3e38578 100644 --- a/web/pgadmin/static/js/utils.js +++ b/web/pgadmin/static/js/utils.js @@ -8,7 +8,6 @@ ////////////////////////////////////////////////////////////////////////// import _ from 'underscore'; -import { getTreeNodeHierarchyFromIdentifier } from 'sources/tree/pgadmin_tree_node'; import $ from 'jquery'; import gettext from 'sources/gettext'; import 'wcdocker'; @@ -237,7 +236,7 @@ export function quote_ident(value) { } export function fully_qualify(pgBrowser, data, item) { - const parentData = getTreeNodeHierarchyFromIdentifier.call(pgBrowser, item); + const parentData = pgBrowser.tree.getTreeNodeHierarchy(item); let namespace = ''; if (parentData.schema !== undefined) { diff --git a/web/pgadmin/static/scss/_pgadmin.style.scss b/web/pgadmin/static/scss/_pgadmin.style.scss index d990b5509..9266f82e4 100644 --- a/web/pgadmin/static/scss/_pgadmin.style.scss +++ b/web/pgadmin/static/scss/_pgadmin.style.scss @@ -166,6 +166,7 @@ right:0px; bottom:0px; height: 100%!important; + overflow: scroll; } .pg-prop-footer { @@ -1089,12 +1090,15 @@ textarea { border-radius: $border-radius*2; background-clip: content-box; background-color: rgba($scrollbar-base-color, 0.7); + background: rgba($scrollbar-base-color, 0.7) !important; } ::-webkit-scrollbar-thumb:hover { background-color: $scrollbar-base-color; + background: $scrollbar-base-color !important; } + input:-webkit-autofill, input:-webkit-autofill:hover, input:-webkit-autofill:focus, diff --git a/web/pgadmin/static/scss/_pgadmin4-tree.overrides.scss b/web/pgadmin/static/scss/_pgadmin4-tree.overrides.scss new file mode 100644 index 000000000..859d075b7 --- /dev/null +++ b/web/pgadmin/static/scss/_pgadmin4-tree.overrides.scss @@ -0,0 +1,123 @@ +.file-tree { + font-family: $font-family-primary !important; + font-size: $tree-font-size !important; + background-color: $color-bg !important; + display: inline-block; + color: $tree-text-fg !important; + &, & * { + box-sizing: border-box; + } + width: 100%; +} + +.file-tree > { + div { + position: absolute !important; + height: 100% !important; + top: 0px !important; + } +} + +.file-entry +{ + color: $tree-text-fg !important; + span.file-name { + color: $tree-text-fg !important; + white-space: nowrap; + } + &:hover, &.pseudo-active { + background-color: $tree-bg-hover !important; + } +} + +.file-entry +{ + font: inherit; + text-align: left; + display: flex; + align-items: center; + white-space: nowrap; + padding: 2px 0; + padding-left: 2px; + cursor: default; + &:hover, &.pseudo-active { + background-color: $tree-bg-hover !important; + } + &.active, &.prompt { + background-color: $tree-bg-selected !important; + border-color: $color-primary-light; + border-right: $active-border !important; + } + i { + display: inline-block; + font: normal normal normal 18px/1 "default-icons"; + font-size: 18px; + text-align: center; + height: 21px !important; + width: 20px; + &:before { + height: inherit; + width: inherit; + display: inline-block; + } + &.directory-toggle { + &:before { + background-position: 6px center !important; + font-family: $font-family-icon; + content: "\f054" !important; + border-style: none; + margin-left: 5px; + font-weight: 900; + right: 15px; + top: 3px; + font-size: 0.6rem; + line-height: 2; + } + &.open:before { + background-position: -14px center !important; + font-family: $font-family-icon; + content: "\f078" !important; + border-style: none; + margin-left: 5px; + font-weight: 900; + transform: none !important; + } + &.loading:before { + background-position: 6px center !important; + font-weight: 900; + font-size: 0.6rem; + line-height: 2; + content: '' !important; + font-family: $font-family-icon; + margin-left: 5px; + border-style: none; + background: $loader-icon-small 0 0 no-repeat; + } + } + } + span.file-label { + display: flex; + align-items: center; + padding:0 2px 0 2px; + border:1px solid transparent; + height:auto; + white-space:normal; + cursor:pointer; + margin-right:24px; + } + &.prompt.new .file-label, &.file .file-label { + margin-left: 18px; + } + span.file-name { + font: inherit; + flex-grow: 1; + user-select: none; + cursor: default; + color: #c1c1c1; + margin-left: 3px; + } +} + +.children-count { + margin-left: 3px; +} diff --git a/web/pgadmin/static/scss/pgadmin.scss b/web/pgadmin/static/scss/pgadmin.scss index 955f41d0f..d5b1e0864 100644 --- a/web/pgadmin/static/scss/pgadmin.scss +++ b/web/pgadmin/static/scss/pgadmin.scss @@ -33,3 +33,5 @@ $theme-colors: ( @import 'pickr.overrides'; @import 'tippy.overrides'; @import 'jsoneditor.overrides'; +@import 'pgadmin4-tree.overrides'; +@import 'pgadmin4-tree/src/css/styles'; diff --git a/web/pgadmin/tools/backup/static/js/backup.js b/web/pgadmin/tools/backup/static/js/backup.js index 9bb32f172..cdbc44d9d 100644 --- a/web/pgadmin/tools/backup/static/js/backup.js +++ b/web/pgadmin/tools/backup/static/js/backup.js @@ -199,7 +199,7 @@ define([ if (!_.isUndefined(m.get('type')) && m.get('type') === 'server') { var t = pgBrowser.tree, i = t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + d = i ? t.itemData(i) : undefined; return _.isUndefined(d) ? false : d.version >= 110000; } return true; @@ -391,8 +391,7 @@ define([ visible: function() { var t = pgBrowser.tree, i = t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined, - s = _.isUndefined(d) ? undefined : pgBrowser.Nodes[d._type].getTreeNodeHierarchy(i)['server']; + s = _.isUndefined(i) ? undefined : t.getTreeNodeHierarchy(i)['server']; return _.isUndefined(s) ? false : s.version >= 110000; }, @@ -466,8 +465,7 @@ define([ var t = pgBrowser.tree, i = t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined, - s = _.isUndefined(d) ? undefined : pgBrowser.Nodes[d._type].getTreeNodeHierarchy(i)['server']; + s = _.isUndefined(i) ? undefined : t.getTreeNodeHierarchy(i)['server']; return _.isUndefined(s) ? false : s.version >= 110000; }, @@ -518,8 +516,7 @@ define([ disabled: function(m) { var t = pgBrowser.tree, i = t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined, - s = _.isUndefined(d) ? undefined : pgBrowser.Nodes[d._type].getTreeNodeHierarchy(i)['server']; + s = _.isUndefined(i) ? undefined : t.getTreeNodeHierarchy(i)['server']; if (!_.isUndefined(s) && s.version >= 120000) return true; @@ -632,7 +629,7 @@ define([ label: gettext('Backup...'), icon: 'fa fa-save', enable: supportedNodes.enabled.bind( - null, pgBrowser.treeMenu, menuUtils.backupSupportedNodes + null, pgBrowser.tree, menuUtils.backupSupportedNodes ), data: { data_disabled: gettext('Please select any database or schema or table from the browser tree to take Backup.'), @@ -650,7 +647,7 @@ define([ label: gettext('Backup...'), icon: 'fa fa-save', enable: supportedNodes.enabled.bind( - null, pgBrowser.treeMenu, menuUtils.backupSupportedNodes + null, pgBrowser.tree, menuUtils.backupSupportedNodes ), }); } diff --git a/web/pgadmin/tools/backup/static/js/backup_dialog.js b/web/pgadmin/tools/backup/static/js/backup_dialog.js index 5f54b77c7..fb18ffd41 100644 --- a/web/pgadmin/tools/backup/static/js/backup_dialog.js +++ b/web/pgadmin/tools/backup/static/js/backup_dialog.js @@ -55,18 +55,15 @@ export class BackupDialog extends Dialog { ); return; } - const typeOfDialog = BackupDialog.typeOfDialog(params); if (!that.canExecuteOnCurrentDatabase(aciTreeItem)) { return; } - const dialog = that.createOrGetDialog( BackupDialog.dialogTitle(typeOfDialog), typeOfDialog ); - dialog(true).resizeTo(width, height); }).catch(function() { that.alertify.alert( diff --git a/web/pgadmin/tools/backup/static/js/backup_dialog_wrapper.js b/web/pgadmin/tools/backup/static/js/backup_dialog_wrapper.js index 5a86bf82e..b45cb8008 100644 --- a/web/pgadmin/tools/backup/static/js/backup_dialog_wrapper.js +++ b/web/pgadmin/tools/backup/static/js/backup_dialog_wrapper.js @@ -7,7 +7,6 @@ // ////////////////////////////////////////////////////////////// -import {getTreeNodeHierarchyFromElement} from '../../../../static/js/tree/pgadmin_tree_node'; import axios from 'axios/index'; import gettext from '../../../../static/js/gettext'; import url_for from '../../../../static/js/url_for'; @@ -105,7 +104,7 @@ export class BackupDialogWrapper extends DialogWrapper { this.main(title); } - const treeInfo = getTreeNodeHierarchyFromElement(this.pgBrowser, selectedTreeNode); + const treeInfo = this.pgBrowser.tree.getTreeNodeHierarchy(selectedTreeNode); const dialog = this.createDialog(node, treeInfo, this.typeOfDialog, $container); this.addAlertifyClassToBackupNodeChildNodes(); dialog.render(); @@ -162,10 +161,7 @@ export class BackupDialogWrapper extends DialogWrapper { 'sid': serverIdentifier, }); - const treeInfo = getTreeNodeHierarchyFromElement( - this.pgBrowser, - selectedTreeNode - ); + const treeInfo = this.pgBrowser.tree.getTreeNodeHierarchy(selectedTreeNode); this.setExtraParameters(selectedTreeNode, treeInfo); let backupDate = this.view.model.toJSON(); @@ -222,7 +218,7 @@ export class BackupDialogWrapper extends DialogWrapper { } getSelectedNode() { - const tree = this.pgBrowser.treeMenu; + const tree = this.pgBrowser.tree; const selectedNode = tree.selected(); if (selectedNode) { return tree.findNodeByDomElement(selectedNode); @@ -260,10 +256,7 @@ export class BackupDialogWrapper extends DialogWrapper { } retrieveServerIdentifier(node, selectedTreeNode) { - const treeInfo = getTreeNodeHierarchyFromElement( - this.pgBrowser, - selectedTreeNode - ); + const treeInfo = this.pgBrowser.tree.getTreeNodeHierarchy(selectedTreeNode); return treeInfo.server._id; } diff --git a/web/pgadmin/tools/datagrid/static/js/datagrid.js b/web/pgadmin/tools/datagrid/static/js/datagrid.js index 84995d235..cabad10cc 100644 --- a/web/pgadmin/tools/datagrid/static/js/datagrid.js +++ b/web/pgadmin/tools/datagrid/static/js/datagrid.js @@ -213,7 +213,7 @@ define('pgadmin.datagrid', [ const transId = commonUtils.getRandomInt(1, 9999999); var t = pgBrowser.tree, i = aciTreeIdentifier || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined; + 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'); @@ -312,7 +312,7 @@ define('pgadmin.datagrid', [ if(panel_data.$titleText[0].innerHTML.includes('File - ')) { is_file = true; } - var selected_item = pgBrowser.treeMenu.selected(); + var selected_item = pgBrowser.tree.selected(); var panel_titles = ''; if(is_query_tool) { diff --git a/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js b/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js index 368da487c..660fd3c81 100644 --- a/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js +++ b/web/pgadmin/tools/datagrid/static/js/datagrid_panel_title.js @@ -7,7 +7,6 @@ // ////////////////////////////////////////////////////////////// -import {getTreeNodeHierarchyFromIdentifier} from '../../../../static/js/tree/pgadmin_tree_node'; import gettext from 'sources/gettext'; import Alertify from 'pgadmin.alertifyjs'; import pgWindow from 'sources/window'; @@ -26,11 +25,12 @@ function isServerInformationAvailable(parentData) { 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) { - selected_item = pgBrowser.treeMenu.selected(); + selected_item = pgBrowser.tree.selected(); } if(parentData == null) { - parentData = getTreeNodeHierarchyFromIdentifier.call(pgBrowser, selected_item); + parentData = pgBrowser.tree.getTreeNodeHierarchy(selected_item); + if(parentData == null) return; if (isServerInformationAvailable(parentData)) { return; } diff --git a/web/pgadmin/tools/datagrid/static/js/show_data.js b/web/pgadmin/tools/datagrid/static/js/show_data.js index b1e19aaa4..018f51607 100644 --- a/web/pgadmin/tools/datagrid/static/js/show_data.js +++ b/web/pgadmin/tools/datagrid/static/js/show_data.js @@ -8,7 +8,6 @@ ////////////////////////////////////////////////////////////// import gettext from '../../../../static/js/gettext'; import url_for from '../../../../static/js/url_for'; -import {getTreeNodeHierarchyFromIdentifier} from '../../../../static/js/tree/pgadmin_tree_node'; import {getDatabaseLabel, generateTitle} from './datagrid_panel_title'; import CodeMirror from 'bundled_codemirror'; import * as SqlEditorUtils from 'sources/sqleditor_utils'; @@ -25,7 +24,7 @@ export function showDataGrid( filter=false, preferences=null ) { - const node = pgBrowser.treeMenu.findNodeByDomElement(aciTreeIdentifier); + const node = pgBrowser.tree.findNodeByDomElement(aciTreeIdentifier); if (node === undefined || !node.getData()) { alertify.alert( gettext('Data Grid Error'), @@ -34,9 +33,7 @@ export function showDataGrid( return; } - const parentData = getTreeNodeHierarchyFromIdentifier.call( - pgBrowser, - aciTreeIdentifier + const parentData = pgBrowser.tree.getTreeNodeHierarchy( aciTreeIdentifier ); if (hasServerOrDatabaseConfiguration(parentData) @@ -293,14 +290,13 @@ function hasSchemaOrCatalogOrViewInformation(parentData) { export function generateDatagridTitle(pgBrowser, aciTreeIdentifier, custom_title=null, backend_entity=null) { //const baseTitle = getPanelTitle(pgBrowser, aciTreeIdentifier); var preferences = pgBrowser.get_preferences_for_module('browser'); - const parentData = getTreeNodeHierarchyFromIdentifier.call( - pgBrowser, + const parentData = pgBrowser.tree.getTreeNodeHierarchy( aciTreeIdentifier ); 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.treeMenu.findNodeByDomElement(aciTreeIdentifier); + const node = pgBrowser.tree.findNodeByDomElement(aciTreeIdentifier); var dtg_title_placeholder = ''; if(custom_title) { diff --git a/web/pgadmin/tools/datagrid/static/js/show_query_tool.js b/web/pgadmin/tools/datagrid/static/js/show_query_tool.js index 33b894788..11e9d1f98 100644 --- a/web/pgadmin/tools/datagrid/static/js/show_query_tool.js +++ b/web/pgadmin/tools/datagrid/static/js/show_query_tool.js @@ -9,7 +9,6 @@ import gettext from '../../../../static/js/gettext'; import url_for from '../../../../static/js/url_for'; -import {getTreeNodeHierarchyFromIdentifier} from '../../../../static/js/tree/pgadmin_tree_node'; import {getPanelTitle} from './datagrid_panel_title'; import {getRandomInt} from 'sources/utils'; import $ from 'jquery'; @@ -52,7 +51,7 @@ export function showQueryTool(datagrid, pgBrowser, alertify, url, aciTreeIdentif const sURL = url || ''; const queryToolTitle = generateTitle(pgBrowser, aciTreeIdentifier); - const currentNode = pgBrowser.treeMenu.findNodeByDomElement(aciTreeIdentifier); + const currentNode = pgBrowser.tree.findNodeByDomElement(aciTreeIdentifier); if (currentNode === undefined) { alertify.alert( gettext('Query Tool Error'), @@ -61,8 +60,7 @@ export function showQueryTool(datagrid, pgBrowser, alertify, url, aciTreeIdentif return; } - const parentData = getTreeNodeHierarchyFromIdentifier.call( - pgBrowser, aciTreeIdentifier); + const parentData = pgBrowser.tree.getTreeNodeHierarchy(currentNode); if (hasServerInformations(parentData)) { return; diff --git a/web/pgadmin/tools/debugger/static/js/debugger.js b/web/pgadmin/tools/debugger/static/js/debugger.js index 6632b83c1..ea34c2bd5 100644 --- a/web/pgadmin/tools/debugger/static/js/debugger.js +++ b/web/pgadmin/tools/debugger/static/js/debugger.js @@ -227,13 +227,12 @@ define([ // Find the function is really available in database var tree = pgBrowser.tree, info = tree.selected(), - d_ = info && info.length == 1 ? tree.itemData(info) : undefined, - node = d_ && pgBrowser.Nodes[d_._type]; + d_ = info ? tree.itemData(info) : undefined; if (!d_) return false; - var treeInfo = node.getTreeNodeHierarchy.apply(node, [info]); + var treeInfo = tree.getTreeNodeHierarchy(info); // For indirect debugging user must be super user if (data && data.debug_type && data.debug_type == 'indirect' && @@ -302,13 +301,13 @@ define([ check_func_debuggable: function(args, item) { var t = pgBrowser.tree, i = item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined, + d = i ? t.itemData(i) : undefined, node = d && pgBrowser.Nodes[d._type]; if (!d) return; - var treeInfo = node.getTreeNodeHierarchy.apply(node, [i]), + var treeInfo = t.getTreeNodeHierarchy(i), _url = this.generate_url('init', treeInfo, node); var self = this; @@ -338,16 +337,15 @@ define([ var self = this; var t = pgBrowser.tree, i = item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined, - node = d && pgBrowser.Nodes[d._type], - tree_data = pgBrowser.treeMenu.translateTreeNodeIdFromACITree(i), - db_data = pgBrowser.treeMenu.findNode(tree_data.slice(0,4)), + d = i ? t.itemData(i) : undefined, + tree_data = pgBrowser.tree.translateTreeNodeIdFromReactTree(i), + db_data = pgBrowser.tree.findNode(tree_data[3]), dbNode = db_data.domNode; if (!d) return; - var treeInfo = node.getTreeNodeHierarchy.apply(node, [i]), + var treeInfo = t.getTreeNodeHierarchy(i), baseUrl; if (d._type == 'function' || d._type == 'edbfunc') { @@ -515,10 +513,10 @@ define([ var t = pgBrowser.tree, i = item || t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined, + d = i ? t.itemData(i) : undefined, node = d && pgBrowser.Nodes[d._type], - tree_data = pgBrowser.treeMenu.translateTreeNodeIdFromACITree(i), - db_data = pgBrowser.treeMenu.findNode(tree_data.slice(0,4)), + tree_data = pgBrowser.tree.translateTreeNodeIdFromReactTree(i), + db_data = pgBrowser.tree.findNode(tree_data[3]), dbNode = db_data.domNode; if (!d) @@ -526,7 +524,7 @@ define([ var is_edb_proc = d._type == 'edbproc'; - var treeInfo = node.getTreeNodeHierarchy.apply(node, [i]), + var treeInfo = t.getTreeNodeHierarchy(i), _url = this.generate_url('init', treeInfo, node); $.ajax({ @@ -546,13 +544,12 @@ define([ // Directly open the panel var _t = pgBrowser.tree, _i = _t.selected(), - _d = _i && _i.length == 1 ? _t.itemData(_i) : undefined, - _node = _d && pgBrowser.Nodes[_d._type]; + _d = _i ? _t.itemData(_i) : undefined; if (!_d) return; - var newTreeInfo = _node.getTreeNodeHierarchy.apply(_node, [_i]), + var newTreeInfo = _t.getTreeNodeHierarchy(_i), baseUrl; if (_d._type == 'function' || _d._type == 'edbfunc') { diff --git a/web/pgadmin/tools/debugger/static/js/debugger_ui.js b/web/pgadmin/tools/debugger/static/js/debugger_ui.js index 43ee2f3f6..2d6717144 100644 --- a/web/pgadmin/tools/debugger/static/js/debugger_ui.js +++ b/web/pgadmin/tools/debugger/static/js/debugger_ui.js @@ -188,13 +188,12 @@ define([ if (restart_debug == 0) { var t = pgBrowser.tree, i = t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined, - node = d && pgBrowser.Nodes[d._type]; + d = i ? t.itemData(i) : undefined; if (!d) return; - var treeInfo = node.getTreeNodeHierarchy.apply(node, [i]), + var treeInfo = t.getTreeNodeHierarchy(i), _Url; if (d._type == 'function') { @@ -623,13 +622,12 @@ define([ if (self.setting('restart_debug') == 0) { var t = pgBrowser.tree, i = t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined, - node = d && pgBrowser.Nodes[d._type]; + d = i ? t.itemData(i) : undefined; if (!d) return; - var treeInfo = node.getTreeNodeHierarchy.apply(node, [i]); + var treeInfo = t.getTreeNodeHierarchy(i); } var args_value_list = []; @@ -939,8 +937,7 @@ define([ if (!item_data) return; - let node_ele = pgBrowser.Nodes[item_data._type]; - let tree_info = node_ele.getTreeNodeHierarchy.call(node_ele, selected_item); + let tree_info = pgBrowser.tree.getTreeNodeHierarchy(selected_item); base_url = url_for('debugger.clear_arguments', { 'sid': tree_info.server._id, diff --git a/web/pgadmin/tools/erd/static/js/erd_module.js b/web/pgadmin/tools/erd/static/js/erd_module.js index f37074cb1..7751686cb 100644 --- a/web/pgadmin/tools/erd/static/js/erd_module.js +++ b/web/pgadmin/tools/erd/static/js/erd_module.js @@ -8,7 +8,6 @@ ////////////////////////////////////////////////////////////// import Alertify from 'pgadmin.alertifyjs'; -import {getTreeNodeHierarchyFromIdentifier} from 'sources/tree/pgadmin_tree_node'; import {getPanelTitle} from 'tools/datagrid/static/js/datagrid_panel_title'; import {getRandomInt, registerDetachEvent} from 'sources/utils'; @@ -98,10 +97,9 @@ export function initialize(gettext, url_for, $, _, pgAdmin, csrfToken, pgBrowser return isEnabled; }, - // Callback to draw schema diff for objects + // Callback to draw ERD Tool for objects showErdTool: function(data, aciTreeIdentifier, gen=false) { - const node = pgBrowser.treeMenu.findNodeByDomElement(aciTreeIdentifier); - if (node === undefined || !node.getData()) { + if (aciTreeIdentifier === undefined) { Alertify.alert( gettext('ERD Error'), gettext('No object selected.') @@ -109,10 +107,7 @@ export function initialize(gettext, url_for, $, _, pgAdmin, csrfToken, pgBrowser return; } - const parentData = getTreeNodeHierarchyFromIdentifier.call( - pgBrowser, - aciTreeIdentifier - ); + const parentData = pgBrowser.tree.getTreeNodeHierarchy(aciTreeIdentifier); if(_.isUndefined(parentData.database)) { Alertify.alert( diff --git a/web/pgadmin/tools/grant_wizard/static/js/grant_wizard.js b/web/pgadmin/tools/grant_wizard/static/js/grant_wizard.js index 182cfda40..419c6bea9 100644 --- a/web/pgadmin/tools/grant_wizard/static/js/grant_wizard.js +++ b/web/pgadmin/tools/grant_wizard/static/js/grant_wizard.js @@ -52,7 +52,7 @@ define([ label: gettext('Grant Wizard...'), icon: 'fa fa-unlock', enable: supportedNodes.enabled.bind( - null, pgBrowser.treeMenu, menuUtils.supportedNodes + null, pgBrowser.tree, menuUtils.supportedNodes ), data: { data_disabled: gettext('Please select any database, schema or schema objects from the browser tree to access Grant Wizard Tool.'), @@ -71,7 +71,7 @@ define([ label: gettext('Grant Wizard...'), icon: 'fa fa-unlock', enable: supportedNodes.enabled.bind( - null, pgBrowser.treeMenu, menuUtils.supportedNodes + null, pgBrowser.tree, menuUtils.supportedNodes ), }); } @@ -112,8 +112,8 @@ define([ Alertify.pgDialogBuild.apply(this); var t = pgBrowser.tree, i = t.selected(), - d = this.d = i && i.length == 1 ? t.itemData(i) : undefined, - info = this.info = pgBrowser.Node.getTreeNodeHierarchy(i); + d = this.d = i ? t.itemData(i) : undefined, + info = this.info = pgBrowser.tree.getTreeNodeHierarchy(i); var sid = info.server._id, did = info.database._id; diff --git a/web/pgadmin/tools/import_export/static/js/import_export.js b/web/pgadmin/tools/import_export/static/js/import_export.js index 1dd8e1a91..e0e68105a 100644 --- a/web/pgadmin/tools/import_export/static/js/import_export.js +++ b/web/pgadmin/tools/import_export/static/js/import_export.js @@ -410,7 +410,7 @@ define([ label: gettext('Import/Export...'), icon: 'fa fa-shopping-cart', enable: supportedNodes.enabled.bind( - null, pgBrowser.treeMenu, ['table'] + null, pgBrowser.tree, ['table'] ), data: { data_disabled: gettext('Please select any table from the browser tree to Import/Export data.'), @@ -433,7 +433,7 @@ define([ } if (pgBrowser.tree.hasParent(i)) { - i = $(pgBrowser.tree.parent(i)); + i = pgBrowser.tree.parent(i); } else { Alertify.alert(gettext('Please select server or child node from tree.')); break; @@ -450,13 +450,13 @@ define([ var t = pgBrowser.tree; i = item || t.selected(); - var d = i && i.length == 1 ? t.itemData(i) : undefined, + var d = i ? t.itemData(i) : undefined, node = d && pgBrowser.Nodes[d._type]; if (!d) return; - var treeInfo = node.getTreeNodeHierarchy.apply(node, [i]); + var treeInfo = t && t.getTreeNodeHierarchy(i); if (!Alertify.ImportDialog) { Alertify.dialog('ImportDialog', function factory() { @@ -505,9 +505,8 @@ define([ callback: function(e) { if (e.button['data-btn-name'] === 'ok') { - var n = this.settings['pg_node'], - itemArr = this.settings['pg_item'], - treeData = n.getTreeNodeHierarchy.apply(n, [itemArr]); + var itemArr = this.settings['pg_item'], + treeData = pgBrowser.tree.getTreeNodeHierarchy(itemArr); this.view.model.set({ 'database': treeData.database._label, @@ -589,9 +588,8 @@ define([ this.__internal.buttons[1].element.disabled = true; var $container = $('
'), - n = this.settings.pg_node, itemArr = this.settings.pg_item, - treeData = n.getTreeNodeHierarchy.apply(n, [itemArr]), + treeData = pgBrowser.tree.getTreeNodeHierarchy(itemArr), newModel = new ImportExportModel({}, { node_info: treeData, }), diff --git a/web/pgadmin/tools/maintenance/static/js/maintenance.js b/web/pgadmin/tools/maintenance/static/js/maintenance.js index 6df2d94fd..049657fe2 100644 --- a/web/pgadmin/tools/maintenance/static/js/maintenance.js +++ b/web/pgadmin/tools/maintenance/static/js/maintenance.js @@ -166,7 +166,7 @@ define([ label: gettext('Maintenance...'), icon: 'fa fa-wrench', enable: supportedNodes.enabled.bind( - null, pgBrowser.treeMenu, menuUtils.maintenanceSupportedNodes + null, pgBrowser.tree, menuUtils.maintenanceSupportedNodes ), data: { data_disabled: gettext('Please select any database from the browser tree to do Maintenance.'), @@ -185,7 +185,7 @@ define([ label: gettext('Maintenance...'), icon: 'fa fa-wrench', enable: supportedNodes.enabled.bind( - null, pgBrowser.treeMenu, menuUtils.maintenanceSupportedNodes + null, pgBrowser.tree, menuUtils.maintenanceSupportedNodes ), data: { data_disabled: gettext('Please select any database from the browser tree to do Maintenance.'), @@ -210,7 +210,7 @@ define([ } if (pgBrowser.tree.hasParent(i)) { - i = $(pgBrowser.tree.parent(i)); + i = pgBrowser.tree.parent(i); } else { Alertify.alert(gettext('Please select server or child node from tree.')); break; @@ -230,13 +230,12 @@ define([ i = item || t.selected(); - var d = i && i.length == 1 ? t.itemData(i) : undefined; + var d = i ? t.itemData(i) : undefined; if (!d) return; - var node = pgBrowser.Nodes[d._type], - treeInfo = node.getTreeNodeHierarchy.apply(node, [i]); + var treeInfo = t && t.getTreeNodeHierarchy(i); if (treeInfo.database._label.indexOf('=') >= 0) { Alertify.alert( @@ -304,7 +303,7 @@ define([ // Callback functions when click on the buttons of the Alertify dialogs callback: function(e) { var sel_item = pgBrowser.tree.selected(), - itemData = sel_item && sel_item.length == 1 ? pgBrowser.tree.itemData(sel_item) : undefined, + itemData = sel_item ? pgBrowser.tree.itemData(sel_item) : undefined, sel_node = itemData && pgBrowser.Nodes[itemData._type]; if (e.button.element.name == 'dialog_help' || e.button.element.name == 'object_help') { @@ -325,7 +324,7 @@ define([ if (!itemData) return; - var node_hierarchy = sel_node.getTreeNodeHierarchy.apply(sel_node, [sel_item]); + var node_hierarchy = pgBrowser.tree.getTreeNodeHierarchy(sel_item); if (node_hierarchy.schema != undefined) { schema = node_hierarchy.schema._label; @@ -409,13 +408,13 @@ define([ var $container = $('
'); var tree = pgBrowser.tree, sel_item = tree.selected(), - itemInfo = sel_item && sel_item.length == 1 ? tree.itemData(sel_item) : undefined, + itemInfo = sel_item ? tree.itemData(sel_item) : undefined, nodeData = itemInfo && pgBrowser.Nodes[itemInfo._type]; if (!itemInfo) return; - var treeData = nodeData.getTreeNodeHierarchy.apply(nodeData, [sel_item]); + var treeData = tree.getTreeNodeHierarchy(sel_item); var newModel = new MaintenanceModel({}, { node_info: treeData, diff --git a/web/pgadmin/tools/psql/static/js/psql_module.js b/web/pgadmin/tools/psql/static/js/psql_module.js index bee77a146..5acba3b1b 100644 --- a/web/pgadmin/tools/psql/static/js/psql_module.js +++ b/web/pgadmin/tools/psql/static/js/psql_module.js @@ -18,7 +18,6 @@ import {getRandomInt, hasBinariesConfiguration, registerDetachEvent} from 'sourc import {retrieveAncestorOfTypeServer} from 'sources/tree/tree_utils'; import pgWindow from 'sources/window'; -import {getTreeNodeHierarchyFromIdentifier} from 'sources/tree/pgadmin_tree_node'; import {generateTitle, refresh_db_node} from 'tools/datagrid/static/js/datagrid_panel_title'; @@ -120,7 +119,7 @@ export function initialize(gettext, url_for, $, _, pgAdmin, csrfToken, Browser) return; } - const node = pgBrowser.treeMenu.findNodeByDomElement(aciTreeIdentifier); + const node = pgBrowser.tree.findNodeByDomElement(aciTreeIdentifier); if (node === undefined || !node.getData()) { Alertify.alert( gettext('PSQL Error'), @@ -129,10 +128,7 @@ export function initialize(gettext, url_for, $, _, pgAdmin, csrfToken, Browser) return; } - parentData = getTreeNodeHierarchyFromIdentifier.call( - pgBrowser, - aciTreeIdentifier - ); + parentData = pgBrowser.tree.getTreeNodeHierarchy(aciTreeIdentifier); if(_.isUndefined(parentData.server)) { Alertify.alert( @@ -366,9 +362,9 @@ export function initialize(gettext, url_for, $, _, pgAdmin, csrfToken, Browser) check_db_name_change: function(db_name, o_db_name) { if (db_name != o_db_name) { - var selected_item = pgWindow.pgAdmin.Browser.treeMenu.selected(), - tree_data = pgWindow.pgAdmin.Browser.treeMenu.translateTreeNodeIdFromACITree(selected_item), - database_data = pgWindow.pgAdmin.Browser.treeMenu.findNode(tree_data.slice(0,4)), + var selected_item = pgWindow.pgAdmin.Browser.tree.selected(), + tree_data = pgWindow.pgAdmin.Browser.tree.translateTreeNodeIdFromReactTree(selected_item), + database_data = pgWindow.pgAdmin.Browser.tree.findNode(tree_data[3]), dbNode = database_data.domNode; var message = `Current database has been moved or renamed to ${o_db_name}. Click on the OK button to refresh the database name, and reopen the psql again.`; diff --git a/web/pgadmin/tools/restore/static/js/restore.js b/web/pgadmin/tools/restore/static/js/restore.js index b0d43f9e5..50bd63dc5 100644 --- a/web/pgadmin/tools/restore/static/js/restore.js +++ b/web/pgadmin/tools/restore/static/js/restore.js @@ -271,8 +271,8 @@ define('tools.restore', [ visible: function() { var t = pgBrowser.tree, i = t.selected(), - d = i && i.length == 1 ? t.itemData(i) : undefined, - s = _.isUndefined(d) ? undefined : pgBrowser.Nodes[d._type].getTreeNodeHierarchy(i)['server']; + d = i ? t.itemData(i) : undefined, + s = _.isUndefined(d) ? undefined : pgBrowser.tree.getTreeNodeHierarchy(i)['server']; return _.isUndefined(s) ? false : s.version >= 110000; }, @@ -396,7 +396,7 @@ define('tools.restore', [ label: gettext('Restore...'), icon: 'fa fa-upload', enable: supportedNodes.enabled.bind( - null, pgBrowser.treeMenu, menuUtils.restoreSupportedNodes + null, pgBrowser.tree, menuUtils.restoreSupportedNodes ), data: { data_disabled: gettext('Please select any schema or table from the browser tree to Restore data.'), @@ -414,7 +414,7 @@ define('tools.restore', [ label: gettext('Restore...'), icon: 'fa fa-upload', enable: supportedNodes.enabled.bind( - null, pgBrowser.treeMenu, menuUtils.restoreSupportedNodes + null, pgBrowser.tree, menuUtils.restoreSupportedNodes ), }); } diff --git a/web/pgadmin/tools/restore/static/js/restore_dialog.js b/web/pgadmin/tools/restore/static/js/restore_dialog.js index 20a22aa8d..f2e95caec 100644 --- a/web/pgadmin/tools/restore/static/js/restore_dialog.js +++ b/web/pgadmin/tools/restore/static/js/restore_dialog.js @@ -57,8 +57,8 @@ export class RestoreDialog extends Dialog { return; } - let aciTreeItem1 = aciTreeItem || that.pgBrowser.treeMenu.selected(); - let item = that.pgBrowser.treeMenu.findNodeByDomElement(aciTreeItem1); + let aciTreeItem1 = aciTreeItem || that.pgBrowser.tree.selected(); + let item = that.pgBrowser.tree.findNodeByDomElement(aciTreeItem1); const data = item.getData(); const node = that.pgBrowser.Nodes[data._type]; diff --git a/web/pgadmin/tools/restore/static/js/restore_dialog_wrapper.js b/web/pgadmin/tools/restore/static/js/restore_dialog_wrapper.js index c9cda5d66..ee57cb2f9 100644 --- a/web/pgadmin/tools/restore/static/js/restore_dialog_wrapper.js +++ b/web/pgadmin/tools/restore/static/js/restore_dialog_wrapper.js @@ -7,7 +7,6 @@ // ////////////////////////////////////////////////////////////// -import {getTreeNodeHierarchyFromElement} from '../../../../static/js/tree/pgadmin_tree_node'; import axios from 'axios/index'; import _ from 'underscore'; import gettext from '../../../../static/js/gettext'; @@ -93,8 +92,7 @@ export class RestoreDialogWrapper extends DialogWrapper { } const node = this.pgBrowser.Nodes[selectedTreeNodeData._type]; - - const treeInfo = getTreeNodeHierarchyFromElement(this.pgBrowser, selectedTreeNode); + const treeInfo = this.pgBrowser.tree.getTreeNodeHierarchy(selectedTreeNode); const dialog = this.createDialog(node, treeInfo, $container); this.addAlertifyClassToRestoreNodeChildNodes(); dialog.render(); @@ -149,10 +147,7 @@ export class RestoreDialogWrapper extends DialogWrapper { 'sid': serverIdentifier, }); - const treeInfo = getTreeNodeHierarchyFromElement( - this.pgBrowser, - selectedTreeNode - ); + const treeInfo = this.pgBrowser.tree.getTreeNodeHierarchy(selectedTreeNode); this.setExtraParameters(selectedTreeNode, treeInfo); @@ -190,7 +185,7 @@ export class RestoreDialogWrapper extends DialogWrapper { } getSelectedNode() { - const tree = this.pgBrowser.treeMenu; + const tree = this.pgBrowser.tree; const selectedNode = tree.selected(); if (selectedNode) { return tree.findNodeByDomElement(selectedNode); @@ -225,10 +220,7 @@ export class RestoreDialogWrapper extends DialogWrapper { } retrieveServerIdentifier(node, selectedTreeNode) { - const treeInfo = getTreeNodeHierarchyFromElement( - this.pgBrowser, - selectedTreeNode - ); + const treeInfo = this.pgBrowser.tree.getTreeNodeHierarchy(selectedTreeNode); return treeInfo.server._id; } diff --git a/web/pgadmin/tools/search_objects/static/js/search_objects_dialog_wrapper.js b/web/pgadmin/tools/search_objects/static/js/search_objects_dialog_wrapper.js index 2bec153d2..62d37edc1 100644 --- a/web/pgadmin/tools/search_objects/static/js/search_objects_dialog_wrapper.js +++ b/web/pgadmin/tools/search_objects/static/js/search_objects_dialog_wrapper.js @@ -1,4 +1,12 @@ -import {getTreeNodeHierarchyFromElement} from 'sources/tree/pgadmin_tree_node'; +///////////////////////////////////////////////////////////// +// +// pgAdmin 4 - PostgreSQL Tools +// +// Copyright (C) 2013 - 2021, The pgAdmin Development Team +// This software is released under the PostgreSQL Licence +// +////////////////////////////////////////////////////////////// + import axios from 'axios/index'; import gettext from 'sources/gettext'; import url_for from 'sources/url_for'; @@ -261,7 +269,7 @@ export default class SearchObjectsDialogWrapper extends DialogWrapper { this.grid.onDblClick.subscribe((event, args) => { let rowData = this.dataview.getItem(args.row); - let treeMenu = this.pgBrowser.treeMenu; + let tree = this.pgBrowser.tree; if(!rowData.show_node) { this.showMessage( @@ -278,9 +286,9 @@ export default class SearchObjectsDialogWrapper extends DialogWrapper { return false; } this.showMessage(gettext('Locating...')); - treeMenu.findNodeWithToggle(rowData.id_path) + tree.findNodeWithToggle(rowData.id_path) .then((treeItem)=>{ - treeMenu.selectNode(treeItem.domNode, true); + tree.select(treeItem, true); this.showMessage(null); }) .catch((error)=>{ @@ -349,7 +357,7 @@ export default class SearchObjectsDialogWrapper extends DialogWrapper { } getSelectedNode() { - const tree = this.pgBrowser.treeMenu; + const tree = this.pgBrowser.tree; const selectedNode = tree.selected(); if (selectedNode) { return tree.findNodeByDomElement(selectedNode); @@ -404,7 +412,7 @@ export default class SearchObjectsDialogWrapper extends DialogWrapper { let id_path = [ this.treeInfo.server_group.id, this.treeInfo.server.id, - this.getCollNode('database').type + '/' + this.treeInfo.server._id, + this.getCollNode('database').type + '_' + this.treeInfo.server._id, this.treeInfo.database.id, ]; @@ -435,10 +443,10 @@ export default class SearchObjectsDialogWrapper extends DialogWrapper { let coll_node = this.getCollNode(node_type); if(coll_node) { /* Add coll node to the path */ - if(prev_node_id != null) id_path.push(`${coll_node.type}/${prev_node_id}`); + if(prev_node_id != null) id_path.push(`${coll_node.type}_${prev_node_id}`); /* Add the node to the path */ - id_path.push(`${node_type}/${node_oid}`); + id_path.push(`${node_type}_${node_oid}`); /* This will be needed for coll node */ prev_node_id = node_oid; @@ -447,7 +455,7 @@ export default class SearchObjectsDialogWrapper extends DialogWrapper { return `/${coll_node.label}/`; } else if(node_type in this.pgBrowser.Nodes) { /* Add the node to the path */ - id_path.push(`${node_type}/${node_oid}`); + id_path.push(`${node_type}_${node_oid}`); /* This will be need for coll node id path */ prev_node_id = node_oid; @@ -652,7 +660,7 @@ export default class SearchObjectsDialogWrapper extends DialogWrapper { return; } - this.treeInfo = getTreeNodeHierarchyFromElement(this.pgBrowser, selectedTreeNode); + this.treeInfo = this.pgBrowser.tree.getTreeNodeHierarchy(selectedTreeNode); this.prepareDialog(); this.focusOnDialog(this); } diff --git a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js index f221161eb..a641ecba8 100644 --- a/web/pgadmin/tools/sqleditor/static/js/sqleditor.js +++ b/web/pgadmin/tools/sqleditor/static/js/sqleditor.js @@ -2720,26 +2720,20 @@ define('tools.querytool', [ $('#btn-conn-status i').removeClass('obtaining-conn'); - var tree_data = pgWindow.default.pgAdmin.Browser.treeMenu.translateTreeNodeIdFromACITree(pgWindow.default.pgAdmin.Browser.treeMenu.selected()); - - var server_data = pgWindow.default.pgAdmin.Browser.treeMenu.findNode(tree_data.slice(0,2)); - var database_data = pgWindow.default.pgAdmin.Browser.treeMenu.findNode(tree_data.slice(0,4)); - var dbData = tree_data.slice(0,3); - dbData.push('database/' + url_params.did); - var dbName = pgWindow.default.pgAdmin.Browser.treeMenu.findNode(dbData).data.label; - let conn_title = panelTitleFunc.getPanelTitle(pgWindow.default.pgAdmin.Browser, null, null, null, true, dbName); + var tree_data = pgWindow.default.pgAdmin.Browser.tree.getTreeNodeHierarchy(pgWindow.default.pgAdmin.Browser.tree.selected()); + let conn_title = panelTitleFunc.getPanelTitle(pgWindow.default.pgAdmin.Browser, null, null, null, true, tree_data.database.label); 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': server_data.data.user.name, + '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(database_data.data.label), - 'server_name': _.unescape(server_data.data.label), + 'database_name': _.unescape(tree_data.database.label), + 'server_name': _.unescape(tree_data.server.label), 'is_selected': true, }; delete connection_data.password; @@ -5171,10 +5165,10 @@ define('tools.querytool', [ var self = this; - var selected_item = pgWindow.default.pgAdmin.Browser.treeMenu.selected(), - tree_data = pgWindow.default.pgAdmin.Browser.treeMenu.translateTreeNodeIdFromACITree(selected_item), - server_data = pgWindow.default.pgAdmin.Browser.treeMenu.findNode(tree_data.slice(0,2)), - database_data = pgWindow.default.pgAdmin.Browser.treeMenu.findNode(tree_data.slice(0,4)), + 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; diff --git a/web/regression/javascript/backup/backup_dialog_spec.js b/web/regression/javascript/backup/backup_dialog_spec.js index 8793e0976..2ac646760 100644 --- a/web/regression/javascript/backup/backup_dialog_spec.js +++ b/web/regression/javascript/backup/backup_dialog_spec.js @@ -22,7 +22,6 @@ describe('BackupDialog', () => { beforeEach(() => { pgBrowser = { - treeMenu: new TreeFake(), Nodes: { server: { hasId: true, @@ -53,6 +52,7 @@ describe('BackupDialog', () => { default: 550, }, }; + pgBrowser.tree = new TreeFake(pgBrowser); pgBrowser.Nodes.server.hasId = true; pgBrowser.Nodes.database.hasId = true; jquerySpy = jasmine.createSpy('jquerySpy'); @@ -126,7 +126,7 @@ describe('BackupDialog', () => { ], }; - pgBrowser.treeMenu = TreeFake.build(hierarchy); + pgBrowser.tree = TreeFake.build(hierarchy, pgBrowser); }); describe('#draw', () => { @@ -151,7 +151,7 @@ describe('BackupDialog', () => { context('there are no ancestors of the type server', () => { it('does not create a dialog', () => { - pgBrowser.treeMenu.selectNode([{id: 'root'}]); + pgBrowser.tree.selectNode([{id: 'root'}]); backupDialog.draw(null, null, null); expect(alertifySpy['backup_objects']).not.toHaveBeenCalled(); }); diff --git a/web/regression/javascript/backup/backup_dialog_wrapper_spec.js b/web/regression/javascript/backup/backup_dialog_wrapper_spec.js index 1fcb44c04..e3c91ecea 100644 --- a/web/regression/javascript/backup/backup_dialog_wrapper_spec.js +++ b/web/regression/javascript/backup/backup_dialog_wrapper_spec.js @@ -12,7 +12,7 @@ import {BackupDialogWrapper} from '../../../pgadmin/tools/backup/static/js/backu import axios from 'axios/index'; import MockAdapter from 'axios-mock-adapter'; import {FakeModel} from '../fake_model'; -import {TreeNode} from '../../../pgadmin/static/js/tree/tree'; +import {TreeNode} from '../../../pgadmin/static/js/tree/tree_nodes'; let context = describe; @@ -34,7 +34,6 @@ describe('BackupDialogWrapper', () => { beforeEach(() => { pgBrowser = { - treeMenu: new TreeFake(), Nodes: { server: { hasId: true, @@ -47,8 +46,10 @@ describe('BackupDialogWrapper', () => { keyboardNavigation: jasmine.createSpyObj('keyboardNavigation', ['getDialogTabNavigator']), }; - noDataNode = pgBrowser.treeMenu.addNewNode('level1.1', undefined, [{id: 'level1'}]); - serverTreeNode = pgBrowser.treeMenu.addNewNode('level2.1', { + pgBrowser.tree = new TreeFake(pgBrowser); + + noDataNode = pgBrowser.tree.addNewNode('level1.1', undefined, [{id: 'level1'}]); + serverTreeNode = pgBrowser.tree.addNewNode('level2.1', { _type: 'server', _id: 10, label: 'some-tree-label', @@ -57,7 +58,7 @@ describe('BackupDialogWrapper', () => { _type: 'database', _label: 'some-database-label', }, [{id: 'database-tree-node'}]); - pgBrowser.treeMenu.addChild(serverTreeNode, databaseTreeNode); + pgBrowser.tree.addChild(serverTreeNode, databaseTreeNode); jquerySpy = jasmine.createSpy('jquerySpy'); backupNode = { @@ -132,7 +133,7 @@ describe('BackupDialogWrapper', () => { context('selected tree node has no data', () => { beforeEach(() => { - pgBrowser.treeMenu.selectNode(noDataNode.domNode); + pgBrowser.tree.selectNode(noDataNode.domNode); }); it('does not create a backform dialog', () => { @@ -159,7 +160,7 @@ describe('BackupDialogWrapper', () => { label: 'some-tree-label', }, }; - pgBrowser.treeMenu.selectNode(serverTreeNode.domNode); + pgBrowser.tree.selectNode(serverTreeNode.domNode); pgBrowser.Nodes['server'].getTreeNodeHierarchy.and .returnValue(treeHierarchyInformation); dialogSpy = jasmine.createSpyObj('newView', ['render']); @@ -238,7 +239,7 @@ describe('BackupDialogWrapper', () => { networkCalled = true; return [200, {}]; }); - pgBrowser.treeMenu.selectNode(serverTreeNode.domNode); + pgBrowser.tree.selectNode(serverTreeNode.domNode); pgBrowser.showHelp = jasmine.createSpy('showHelp'); const event = { @@ -278,7 +279,7 @@ describe('BackupDialogWrapper', () => { networkCalled = true; return [200, {}]; }); - pgBrowser.treeMenu.selectNode(serverTreeNode.domNode); + pgBrowser.tree.selectNode(serverTreeNode.domNode); pgBrowser.showHelp = jasmine.createSpy('showHelp'); const event = { @@ -337,7 +338,7 @@ describe('BackupDialogWrapper', () => { context('tree node has no data', () => { it('does not start the backup', () => { - pgBrowser.treeMenu.selectNode(noDataNode.domNode); + pgBrowser.tree.selectNode(noDataNode.domNode); let networkCalled = false; networkMock.onAny(/.*/).reply(() => { @@ -365,7 +366,7 @@ describe('BackupDialogWrapper', () => { context('when dialog type is global', () => { let event; beforeEach(() => { - pgBrowser.treeMenu.selectNode(serverTreeNode.domNode); + pgBrowser.tree.selectNode(serverTreeNode.domNode); backupDialogWrapper.view = { model: new FakeModel(), @@ -465,7 +466,7 @@ describe('BackupDialogWrapper', () => { backform ); - pgBrowser.treeMenu.selectNode(databaseTreeNode.domNode); + pgBrowser.tree.selectNode(databaseTreeNode.domNode); backupDialogWrapper.view = { model: new FakeModel(), diff --git a/web/regression/javascript/backup/global_server_backup_dialog_spec.js b/web/regression/javascript/backup/global_server_backup_dialog_spec.js index 8497e7a71..b16dfa33e 100644 --- a/web/regression/javascript/backup/global_server_backup_dialog_spec.js +++ b/web/regression/javascript/backup/global_server_backup_dialog_spec.js @@ -26,7 +26,6 @@ describe('GlobalServerBackupDialog', () => { beforeEach(() => { pgBrowser = { - treeMenu: new TreeFake(), Nodes: { server: jasmine.createSpyObj('Node[server]', ['getTreeNodeHierarchy']), }, @@ -43,35 +42,36 @@ describe('GlobalServerBackupDialog', () => { default: 550, }, }; + pgBrowser.tree = new TreeFake(pgBrowser); pgBrowser.Nodes.server.hasId = true; jquerySpy = jasmine.createSpy('jquerySpy'); backupModelSpy = jasmine.createSpy('backupModelSpy'); - rootNode = pgBrowser.treeMenu.addNewNode('level1', {}, undefined, []); - serverTreeNode = pgBrowser.treeMenu.addNewNode('level1.1', { + rootNode = pgBrowser.tree.addNewNode('level1', {}, undefined, []); + serverTreeNode = pgBrowser.tree.addNewNode('level1.1', { _type: 'server', _id: 10, server_type: 'pg', version: 100000, }, undefined, ['level1']); - serverTreeNodeWrongPath = pgBrowser.treeMenu.addNewNode('level1.2', { + serverTreeNodeWrongPath = pgBrowser.tree.addNewNode('level1.2', { _type: 'server', _id: 11, server_type: 'pg', version: 90600, }, undefined, ['level1']); - ppasServerTreeNode = pgBrowser.treeMenu.addNewNode('level1.3', { + ppasServerTreeNode = pgBrowser.tree.addNewNode('level1.3', { _type: 'server', server_type: 'ppas', version: 130000, }, undefined, ['level1']); - ppasServerTreeNodeWrongPath = pgBrowser.treeMenu.addNewNode('level1.4', { + ppasServerTreeNodeWrongPath = pgBrowser.tree.addNewNode('level1.4', { _type: 'server', server_type: 'ppas', version: 90600, }, undefined, ['level1']); - pgBrowser.treeMenu.addNewNode('level3', {}, undefined, ['level1', 'level1.2', 'level1.3', 'level1.4']); - pgBrowser.treeMenu.addNewNode('level3.1', undefined, undefined, ['level1', 'level1.2', 'level3']); + pgBrowser.tree.addNewNode('level3', {}, undefined, ['level1', 'level1.2', 'level1.3', 'level1.4']); + pgBrowser.tree.addNewNode('level3.1', undefined, undefined, ['level1', 'level1.2', 'level3']); }); describe('#draw', () => { @@ -97,7 +97,7 @@ describe('GlobalServerBackupDialog', () => { context('there are no ancestors of the type server', () => { it('does not create a dialog', () => { - pgBrowser.treeMenu.selectNode([{id: 'level1'}]); + pgBrowser.tree.selectNode([{id: 'level1'}]); backupDialog.draw(null, null, null); expect(alertifySpy['BackupDialog_globals']).not.toHaveBeenCalled(); expect(alertifySpy['BackupDialog_server']).not.toHaveBeenCalled(); diff --git a/web/regression/javascript/datagrid/get_panel_title_spec.js b/web/regression/javascript/datagrid/get_panel_title_spec.js index 28d2a4609..ed295be11 100644 --- a/web/regression/javascript/datagrid/get_panel_title_spec.js +++ b/web/regression/javascript/datagrid/get_panel_title_spec.js @@ -9,7 +9,7 @@ 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'; +import {TreeNode} from '../../../pgadmin/static/js/tree/tree_nodes'; import {pgBrowser} from 'pgadmin.browser.preferences'; const context = describe; @@ -28,7 +28,6 @@ describe('#getPanelTitle', () => { let tree; beforeEach(() => { pgBrowser.preferences_cache = dummy_cache; - tree = new TreeFake(); pgBrowser.Nodes = { server: { hasId: true, @@ -39,10 +38,11 @@ describe('#getPanelTitle', () => { _type: 'database', }, }; - pgBrowser.treeMenu = tree; pgBrowser.preferences = { 'qt_tab_title_placeholder': '', }; + tree = new TreeFake(pgBrowser); + pgBrowser.tree = tree; }); context('selected node does not belong to a server', () => { diff --git a/web/regression/javascript/datagrid/show_data_spec.js b/web/regression/javascript/datagrid/show_data_spec.js index a5c5e9323..13cd96c56 100644 --- a/web/regression/javascript/datagrid/show_data_spec.js +++ b/web/regression/javascript/datagrid/show_data_spec.js @@ -9,7 +9,7 @@ import {showDataGrid} from '../../../pgadmin/tools/datagrid/static/js/show_data'; import {TreeFake} from '../tree/tree_fake'; -import {TreeNode} from '../../../pgadmin/static/js/tree/tree'; +import {TreeNode} from '../../../pgadmin/static/js/tree/tree_nodes'; import {pgBrowser} from 'pgadmin.browser.preferences'; const context = describe; @@ -34,7 +34,6 @@ describe('#show_data', () => { datagrid = { launch_grid: jasmine.createSpy('launch_grid'), }; - pgBrowser.treeMenu = new TreeFake(); pgBrowser.Nodes = { server_group: { _type: 'server_group', @@ -61,12 +60,13 @@ describe('#show_data', () => { hasId: true, }, }; - const parent = pgBrowser.treeMenu.addNewNode('parent', {_type: 'parent'}, []); + 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.treeMenu.addChild(parent, serverGroup1); + pgBrowser.tree.addChild(parent, serverGroup1); const server1 = new TreeNode('server1', { _type: 'server', @@ -75,35 +75,35 @@ describe('#show_data', () => { _id: 2, user: {name: 'someuser'}, }, ['parent', 'server_group1']); - pgBrowser.treeMenu.addChild(serverGroup1, server1); + pgBrowser.tree.addChild(serverGroup1, server1); const database1 = new TreeNode('database1', { _type: 'database', label: 'database1', _id: 3, }, ['parent', 'server_group1', 'server1']); - pgBrowser.treeMenu.addChild(server1, database1); + pgBrowser.tree.addChild(server1, database1); const schema1 = new TreeNode('schema1', { _type: 'schema', label: 'schema1', _id: 4, }); - pgBrowser.treeMenu.addChild(database1, schema1); + pgBrowser.tree.addChild(database1, schema1); const view1 = new TreeNode('view1', { _type: 'view', label: 'view1', _id: 5, }, ['parent', 'server_group1', 'server1', 'database1']); - pgBrowser.treeMenu.addChild(database1, view1); + pgBrowser.tree.addChild(database1, view1); const catalog1 = new TreeNode('catalog1', { _type: 'catalog', label: 'catalog1', _id: 6, }, ['parent', 'server_group1', 'server1', 'database1']); - pgBrowser.treeMenu.addChild(database1, catalog1); + pgBrowser.tree.addChild(database1, catalog1); }); context('cannot find the tree node', () => { diff --git a/web/regression/javascript/datagrid/show_query_tool_spec.js b/web/regression/javascript/datagrid/show_query_tool_spec.js index 33f6b00f8..8938bb00e 100644 --- a/web/regression/javascript/datagrid/show_query_tool_spec.js +++ b/web/regression/javascript/datagrid/show_query_tool_spec.js @@ -9,7 +9,7 @@ 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'; +import {TreeNode} from '../../../pgadmin/static/js/tree/tree_nodes'; import {pgBrowser} from 'pgadmin.browser.preferences'; const context = describe; @@ -34,7 +34,6 @@ describe('#showQueryTool', () => { queryTool = { launch_grid: jasmine.createSpy('launch_grid'), }; - pgBrowser.treeMenu = new TreeFake(); pgBrowser.Nodes = { server_group: { _type: 'server_group', @@ -49,13 +48,14 @@ describe('#showQueryTool', () => { hasId: true, }, }; + pgBrowser.tree = new TreeFake(pgBrowser); - const parent = pgBrowser.treeMenu.addNewNode('parent', {_type: 'parent'}); + const parent = pgBrowser.tree.addNewNode('parent', {_type: 'parent'}); const serverGroup1 = new TreeNode('server_group1', { _type: 'server_group', _id: 1, }, ['parent']); - pgBrowser.treeMenu.addChild(parent, serverGroup1); + pgBrowser.tree.addChild(parent, serverGroup1); const server1 = new TreeNode('server1', { _type: 'server', @@ -65,14 +65,14 @@ describe('#showQueryTool', () => { user: {name: 'someuser'}, db: 'otherdblabel', }); - pgBrowser.treeMenu.addChild(serverGroup1, server1); + pgBrowser.tree.addChild(serverGroup1, server1); const database1 = new TreeNode('database1', { _type: 'database', label: 'database1', _id: 3, }); - pgBrowser.treeMenu.addChild(server1, database1); + pgBrowser.tree.addChild(server1, database1); }); context('cannot find the tree node', () => { diff --git a/web/regression/javascript/misc/statistics/statistics_spec.js b/web/regression/javascript/misc/statistics/statistics_spec.js index 4fe2b1af3..79f5af52f 100644 --- a/web/regression/javascript/misc/statistics/statistics_spec.js +++ b/web/regression/javascript/misc/statistics/statistics_spec.js @@ -15,7 +15,7 @@ describe('#nodeHasStatistics', () => { const node = { hasStatistics: true, }; - expect(nodeHasStatistics(node, {})).toEqual(true); + expect(nodeHasStatistics({}, node, {})).toEqual(true); }); }); @@ -24,12 +24,16 @@ describe('#nodeHasStatistics', () => { it('returns true', () => { const node = { hasStatistics: () => true, - getTreeNodeHierarchy: jasmine.createSpy(), + }; + const pgBrowser = { + tree: { + getTreeNodeHierarchy: jasmine.createSpy(), + } }; const item = {}; - expect(nodeHasStatistics(node, item)).toEqual(true); - expect(node.getTreeNodeHierarchy).toHaveBeenCalledWith(item); + expect(nodeHasStatistics(pgBrowser, node, item)).toEqual(true); + expect(pgBrowser.tree.getTreeNodeHierarchy).toHaveBeenCalledWith(item); }); }); }); diff --git a/web/regression/javascript/nodes/schema/child_menu_spec.js b/web/regression/javascript/nodes/schema/child_menu_spec.js index 61acb01c3..23952f241 100644 --- a/web/regression/javascript/nodes/schema/child_menu_spec.js +++ b/web/regression/javascript/nodes/schema/child_menu_spec.js @@ -10,13 +10,14 @@ import { isTreeItemOfChildOfSchema, childCreateMenuEnabled, } from 'pgadmin.schema.dir/schema_child_tree_node'; - -import * as pgBrowser from 'pgbrowser/browser'; +import pgAdmin from 'sources/pgadmin'; import {TreeFake} from '../../tree/tree_fake'; + describe('#childCreateMenuEnabled', () => { - let data; - let tree; + let data, + tree, + pgBrowser = pgAdmin.Browser; describe(' - when data is not null', () => { beforeEach(() => { @@ -47,8 +48,8 @@ describe('#childCreateMenuEnabled', () => { }], }; - tree = TreeFake.build(hierarchy); - pgBrowser.treeMenu = tree; + tree = TreeFake.build(hierarchy, pgBrowser); + pgBrowser.tree = tree; }); it(' it is true', () => { expect(childCreateMenuEnabled( @@ -72,8 +73,8 @@ describe('#childCreateMenuEnabled', () => { }], }; - tree = TreeFake.build(hierarchy); - pgBrowser.treeMenu = tree; + tree = TreeFake.build(hierarchy, pgBrowser); + pgBrowser.tree = tree; }); it(' it is true', () => { @@ -101,8 +102,8 @@ describe('#childCreateMenuEnabled', () => { }], }; - tree = TreeFake.build(hierarchy); - pgBrowser.treeMenu = tree; + tree = TreeFake.build(hierarchy, pgBrowser); + pgBrowser.tree = tree; }); it(' it is true', () => { @@ -122,8 +123,8 @@ describe('#childCreateMenuEnabled', () => { }], }; - tree = TreeFake.build(hierarchy); - pgBrowser.treeMenu = tree; + tree = TreeFake.build(hierarchy, pgBrowser); + pgBrowser.tree = tree; }); it(' it is false', () => { expect( @@ -146,8 +147,8 @@ describe('#childCreateMenuEnabled', () => { }], }; - tree = TreeFake.build(hierarchy); - pgBrowser.treeMenu = tree; + tree = TreeFake.build(hierarchy, pgBrowser); + pgBrowser.tree = tree; }); it(' it is false', () => { @@ -175,8 +176,8 @@ describe('#childCreateMenuEnabled', () => { }], }; - tree = TreeFake.build(hierarchy); - pgBrowser.treeMenu = tree; + tree = TreeFake.build(hierarchy, pgBrowser); + pgBrowser.tree = tree; }); it(' it is false', () => { @@ -191,7 +192,9 @@ describe('#childCreateMenuEnabled', () => { }); describe('#childDropMenuEnabled', () => { - let tree; + let tree, + pgBrowser = pgAdmin.Browser; + describe(' - the child node under schema node ', () => { beforeEach(() => { @@ -211,8 +214,8 @@ describe('#childDropMenuEnabled', () => { }], }; - tree = TreeFake.build(hierarchy); - pgBrowser.treeMenu = tree; + tree = TreeFake.build(hierarchy, pgBrowser); + pgBrowser.tree = tree; }); it(' it is true', () => { @@ -240,8 +243,8 @@ describe('#childDropMenuEnabled', () => { }], }; - tree = TreeFake.build(hierarchy); - pgBrowser.treeMenu = tree; + tree = TreeFake.build(hierarchy, pgBrowser); + pgBrowser.tree = tree; }); it(' it is false', () => { diff --git a/web/regression/javascript/restore/restore_dialog_spec.js b/web/regression/javascript/restore/restore_dialog_spec.js index c77f3775a..a62dc82fa 100644 --- a/web/regression/javascript/restore/restore_dialog_spec.js +++ b/web/regression/javascript/restore/restore_dialog_spec.js @@ -22,7 +22,7 @@ describe('RestoreDialog', () => { beforeEach(() => { pgBrowser = { - treeMenu: new TreeFake(), + tree: new TreeFake(), Nodes: { server: jasmine.createSpyObj('Node[server]', ['getTreeNodeHierarchy']), database: jasmine.createSpyObj('Node[database]', ['getTreeNodeHierarchy']), @@ -113,7 +113,7 @@ describe('RestoreDialog', () => { ], }; - pgBrowser.treeMenu = TreeFake.build(hierarchy); + pgBrowser.tree = TreeFake.build(hierarchy, pgBrowser); }); describe('#draw', () => { @@ -138,7 +138,7 @@ describe('RestoreDialog', () => { context('there are no ancestors of the type server', () => { it('does not create a dialog', () => { - pgBrowser.treeMenu.selectNode([{id: 'root'}]); + pgBrowser.tree.selectNode([{id: 'root'}]); restoreDialog.draw(null, null, null); expect(alertifySpy['pg_restore']).not.toHaveBeenCalled(); }); diff --git a/web/regression/javascript/restore/restore_dialog_wrapper_spec.js b/web/regression/javascript/restore/restore_dialog_wrapper_spec.js index a328bb5be..cde9b145c 100644 --- a/web/regression/javascript/restore/restore_dialog_wrapper_spec.js +++ b/web/regression/javascript/restore/restore_dialog_wrapper_spec.js @@ -11,7 +11,7 @@ import {RestoreDialogWrapper} from '../../../pgadmin/tools/restore/static/js/res import MockAdapter from 'axios-mock-adapter'; import axios from 'axios/index'; import {FakeModel} from '../fake_model'; -import {TreeNode} from '../../../pgadmin/static/js/tree/tree'; +import {TreeNode} from '../../../pgadmin/static/js/tree/tree_nodes'; let context = describe; @@ -32,7 +32,6 @@ describe('RestoreDialogWrapper', () => { beforeEach(() => { pgBrowser = { - treeMenu: new TreeFake(), Nodes: { server: { hasId: true, @@ -41,9 +40,10 @@ describe('RestoreDialogWrapper', () => { }, keyboardNavigation: jasmine.createSpyObj('keyboardNavigation', ['getDialogTabNavigator']), }; + pgBrowser.tree = new TreeFake(pgBrowser); - noDataNode = pgBrowser.treeMenu.addNewNode('level1.1', undefined, [{id: 'level1'}]); - serverTreeNode = pgBrowser.treeMenu.addNewNode('level2.1', { + noDataNode = pgBrowser.tree.addNewNode('level1.1', undefined, [{id: 'level1'}]); + serverTreeNode = pgBrowser.tree.addNewNode('level2.1', { _type: 'server', _id: 10, label: 'some-tree-label', @@ -123,7 +123,7 @@ describe('RestoreDialogWrapper', () => { context('selected tree node has no data', () => { beforeEach(() => { - pgBrowser.treeMenu.selectNode(noDataNode.domNode); + pgBrowser.tree.selectNode(noDataNode.domNode); }); it('does not create a backform dialog', () => { @@ -149,7 +149,7 @@ describe('RestoreDialogWrapper', () => { label: 'some-tree-label', }, }; - pgBrowser.treeMenu.selectNode(serverTreeNode.domNode); + pgBrowser.tree.selectNode(serverTreeNode.domNode); pgBrowser.Nodes['server'].getTreeNodeHierarchy.and .returnValue(treeHierarchyInformation); dialogSpy = jasmine.createSpyObj('newView', ['render']); @@ -226,7 +226,7 @@ describe('RestoreDialogWrapper', () => { let networkCalled; beforeEach(() => { networkCalled = false; - pgBrowser.treeMenu.selectNode(serverTreeNode.domNode); + pgBrowser.tree.selectNode(serverTreeNode.domNode); networkMock.onAny(/.+/).reply(() => { networkCalled = true; return [200, {}]; @@ -267,7 +267,7 @@ describe('RestoreDialogWrapper', () => { let networkCalled; beforeEach(() => { networkCalled = false; - pgBrowser.treeMenu.selectNode(serverTreeNode.domNode); + pgBrowser.tree.selectNode(serverTreeNode.domNode); networkMock.onAny(/.+/).reply(() => { networkCalled = true; return [200, {}]; @@ -350,7 +350,7 @@ describe('RestoreDialogWrapper', () => { }, }, }; - pgBrowser.treeMenu.selectNode(noDataNode.domNode); + pgBrowser.tree.selectNode(noDataNode.domNode); }); it('does not start the restore', () => { @@ -364,12 +364,12 @@ describe('RestoreDialogWrapper', () => { let databaseTreeNode; beforeEach(() => { - databaseTreeNode = pgBrowser.treeMenu.addNewNode('level3.1', { + databaseTreeNode = pgBrowser.tree.addNewNode('level3.1', { _type: 'database', _id: 10, _label: 'some-database-label', }, [{id: 'level3.1'}]); - pgBrowser.treeMenu.addChild(serverTreeNode, databaseTreeNode); + pgBrowser.tree.addChild(serverTreeNode, databaseTreeNode); pgBrowser.Nodes.database = { hasId: true, _label: 'some-database-label', @@ -379,7 +379,7 @@ describe('RestoreDialogWrapper', () => { restoreDialogWrapper.view = { model: fakeModel, }; - pgBrowser.treeMenu.selectNode(databaseTreeNode.domNode); + pgBrowser.tree.selectNode(databaseTreeNode.domNode); pgBrowser.Events = jasmine.createSpyObj('pgBrowserEventsSpy', ['trigger']); event = { button: { diff --git a/web/regression/javascript/search_objects/search_objects_dialog_spec.js b/web/regression/javascript/search_objects/search_objects_dialog_spec.js index 465d4152c..eec5ddb0a 100644 --- a/web/regression/javascript/search_objects/search_objects_dialog_spec.js +++ b/web/regression/javascript/search_objects/search_objects_dialog_spec.js @@ -32,7 +32,6 @@ describe('SearchObjectsDialog', () => { beforeEach(() => { pgBrowser.preferences_cache = dummy_cache; - pgBrowser.treeMenu = new TreeFake(); pgBrowser.Nodes = { server: { hasId: true, @@ -50,7 +49,7 @@ describe('SearchObjectsDialog', () => { getTreeNodeHierarchy: jasmine.createSpy('db.getTreeNodeHierarchy'), }, }; - + pgBrowser.tree = new TreeFake(pgBrowser); pgBrowser.stdW = { sm: 500, md: 700, @@ -108,7 +107,7 @@ describe('SearchObjectsDialog', () => { ], }; - pgBrowser.treeMenu = TreeFake.build(hierarchy); + pgBrowser.tree = TreeFake.build(hierarchy, pgBrowser); }); describe('#draw', () => { @@ -137,7 +136,7 @@ describe('SearchObjectsDialog', () => { context('there are no ancestors of the type database', () => { it('does not create a dialog', () => { - pgBrowser.treeMenu.selectNode([{id: 'serverTreeNode'}]); + pgBrowser.tree.selectNode([{id: 'serverTreeNode'}]); soDialog.draw(null, null, null); expect(alertifySpy['search_objects']).not.toHaveBeenCalled(); }); diff --git a/web/regression/javascript/search_objects/search_objects_dialog_wrapper_spec.js b/web/regression/javascript/search_objects/search_objects_dialog_wrapper_spec.js index 9681b4671..ae0e7be35 100644 --- a/web/regression/javascript/search_objects/search_objects_dialog_wrapper_spec.js +++ b/web/regression/javascript/search_objects/search_objects_dialog_wrapper_spec.js @@ -11,7 +11,7 @@ import {TreeFake} from '../tree/tree_fake'; import SearchObjectsDialogWrapper from 'tools/search_objects/static/js/search_objects_dialog_wrapper'; import axios from 'axios/index'; import MockAdapter from 'axios-mock-adapter'; -import {TreeNode} from '../../../pgadmin/static/js/tree/tree'; +import {TreeNode} from '../../../pgadmin/static/js/tree/tree_nodes'; let context = describe; @@ -32,7 +32,6 @@ describe('SearchObjectsDialogWrapper', () => { beforeEach(() => { pgBrowser = { - treeMenu: new TreeFake(), Nodes: { server: { hasId: true, @@ -74,8 +73,9 @@ describe('SearchObjectsDialogWrapper', () => { }, keyboardNavigation: jasmine.createSpyObj('keyboardNavigation', ['getDialogTabNavigator']), }; - noDataNode = pgBrowser.treeMenu.addNewNode('level1.1', undefined, [{id: 'level1'}]); - serverTreeNode = pgBrowser.treeMenu.addNewNode('level2.1', { + pgBrowser.tree = new TreeFake(pgBrowser), + noDataNode = pgBrowser.tree.addNewNode('level1.1', undefined, [{id: 'level1'}]); + serverTreeNode = pgBrowser.tree.addNewNode('level2.1', { _type: 'server', _id: 10, label: 'some-tree-label', @@ -85,7 +85,7 @@ describe('SearchObjectsDialogWrapper', () => { _id: 123, _label: 'some-database-label', }, [{id: 'database-tree-node'}]); - pgBrowser.treeMenu.addChild(serverTreeNode, databaseTreeNode); + pgBrowser.tree.addChild(serverTreeNode, databaseTreeNode); jquerySpy = jasmine.createSpy('jquerySpy'); soNode = { @@ -153,7 +153,7 @@ describe('SearchObjectsDialogWrapper', () => { context('selected tree node has no data', () => { beforeEach(() => { - pgBrowser.treeMenu.selectNode(noDataNode.domNode); + pgBrowser.tree.selectNode(noDataNode.domNode); }); it('does not prepare the dialog', () => { @@ -168,7 +168,7 @@ describe('SearchObjectsDialogWrapper', () => { let networkMock; beforeEach(() => { - pgBrowser.treeMenu.selectNode(databaseTreeNode.domNode); + pgBrowser.tree.selectNode(databaseTreeNode.domNode); soDialogWrapper.grid = jasmine.createSpyObj('grid', ['destroy']); spyOn(soDialogWrapper, 'showMessage'); gridDestroySpy = spyOn(soDialogWrapper.grid, 'destroy'); @@ -503,9 +503,9 @@ describe('SearchObjectsDialogWrapper', () => { }; soDialogWrapper.treeInfo = { - 'server_group': {'id': 'server_group/1', '_id': 1}, - 'server': {'id': 'server/3', '_id': 3}, - 'database': {'id': 'database/18456', '_id': 18456}, + 'server_group': {'id': 'server_group_1', '_id': 1}, + 'server': {'id': 'server_3', '_id': 3}, + 'database': {'id': 'database_18456', '_id': 18456}, }; }); it('regular schema', ()=>{ @@ -515,7 +515,7 @@ describe('SearchObjectsDialogWrapper', () => { let retVal = soDialogWrapper.translateSearchObjectsPath(path, catalog_level); expect(retVal).toEqual([ 'Schemas/test_db/Tables/sampletab', - ['server_group/1','server/3','coll-database/3','database/18456','coll-schema/18456','schema/2200','coll-table/2200','table/2604'], + ['server_group_1','server_3','coll-database_3','database_18456','coll-schema_18456','schema_2200','coll-table_2200','table_2604'], ]); }); @@ -527,7 +527,7 @@ describe('SearchObjectsDialogWrapper', () => { let retVal = soDialogWrapper.translateSearchObjectsPath(path, catalog_level); expect(retVal).toEqual([ 'Catalogs/PostgreSQL Catalog (pg_catalog)/Tables/pg_class', - ['server_group/1','server/3','coll-database/3','database/18456','coll-catalog/18456','catalog/11','coll-table/11','table/2604'], + ['server_group_1','server_3','coll-database_3','database_18456','coll-catalog_18456','catalog_11','coll-table_11','table_2604'], ]); }); @@ -538,7 +538,7 @@ describe('SearchObjectsDialogWrapper', () => { let retVal = soDialogWrapper.translateSearchObjectsPath(path, catalog_level); expect(retVal).toEqual([ 'Catalogs/ANSI (information_schema)/Catalog Objects/attributes', - ['server_group/1','server/3','coll-database/3','database/18456','coll-catalog/18456','catalog/11','coll-catalog_object/11','catalog_object/2604'], + ['server_group_1','server_3','coll-database_3','database_18456','coll-catalog_18456','catalog_11','coll-catalog_object_11','catalog_object_2604'], ]); }); }); diff --git a/web/regression/javascript/table/enable_disable_triggers_spec.js b/web/regression/javascript/table/enable_disable_triggers_spec.js index 8b4694ee5..ff8906ba8 100644 --- a/web/regression/javascript/table/enable_disable_triggers_spec.js +++ b/web/regression/javascript/table/enable_disable_triggers_spec.js @@ -14,7 +14,7 @@ import { disableTriggers, } from '../../../pgadmin/browser/server_groups/servers/databases/schemas/tables/static/js/enable_disable_triggers'; import {TreeFake} from '../tree/tree_fake'; -import {TreeNode} from '../../../pgadmin/static/js/tree/tree'; +import {TreeNode} from '../../../pgadmin/static/js/tree/tree_nodes'; describe('#enableTriggers', () => { let networkMock; @@ -24,6 +24,13 @@ describe('#enableTriggers', () => { beforeEach(() => { networkMock = new MockAdapter(axios); tree = new TreeFake(); + + spyOn(tree, 'unload').and.callFake(function() { + return new Promise((resolve)=>{ + resolve('Success!'); + }); + }); + const server1 = tree.addNewNode('server1', {_id: 1}, ['
  • server1
  • ']); const database1 = tree.addNewNode('database1', {_type: 'database'}, ['
  • database1
  • ']); tree.addChild(server1, database1); @@ -100,7 +107,7 @@ describe('#enableTriggers', () => { setTimeout(() => { expect(tree.selected()).toEqual(['
  • table1
  • ']); done(); - }, 20); + }, 30); }); it('call backend with the correct parameters', (done) => { @@ -171,6 +178,12 @@ describe('#disableTriggers', () => { alertify = jasmine.createSpyObj('alertify', ['success', 'error']); generateUrlSpy = jasmine.createSpy('generateUrl'); generateUrlSpy.and.returnValue('/some/place'); + spyOn(tree, 'unload').and.callFake(function() { + return new Promise((resolve)=>{ + resolve('Success!'); + }); + }); + }); describe('no node is selected', () => { diff --git a/web/regression/javascript/tree/pgadmin_tree_node_spec.js b/web/regression/javascript/tree/pgadmin_tree_node_spec.js deleted file mode 100644 index 967f07f09..000000000 --- a/web/regression/javascript/tree/pgadmin_tree_node_spec.js +++ /dev/null @@ -1,363 +0,0 @@ -////////////////////////////////////////////////////////////////////////// -// -// pgAdmin 4 - PostgreSQL Tools -// -// Copyright (C) 2013 - 2021, The pgAdmin Development Team -// This software is released under the PostgreSQL Licence -// -////////////////////////////////////////////////////////////////////////// - -import { - getTreeNodeHierarchyFromElement, - getTreeNodeHierarchyFromIdentifier, -} from '../../../pgadmin/static/js/tree/pgadmin_tree_node'; -import {TreeNode} from '../../../pgadmin/static/js/tree/tree'; -import {TreeFake} from './tree_fake'; - -const context = describe; - -describe('tree#node#getTreeNodeHierarchy', () => { - let browser; - let newTree; - beforeEach(() => { - newTree = new TreeFake(); - browser = { - Nodes: { - 'special one': {hasId: true}, - 'child special': {hasId: true}, - 'other type': {hasId: true}, - 'table': {hasId: true}, - 'partition': {hasId: true}, - 'no id': {hasId: false}, - }, - }; - browser.treeMenu = newTree; - }); - - context('getTreeNodeHierarchy is called with aciTreeNode object', () => { - describe('When the current node is root element', () => { - beforeEach(() => { - newTree.addNewNode('root', { - 'some key': 'some value', - '_type': 'special one', - }); - }); - - it('returns a object with the element type passed data and priority == 0', () => { - const result = getTreeNodeHierarchyFromIdentifier.bind(browser)([{id: 'root'}]); - expect(result).toEqual({ - 'special one': { - 'some key': 'some value', - '_type': 'special one', - 'priority': 0, - }, - }); - }); - }); - - describe('When the current node is not of a known type', () => { - beforeEach(() => { - newTree.addNewNode('root', { - 'some key': 'some value', - '_type': 'do not exist', - }, []); - }); - - it('returns a empty object', () => { - const result = getTreeNodeHierarchyFromIdentifier.bind(browser)('root'); - expect(result).toEqual({}); - }); - }); - - describe('When the current node type has no id', () => { - beforeEach(() => { - newTree.addNewNode('root', { - 'some key': 'some value', - '_type': 'no id', - }, []); - }); - - it('returns a empty object', () => { - const result = getTreeNodeHierarchyFromIdentifier.bind(browser)('root'); - expect(result).toEqual({}); - }); - }); - - describe('When the current node is at the second level', () => { - beforeEach(() => { - const root = newTree.addNewNode('root', { - 'some key': 'some value', - '_type': 'special one', - }); - const firstChild = new TreeNode('first child', { - 'some key': 'some other value', - '_type': 'child special', - }, ['root']); - newTree.addChild(root, firstChild); - }); - - it('returns a empty object', () => { - const result = getTreeNodeHierarchyFromIdentifier.bind(browser)([{id: 'first child'}]); - expect(result).toEqual({ - 'child special': { - 'some key': 'some other value', - '_type': 'child special', - 'priority': 0, - }, - 'special one': { - 'some key': 'some value', - '_type': 'special one', - 'priority': -1, - }, - }); - }); - }); - - context('When tree as "special type"', () => { - context('When "special type" have "other type"', () => { - context('When "other type" have "special type"', () => { - describe('When retrieving lead node', () => { - it('does not override previous node type data', () => { - const rootNode = newTree.addNewNode('root', { - 'some key': 'some value', - '_type': 'special one', - }, []); - - const level1 = new TreeNode('level 1', { - 'some key': 'some value', - '_type': 'other type', - }); - newTree.addChild(rootNode, level1); - - newTree.addChild(level1, new TreeNode('level 2', { - 'some key': 'expected value', - '_type': 'special one', - 'some other key': 'some other value', - })); - - const result = getTreeNodeHierarchyFromIdentifier.bind(browser)([{id: 'level 2'}]); - expect(result).toEqual({ - 'special one': { - 'some key': 'expected value', - '_type': 'special one', - 'some other key': 'some other value', - 'priority': 0, - }, - 'other type': { - 'some key': 'some value', - '_type': 'other type', - 'priority': -1, - }, - }); - }); - }); - }); - }); - }); - - context('When tree has table', () => { - context('when table has partition', () => { - it('returns table with partition parameters', () => { - const root = newTree.addNewNode('root', { - 'some key': 'some value', - '_type': 'special one', - }, []); - const level1 = new TreeNode('level 1', { - 'some key': 'some value', - '_type': 'table', - }); - newTree.addChild(root, level1); - newTree.addChild(level1, new TreeNode('level 2', { - 'some key': 'expected value', - '_type': 'partition', - 'some other key': 'some other value', - })); - - const result = getTreeNodeHierarchyFromIdentifier.bind(browser)([{id:'level 2'}]); - expect(result).toEqual({ - 'special one': { - 'some key': 'some value', - '_type': 'special one', - 'priority': -2, - }, - 'table': { - 'some key': 'some value', - '_type': 'table', - 'priority': -1, - }, - 'partition': { - 'some key': 'expected value', - 'some other key': 'some other value', - '_type': 'partition', - 'priority': 0, - }, - }); - }); - }); - }); - }); - - context('getTreeNodeHierarchy is called with TreeNode object', () => { - let treeNode; - describe('When the current node is root element', () => { - beforeEach(() => { - treeNode = newTree.addNewNode('root', { - 'some key': 'some value', - '_type': 'special one', - }, []); - }); - - it('returns a object with the element type passed data and priority == 0', () => { - const result = getTreeNodeHierarchyFromElement(browser, treeNode); - expect(result).toEqual({ - 'special one': { - 'some key': 'some value', - '_type': 'special one', - 'priority': 0, - }, - }); - }); - }); - - describe('When the current node is not of a known type', () => { - beforeEach(() => { - treeNode = newTree.addNewNode('root', { - 'some key': 'some value', - '_type': 'do not exist', - }, []); - }); - - it('returns a empty object', () => { - const result = getTreeNodeHierarchyFromElement(browser, treeNode); - expect(result).toEqual({}); - }); - }); - - describe('When the current node type has no id', () => { - beforeEach(() => { - treeNode = newTree.addNewNode('root', { - 'some key': 'some value', - '_type': 'no id', - }, []); - }); - - it('returns a empty object', () => { - const result = getTreeNodeHierarchyFromElement(browser, treeNode); - expect(result).toEqual({}); - }); - }); - - describe('When the current node is at the second level', () => { - beforeEach(() => { - const root = newTree.addNewNode('root', { - 'some key': 'some value', - '_type': 'special one', - }, []); - treeNode = new TreeNode('first child', { - 'some key': 'some other value', - '_type': 'child special', - }); - newTree.addChild(root, treeNode); - }); - - it('returns a empty object', () => { - const result = getTreeNodeHierarchyFromElement(browser, treeNode); - expect(result).toEqual({ - 'child special': { - 'some key': 'some other value', - '_type': 'child special', - 'priority': 0, - }, - 'special one': { - 'some key': 'some value', - '_type': 'special one', - 'priority': -1, - }, - }); - }); - }); - - context('When tree as "special type"', () => { - context('When "special type" have "other type"', () => { - context('When "other type" have "special type"', () => { - describe('When retrieving lead node', () => { - it('does not override previous node type data', () => { - const root = newTree.addNewNode('root', { - 'some key': 'some value', - '_type': 'special one', - }, []); - const level1 = new TreeNode('level 1', { - 'some key': 'some value', - '_type': 'other type', - }); - newTree.addChild(root, level1); - treeNode = new TreeNode('level 2', { - 'some key': 'expected value', - '_type': 'special one', - 'some other key': 'some other value', - }); - newTree.addChild(level1, treeNode); - - const result = getTreeNodeHierarchyFromElement(browser, treeNode); - expect(result).toEqual({ - 'special one': { - 'some key': 'expected value', - '_type': 'special one', - 'some other key': 'some other value', - 'priority': 0, - }, - 'other type': { - 'some key': 'some value', - '_type': 'other type', - 'priority': -1, - }, - }); - }); - }); - }); - }); - }); - - context('When tree has table', () => { - context('when table has partition', () => { - it('returns table with partition parameters', () => { - const root = newTree.addNewNode('root', { - 'some key': 'some value', - '_type': 'special one', - }); - const level1 = newTree.addNewNode('level 1', { - 'some key': 'some value', - '_type': 'table', - }); - newTree.addChild(root, level1); - treeNode = new TreeNode('level 2', { - 'some key': 'expected value', - '_type': 'partition', - 'some other key': 'some other value', - }); - newTree.addChild(level1, treeNode); - - const result = getTreeNodeHierarchyFromElement(browser, treeNode); - expect(result).toEqual({ - 'special one': { - 'some key': 'some value', - '_type': 'special one', - 'priority': -2, - }, - 'table': { - 'some key': 'some value', - '_type': 'table', - 'priority': -1, - }, - 'partition': { - 'some key': 'expected value', - 'some other key': 'some other value', - '_type': 'partition', - 'priority': 0, - }, - }); - }); - }); - }); - }); -}); diff --git a/web/regression/javascript/tree/pgadmin_tree_state_save_spec.js b/web/regression/javascript/tree/pgadmin_tree_state_save_spec.js index 6e902768b..e89ef91d1 100644 --- a/web/regression/javascript/tree/pgadmin_tree_state_save_spec.js +++ b/web/regression/javascript/tree/pgadmin_tree_state_save_spec.js @@ -107,7 +107,10 @@ describe('#browserTreeState', () => { };}, }, }; - pgBrowser.tree = jasmine.createSpyObj('tree', ['itemData', 'pathId', 'hasParent', 'isOpen', 'isClosed', 'selected']); + pgBrowser.tree = jasmine.createSpyObj('tree', ['itemData', 'pathId', 'hasParent', 'isOpen', 'isClosed', 'selected', 'parent']); + pgBrowser.tree.getTreeNodeHierarchy = function (item) { + return pgBrowser.Nodes[item._type].getTreeNodeHierarchy(); + }; }); describe('When node is opened tree state is getting updated', () => { diff --git a/web/regression/javascript/tree/tree_fake.js b/web/regression/javascript/tree/tree_fake.js index fe647504f..337594f52 100644 --- a/web/regression/javascript/tree/tree_fake.js +++ b/web/regression/javascript/tree/tree_fake.js @@ -8,10 +8,11 @@ ////////////////////////////////////////////////////////////// import {Tree} from '../../../pgadmin/static/js/tree/tree'; +import {ManageTreeNodes, TreeNode} from '../../../pgadmin/static/js/tree/tree_nodes'; export class TreeFake extends Tree { - static build(structure) { - let tree = new TreeFake(); + static build(structure, pgBrowser) { + let tree = new TreeFake(pgBrowser); let rootNode = tree.rootNode; if (structure.children !== undefined) { @@ -27,7 +28,10 @@ export class TreeFake extends Tree { let id = newNode.id; let data = newNode.data ? newNode.data : {}; let domNode = newNode.domNode ? newNode.domNode : [{id: id}]; - tree.addNewNode(id, data, domNode, tree.translateTreeNodeIdFromACITree([parent])); + + let parentPath = tree.translateTreeNodeIdFromReactTree([parent]); + + tree.addNewNode(id, data, domNode, parentPath); if (newNode.children !== undefined) { newNode.children.forEach((child) => { @@ -36,50 +40,96 @@ export class TreeFake extends Tree { } } - constructor() { - super(); - this.aciTreeToOurTreeTranslator = {}; - this.aciTreeApi = jasmine.createSpyObj( - 'ACITreeApi', ['setInode', 'unload', 'deselect', 'select']); - this.aciTreeApi.unload.and.callFake(function(domNode, config) { + constructor(pgBrowser) { + let manageTree = new ManageTreeNodes(); + let tree = jasmine.createSpyObj( + 'tree', ['unload', 'onTreeEvents', + 'getActiveFile', 'setActiveFile', + 'deSelectActiveFile', 'closeDirectory']); + tree.unload.and.callFake(function(domNode, config) { config.success(); }); + + super(tree, manageTree, pgBrowser); + this.aciTreeToOurTreeTranslator = {}; + } addNewNode(id, data, domNode, path) { - this.aciTreeToOurTreeTranslator[id] = [id]; + this.aciTreeToOurTreeTranslator[id] = id; if (path !== null && path !== undefined) { - this.aciTreeToOurTreeTranslator[id] = path.concat(id); + if (typeof(path) === 'object') path = path.join('/'); + this.aciTreeToOurTreeTranslator[id] = path != '' ? path + '/' + id : id; + if (path.indexOf('/browser/') != 0) path = path != '' ? '/browser/' + path : undefined; } return super.addNewNode(id, data, domNode, path); } addChild(parent, child) { child.setParent(parent); - this.aciTreeToOurTreeTranslator[child.id] = this.aciTreeToOurTreeTranslator[parent.id].concat(child.id); + this.aciTreeToOurTreeTranslator[child.id] = this.aciTreeToOurTreeTranslator[parent.id] + '/' + child.id; parent.children.push(child); } hasParent(aciTreeNode) { - return this.translateTreeNodeIdFromACITree(aciTreeNode).length > 1; + let parents = this.translateTreeNodeIdFromReactTree(aciTreeNode).split('/'); + return parents.length > 1; } parent(aciTreeNode) { if (this.hasParent(aciTreeNode)) { - let path = this.translateTreeNodeIdFromACITree(aciTreeNode); - return [{id: this.findNode(path).parent().id}]; + let path = this.translateTreeNodeIdFromReactTree(aciTreeNode); + return [{id: this.findNode('/browser/' + path).parent().id}]; } return null; } - translateTreeNodeIdFromACITree(aciTreeNode) { + translateTreeNodeIdFromReactTree(aciTreeNode) { if (aciTreeNode === undefined || aciTreeNode[0] === undefined) { return null; } return this.aciTreeToOurTreeTranslator[aciTreeNode[0].id]; } + findNodeByDomElement(domElement) { + const path = this.translateTreeNodeIdFromReactTree(domElement); + + if(!path || !path[0]) { + return undefined; + } + + return this.findNode('/browser/' + path); + + } + + getTreeNodeHierarchy(identifier) { + let idx = 0; + let node_cnt = 0; + let result = {}; + let item = TreeNode.prototype.isPrototypeOf(identifier) ? identifier : + (identifier.path ? this.findNode(identifier.path) : this.findNodeByDomElement(identifier)); + + if (item == undefined || item == null) return null; + + do { + const currentNodeData = item.getData(); + if (currentNodeData._type in this.Nodes && this.Nodes[currentNodeData._type].hasId) { + const nodeType = mapType(currentNodeData._type, node_cnt); + if (result[nodeType] === undefined) { + result[nodeType] = _.extend({}, currentNodeData, { + 'priority': idx, + }); + idx -= 1; + } + } + node_cnt += 1; + item = item.hasParent() ? item.parent() : null; + } while (item); + + return result; + } + itemData(aciTreeNode) { let node = this.findNodeByDomElement(aciTreeNode); if (node === undefined || node === null) { @@ -96,3 +146,7 @@ export class TreeFake extends Tree { this.selectedNode = selectedNode; } } + +function mapType(type, idx) { + return (type === 'partition' && idx > 0) ? 'table' : type; +} diff --git a/web/regression/javascript/tree/tree_spec.js b/web/regression/javascript/tree/tree_spec.js index 239a3a87d..2f80f6304 100644 --- a/web/regression/javascript/tree/tree_spec.js +++ b/web/regression/javascript/tree/tree_spec.js @@ -1,13 +1,14 @@ ////////////////////////////////////////////////////////////////////////// // -// pgAdmin 4 - PostgreSQL Tools +// pgAdmin 4 PostgreSQL Tools // -// Copyright (C) 2013 - 2021, The pgAdmin Development Team +// Copyright (C) 2013 2021, The pgAdmin Development Team // This software is released under the PostgreSQL Licence // ////////////////////////////////////////////////////////////////////////// -import {Tree, TreeNode} from '../../../pgadmin/static/js/tree/tree'; +import {Tree} from '../../../pgadmin/static/js/tree/tree'; +import {TreeNode, ManageTreeNodes} from '../../../pgadmin/static/js/tree/tree_nodes'; import {TreeFake} from './tree_fake'; const context = describe; @@ -15,28 +16,34 @@ const context = describe; const treeTests = (treeClass, setDefaultCallBack) => { let tree; beforeEach(() => { - tree = new treeClass(); + let manageTree = new ManageTreeNodes(); + let reactTree = jasmine.createSpyObj( + 'tree', ['onTreeEvents', 'getActiveFile']); + tree = new treeClass(reactTree, manageTree); }); describe('#addNewNode', () => { + beforeEach(() => { + tree.rootNode = new TreeNode(undefined, {}); + }); describe('when add a new root element', () => { - context('using [] as the parent', () => { + context('using undefined as the parent', () => { beforeEach(() => { - tree.addNewNode('some new node', {data: 'interesting'}, undefined, []); + tree.addNewNode('some new node', {data: 'interesting'}, undefined, undefined); }); it('can be retrieved', () => { - const node = tree.findNode(['some new node']); + const node = tree.findNode('/browser/some new node'); expect(node.data).toEqual({data: 'interesting'}); }); it('return false for #hasParent()', () => { - const node = tree.findNode(['some new node']); + const node = tree.findNode('/browser/some new node'); expect(node.hasParent()).toEqual(false); }); it('return null for #parent()', () => { - const node = tree.findNode(['some new node']); + const node = tree.findNode('/browser/some new node'); expect(node.parent()).toBeNull(); }); }); @@ -47,38 +54,17 @@ const treeTests = (treeClass, setDefaultCallBack) => { }); it('can be retrieved', () => { - const node = tree.findNode(['some new node']); + const node = tree.findNode('/browser/some new node'); expect(node.data).toEqual({data: 'interesting'}); }); it('return false for #hasParent()', () => { - const node = tree.findNode(['some new node']); + const node = tree.findNode('/browser/some new node'); expect(node.hasParent()).toEqual(false); }); it('return null for #parent()', () => { - const node = tree.findNode(['some new node']); - expect(node.parent()).toBeNull(); - }); - }); - - context('using undefined as the parent', () => { - beforeEach(() => { - tree.addNewNode('some new node', {data: 'interesting'}); - }); - - it('can be retrieved', () => { - const node = tree.findNode(['some new node']); - expect(node.data).toEqual({data: 'interesting'}); - }); - - it('return false for #hasParent()', () => { - const node = tree.findNode(['some new node']); - expect(node.hasParent()).toEqual(false); - }); - - it('return null for #parent()', () => { - const node = tree.findNode(['some new node']); + const node = tree.findNode('/browser/some new node'); expect(node.parent()).toBeNull(); }); }); @@ -87,101 +73,46 @@ const treeTests = (treeClass, setDefaultCallBack) => { describe('when add a new element as a child', () => { let parentNode; beforeEach(() => { - parentNode = tree.addNewNode('parent node', {data: 'parent data'}, undefined, []); - tree.addNewNode('some new node', {data: 'interesting'}, undefined, ['parent' + - ' node']); + parentNode = tree.addNewNode('parent node', {data: 'parent data'}, undefined, undefined); + tree.addNewNode('some new node', {data: 'interesting'}, undefined, '/browser/parent node'); }); it('can be retrieved', () => { - const node = tree.findNode(['parent node', 'some new node']); + const node = tree.findNode('/browser/parent node/some new node'); expect(node.data).toEqual({data: 'interesting'}); }); it('return true for #hasParent()', () => { - const node = tree.findNode(['parent node', 'some new node']); + const node = tree.findNode('/browser/parent node/some new node'); expect(node.hasParent()).toEqual(true); }); it('return "parent node" object for #parent()', () => { - const node = tree.findNode(['parent node', 'some new node']); + const node = tree.findNode('/browser/parent node/some new node'); expect(node.parent()).toEqual(parentNode); }); }); describe('when add an element that already exists under a parent', () => { beforeEach(() => { - tree.addNewNode('parent node', {data: 'parent data'}, undefined, []); - tree.addNewNode('some new node', {data: 'interesting'}, undefined, ['parent' + - ' node']); + tree.addNewNode('parent node', {data: 'parent data'}, undefined, undefined); + tree.addNewNode('some new node', {data: 'interesting'}, undefined, '/browser/parent node'); }); it('does not add a new child', () => { - tree.addNewNode('some new node', {data: 'interesting 1'}, undefined, ['parent' + - ' node']); - const parentNode = tree.findNode(['parent node']); + tree.addNewNode('some new node', {data: 'interesting 1'}, undefined, '/browser/parent node'); + const parentNode = tree.findNode('/browser/parent node'); expect(parentNode.children.length).toEqual(1); }); it('updates the existing node data', () => { - tree.addNewNode('some new node', {data: 'interesting 1'}, undefined, ['parent' + - ' node']); - const node = tree.findNode(['parent node', 'some new node']); + tree.addNewNode('some new node', {data: 'interesting 1'}, undefined, '/browser/parent node'); + const node = tree.findNode('/browser/parent node/some new node'); expect(node.data).toEqual({data: 'interesting 1'}); }); }); }); - describe('#translateTreeNodeIdFromACITree', () => { - let aciTreeApi; - beforeEach(() => { - aciTreeApi = jasmine.createSpyObj('ACITreeApi', [ - 'hasParent', - 'parent', - 'getId', - ]); - - aciTreeApi.getId.and.callFake((node) => { - return node[0].id; - }); - tree.aciTreeApi = aciTreeApi; - }); - - describe('When tree as a single level', () => { - beforeEach(() => { - aciTreeApi.hasParent.and.returnValue(false); - }); - - it('returns an array with the ID of the first level', () => { - let node = [{ - id: 'some id', - }]; - tree.addNewNode('some id', {}, undefined, []); - - expect(tree.translateTreeNodeIdFromACITree(node)).toEqual(['some id']); - }); - }); - - describe('When tree as a 2 levels', () => { - describe('When we try to retrieve the node in the second level', () => { - it('returns an array with the ID of the first level and second level', () => { - aciTreeApi.hasParent.and.returnValues(true, false); - aciTreeApi.parent.and.returnValue([{ - id: 'parent id', - }]); - let node = [{ - id: 'some id', - }]; - - tree.addNewNode('parent id', {}, undefined, []); - tree.addNewNode('some id', {}, undefined, ['parent id']); - - expect(tree.translateTreeNodeIdFromACITree(node)) - .toEqual(['parent id', 'some id']); - }); - }); - }); - }); - describe('#selected', () => { context('a node in the tree is selected', () => { it('returns that node object', () => { @@ -195,16 +126,17 @@ const treeTests = (treeClass, setDefaultCallBack) => { describe('#findNodeByTreeElement', () => { context('retrieve data from node not found', () => { it('return undefined', () => { - let aciTreeApi = jasmine.createSpyObj('ACITreeApi', [ + let reactTree = jasmine.createSpyObj('tree', [ 'hasParent', 'parent', 'getId', + 'onTreeEvents', ]); - aciTreeApi.getId.and.callFake((node) => { + reactTree.getId.and.callFake((node) => { return node[0].id; }); - tree.aciTreeApi = aciTreeApi; + tree.tree = reactTree; expect(tree.findNodeByDomElement(['
  • something
  • '])).toBeUndefined(); }); }); @@ -240,14 +172,18 @@ describe('tree tests', () => { let level2; beforeEach(() => { tree = new TreeFake(); - tree.addNewNode('level1', {data: 'interesting'}, [{id: 'level1'}], []); + tree.addNewNode('level1', {data: 'interesting'}, [{id: 'level1'}], undefined); level2 = tree.addNewNode('level2', {data: 'data'}, [{id: 'level2'}], ['level1']); tree.addNewNode('level3', {data: 'more data'}, [{id: 'level3'}], ['level1', 'level2']); - tree.aciTreeApi = jasmine.createSpyObj( - 'ACITreeApi', ['setInode', 'unload', 'deselect', 'select']); - tree.aciTreeApi.unload.and.callFake((domNode, config) => { - config.success(); + tree.tree = jasmine.createSpyObj( + 'tree', ['unload', 'onTreeEvents', + 'setActiveFile', 'closeDirectory', 'getActiveFile', + 'deSelectActiveFile']); + tree.tree.unload.and.callFake(function() { + return new Promise((resolve)=>{ + resolve('Success!'); + }); }); }); @@ -286,11 +222,11 @@ describe('tree tests', () => { }); }); - describe('ACITree specific', () => { + describe('ReactTree specific', () => { it('sets the current node as a Inode, changing the Icon back to +', (done) => { level2.reload(tree) .then(()=>{ - expect(tree.aciTreeApi.setInode).toHaveBeenCalledWith([{id: 'level2'}]); + expect(tree.tree.closeDirectory).toHaveBeenCalledWith([{id: 'level2'}]); done(); }) .catch((error)=>{ @@ -298,12 +234,12 @@ describe('tree tests', () => { }); }); - it('deselect the node and selects it again to trigger ACI tree' + - ' events', (done) => { + it('deselect the node and selects it again to trigger React tree' + + ' events', (done) => { level2.reload(tree) .then(()=>{ setTimeout(() => { - expect(tree.aciTreeApi.deselect).toHaveBeenCalledWith([{id: 'level2'}]); + expect(tree.tree.deSelectActiveFile).toHaveBeenCalledWith([{id: 'level2'}]); done(); }, 20); }) @@ -319,12 +255,14 @@ describe('tree tests', () => { let level2; beforeEach(() => { tree = new TreeFake(); - tree.addNewNode('level1', {data: 'interesting'}, ['
  • level1
  • '], []); + tree.addNewNode('level1', {data: 'interesting'}, ['
  • level1
  • '], undefined); level2 = tree.addNewNode('level2', {data: 'data'}, ['
  • level2
  • '], ['level1']); - tree.addNewNode('level3', {data: 'more data'}, ['
  • level3
  • '], ['level1', 'level2']); - tree.aciTreeApi = jasmine.createSpyObj('ACITreeApi', ['unload']); - tree.aciTreeApi.unload.and.callFake((domNode, config) => { - config.success(); + tree.addNewNode('level3', {data: 'more data'}, ['
  • level3
  • '], ['level1','level2']); + tree.tree = jasmine.createSpyObj('tree', ['unload']); + tree.tree.unload.and.callFake(() => { + return new Promise((resolve)=>{ + resolve('Success!'); + }); }); }); @@ -340,10 +278,10 @@ describe('tree tests', () => { }); }); - it('calls unload on the ACI Tree', (done) => { + it('calls unload on the React Tree', (done) => { level2.unload(tree) .then(()=>{ - expect(tree.aciTreeApi.unload).toHaveBeenCalledWith(['
  • level2
  • '], jasmine.any(Object)); + expect(tree.tree.unload).toHaveBeenCalledWith(['
  • level2
  • ']); done(); }) .catch((error)=>{ @@ -355,11 +293,11 @@ describe('tree tests', () => { describe('Tree', () => { function realTreeSelectNode(tree, selectedNode) { - let aciTreeApi = jasmine.createSpyObj('ACITreeApi', [ - 'selected', + let reactTree = jasmine.createSpyObj('tree', [ + 'getActiveFile', ]); - tree.aciTreeApi = aciTreeApi; - aciTreeApi.selected.and.returnValue(selectedNode); + tree.tree = reactTree; + reactTree.getActiveFile.and.returnValue(selectedNode); } treeTests(Tree, realTreeSelectNode); @@ -377,8 +315,8 @@ describe('tree tests', () => { let tree; beforeEach(() => { tree = new TreeFake(); - tree.addNewNode('level1', {data: 'interesting'}, undefined, []); - tree.addNewNode('level2', {data: 'interesting'}, undefined, ['level1']); + tree.addNewNode('level1', {data: 'interesting'}, undefined, undefined); + tree.addNewNode('level2', {data: 'interesting'}, undefined, '/browser/level1'); }); context('node is at the first level', () => { @@ -399,7 +337,7 @@ describe('tree tests', () => { let tree; beforeEach(() => { tree = new TreeFake(); - tree.addNewNode('level1', {data: 'interesting'}, undefined, []); + tree.addNewNode('level1', {data: 'interesting'}, undefined, undefined); tree.addNewNode('level2', {data: 'interesting'}, undefined, ['level1']); }); @@ -416,30 +354,6 @@ describe('tree tests', () => { }); }); - describe('#itemData', () => { - let tree; - beforeEach(() => { - tree = new TreeFake(); - tree.addNewNode('level1', {data: 'interesting'}, undefined, []); - tree.addNewNode('level2', {data: 'expected data'}, undefined, ['level1']); - }); - - context('retrieve data from the node', () => { - it('return the node data', () => { - expect(tree.itemData([{id: 'level2'}])).toEqual({ - data: 'expected' + - ' data', - }); - }); - }); - - context('retrieve data from node not found', () => { - it('return undefined', () => { - expect(tree.itemData([{id: 'bamm'}])).toBeUndefined(); - }); - }); - }); - describe('#addChild', () => { let root, child; beforeEach(() => { @@ -459,7 +373,7 @@ describe('tree tests', () => { }); it('changes the path of the child', () => { - expect(child.path).toEqual('root.node.1'); + expect(child.path).toEqual('/browser/root/node.1'); }); }); }); diff --git a/web/webpack.config.js b/web/webpack.config.js index 1ed1761dc..54b7af79f 100644 --- a/web/webpack.config.js +++ b/web/webpack.config.js @@ -190,7 +190,7 @@ var themeCssRules = function(theme_name) { filename: 'img/[name].[ext]', }, exclude: /vendor/, - }, { + },{ test: /\.(eot|svg|ttf|woff|woff2)$/, type: 'asset/resource', generator: { @@ -203,7 +203,7 @@ var themeCssRules = function(theme_name) { path.join(sourceDir, '/fonts/'), ], exclude: /vendor/, - }, { + },{ test: /\.scss$/, use: [ { @@ -212,7 +212,13 @@ var themeCssRules = function(theme_name) { publicPath: '', }, }, - {loader: 'css-loader'}, + { + loader: 'css-loader', + options: { + url: false, + sourceMap: true, + }, + }, { loader: 'postcss-loader', options: { @@ -403,8 +409,17 @@ module.exports = [{ use: { loader: 'babel-loader', options: { - presets: [['@babel/preset-env', {'modules': 'commonjs', 'useBuiltIns': 'usage', 'corejs': 3}], '@babel/preset-react'], - plugins: ['@babel/plugin-proposal-class-properties'], + presets: [['@babel/preset-env', {'modules': 'commonjs', 'useBuiltIns': 'usage', 'corejs': 3}], '@babel/preset-react', '@babel/preset-typescript'], + plugins: ['@babel/plugin-proposal-class-properties', '@babel/proposal-object-rest-spread'], + }, + }, + }, { + test: /\.tsx?$|\.ts?$/, + use: { + loader: 'babel-loader', + options: { + presets: [['@babel/preset-env', {'modules': 'commonjs', 'useBuiltIns': 'usage', 'corejs': 3}], '@babel/preset-react', '@babel/preset-typescript'], + plugins: ['@babel/plugin-proposal-class-properties', '@babel/proposal-object-rest-spread'], }, }, }, { @@ -544,7 +559,7 @@ module.exports = [{ resolve: { alias: webpackShimConfig.resolveAlias, modules: ['node_modules', '.'], - extensions: ['.js', '.jsx'], + extensions: ['.js', '.jsx', '.ts', '.tsx'], unsafeCache: true, }, // Watch mode Configuration: After initial build, webpack will watch for diff --git a/web/webpack.shim.js b/web/webpack.shim.js index f91506ed1..8b3fa8987 100644 --- a/web/webpack.shim.js +++ b/web/webpack.shim.js @@ -155,6 +155,7 @@ var webpackShimConfig = { 'react-dom': path.join(__dirname, 'node_modules/react-dom'), 'stylis': path.join(__dirname, 'node_modules/stylis'), 'popper.js': path.join(__dirname, 'node_modules/popper.js'), + 'pgadmin4-tree': path.join(__dirname, 'node_modules/pgadmin4-tree'), // AciTree 'jquery.acitree': path.join(__dirname, './node_modules/acitree/js/jquery.aciTree.min'), diff --git a/web/webpack.test.config.js b/web/webpack.test.config.js index c05e9dacb..fe01129a2 100644 --- a/web/webpack.test.config.js +++ b/web/webpack.test.config.js @@ -44,105 +44,115 @@ module.exports = { ], module: { - rules: [ - { - test: /\.jsx?$/, - exclude: [/node_modules/, /vendor/], - use: { - loader: 'babel-loader', + rules: [{ + test: /\.jsx?$/, + exclude: [/node_modules/, /vendor/], + use: { + loader: 'babel-loader', + options: { + presets: [['@babel/preset-env', {'modules': 'commonjs', 'useBuiltIns': 'usage', 'corejs': 3}], '@babel/preset-react'], + plugins: ['@babel/plugin-proposal-class-properties'], + sourceMap: 'inline', + }, + }, + }, { + test: /\.tsx?$|\.ts?$/, + exclude: [/node_modules/, /vendor/], + use: { + loader: 'babel-loader', + options: { + presets: [['@babel/preset-env', {'modules': 'commonjs', 'useBuiltIns': 'usage', 'corejs': 3}], '@babel/preset-react', '@babel/preset-typescript'], + plugins: ['@babel/plugin-proposal-class-properties', '@babel/proposal-object-rest-spread'], + sourceMap: 'inline', + }, + }, + }, { + test: /\.css$/, + type: 'asset/source', + use: ['style-loader'], + }, { + test: /\.(jpe?g|png|gif|svg)$/i, + type: 'asset', + parser: { + dataUrlCondition: { + maxSize: 4 * 1024, // 4kb + }, + }, + generator: { + filename: 'img/[name].[ext]', + }, + exclude: /vendor/, + }, { + test: /.*slickgrid[\\\/]+slick\.(?!core)*/, + use:[ + { + loader: 'imports-loader', options: { - presets: [['@babel/preset-env', {'modules': 'commonjs', 'useBuiltIns': 'usage', 'corejs': 3}], '@babel/preset-react'], - plugins: ['@babel/plugin-proposal-class-properties'], - sourceMap: 'inline', + type: 'commonjs', + imports: [ + 'pure|jquery.ui', + 'pure|jquery.event.drag', + 'pure|slickgrid', + ], }, }, - }, { - test: /\.css$/, - type: 'asset/source', - use: ['style-loader'], - }, { - test: /\.(jpe?g|png|gif|svg)$/i, - type: 'asset', - parser: { - dataUrlCondition: { - maxSize: 4 * 1024, // 4kb + ], + }, { + test: /.*slickgrid\.plugins[\\\/]+slick\.cellrangeselector/, + use:[ + { + loader: 'imports-loader', + options: { + type: 'commonjs', + imports: [ + 'pure|jquery.ui', + 'pure|jquery.event.drag', + 'pure|slickgrid', + ], + }, + }, { + loader: 'exports-loader', + options: { + type: 'commonjs', + exports: 'single|Slick.CellRangeSelector', }, }, - generator: { - filename: 'img/[name].[ext]', + ], + }, { + test: /.*slickgrid[\\\/]+slick\.core.*/, + use:[ + { + loader: 'imports-loader', + options: { + type: 'commonjs', + imports: [ + 'pure|jquery.ui', + 'pure|jquery.event.drag', + ], + }, + }, { + loader: 'exports-loader', + options: { + type: 'commonjs', + exports: 'single|Slick', + }, }, - exclude: /vendor/, - }, { - test: /.*slickgrid[\\\/]+slick\.(?!core)*/, - use:[ - { - loader: 'imports-loader', - options: { - type: 'commonjs', - imports: [ - 'pure|jquery.ui', - 'pure|jquery.event.drag', - 'pure|slickgrid', - ], - }, - }, - ], - }, { - test: /.*slickgrid\.plugins[\\\/]+slick\.cellrangeselector/, - use:[ - { - loader: 'imports-loader', - options: { - type: 'commonjs', - imports: [ - 'pure|jquery.ui', - 'pure|jquery.event.drag', - 'pure|slickgrid', - ], - }, - }, { - loader: 'exports-loader', - options: { - type: 'commonjs', - exports: 'single|Slick.CellRangeSelector', - }, - }, - ], - }, { - test: /.*slickgrid[\\\/]+slick\.core.*/, - use:[ - { - loader: 'imports-loader', - options: { - type: 'commonjs', - imports: [ - 'pure|jquery.ui', - 'pure|jquery.event.drag', - ], - }, - }, { - loader: 'exports-loader', - options: { - type: 'commonjs', - exports: 'single|Slick', - }, - }, - ], - }, - { - test: /\.js$|\.jsx$/, - use: { - loader: 'istanbul-instrumenter-loader', - options: { esModules: true }, - }, - enforce: 'post', - exclude: /node_modules|slickgrid|plugins|bundle|generated|regression|[Tt]est.js|[Ss]pecs.js|[Ss]pec.js|\.spec\.js$/, + ], + }, + { + test: /\.js$|\.jsx$/, + use: { + loader: 'istanbul-instrumenter-loader', + options: { esModules: true }, }, + enforce: 'post', + exclude: /node_modules|slickgrid|plugins|bundle|generated|regression|[Tt]est.js|[Ss]pecs.js|[Ss]pec.js|\.spec\.js$/, + }, ], }, resolve: { - extensions: ['.js', '.jsx'], + extensions: ['.js', '.jsx', '.ts', '.tsx'], alias: { 'top': path.join(__dirname, './pgadmin'), 'jquery': path.join(__dirname, './node_modules/jquery/dist/jquery'), @@ -173,6 +183,7 @@ module.exports = { 'pgadmin.alertifyjs': sourcesDir + '/js/alertify.pgadmin.defaults', 'pgadmin.backgrid': sourcesDir + '/js/backgrid.pgadmin', 'pgadmin.backform': sourcesDir + '/js/backform.pgadmin', + 'pgadmin4-tree': path.join(__dirname, 'node_modules/pgadmin4-tree'), 'pgbrowser': path.resolve(__dirname, 'regression/javascript/fake_browser'), 'pgadmin.schema.dir': path.resolve(__dirname, 'pgadmin/browser/server_groups/servers/databases/schemas/static/js'), 'pgadmin.browser.layout': path.join(__dirname, './pgadmin/browser/static/js/layout'), diff --git a/web/yarn.lock b/web/yarn.lock index dd33626e6..acc3d5649 100644 --- a/web/yarn.lock +++ b/web/yarn.lock @@ -16,11 +16,23 @@ dependencies: "@babel/highlight" "^7.12.13" +"@babel/code-frame@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.14.5.tgz#23b08d740e83f49c5e59945fbf1b43e80bbf4edb" + integrity sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw== + dependencies: + "@babel/highlight" "^7.14.5" + "@babel/compat-data@^7.13.0", "@babel/compat-data@^7.13.8": version "7.13.8" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.13.8.tgz#5b783b9808f15cef71547f1b691f34f8ff6003a6" integrity sha512-EaI33z19T4qN3xLXsGf48M2cDqa6ei9tPZlfLdb2HC+e/cFtREiRd8hdSqDbwdLB0/+gLwqJmCYASH0z2bUdog== +"@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/core@^7.10.2", "@babel/core@^7.7.5": version "7.13.8" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.13.8.tgz#c191d9c5871788a591d69ea1dc03e5843a3680fb" @@ -68,6 +80,15 @@ jsesc "^2.5.1" source-map "^0.5.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/helper-annotate-as-pure@^7.0.0", "@babel/helper-annotate-as-pure@^7.10.4", "@babel/helper-annotate-as-pure@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.12.13.tgz#0f58e86dfc4bb3b1fcd7db806570e177d439b6ab" @@ -75,6 +96,13 @@ dependencies: "@babel/types" "^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== + dependencies: + "@babel/types" "^7.14.5" + "@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" @@ -93,6 +121,16 @@ browserslist "^4.14.5" semver "^6.3.0" +"@babel/helper-compilation-targets@^7.14.5": + 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== + dependencies: + "@babel/compat-data" "^7.14.5" + "@babel/helper-validator-option" "^7.14.5" + browserslist "^4.16.6" + semver "^6.3.0" + "@babel/helper-create-class-features-plugin@^7.13.0": version "7.13.8" resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.13.8.tgz#0367bd0a7505156ce018ca464f7ac91ba58c1a04" @@ -104,6 +142,18 @@ "@babel/helper-replace-supers" "^7.13.0" "@babel/helper-split-export-declaration" "^7.12.13" +"@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== + 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-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" @@ -142,6 +192,15 @@ "@babel/template" "^7.12.13" "@babel/types" "^7.14.2" +"@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== + dependencies: + "@babel/helper-get-function-arity" "^7.14.5" + "@babel/template" "^7.14.5" + "@babel/types" "^7.14.5" + "@babel/helper-get-function-arity@^7.12.13": version "7.12.13" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.12.13.tgz#bc63451d403a3b3082b97e1d8b3fe5bd4091e583" @@ -149,6 +208,13 @@ dependencies: "@babel/types" "^7.12.13" +"@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-hoist-variables@^7.13.0": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.13.0.tgz#5d5882e855b5c5eda91e0cadc26c6e7a2c8593d8" @@ -157,6 +223,13 @@ "@babel/traverse" "^7.13.0" "@babel/types" "^7.13.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-member-expression-to-functions@^7.13.0": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.13.0.tgz#6aa4bb678e0f8c22f58cdb79451d30494461b091" @@ -164,6 +237,13 @@ dependencies: "@babel/types" "^7.13.0" +"@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== + dependencies: + "@babel/types" "^7.14.5" + "@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.13.12": version "7.13.12" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.13.12.tgz#c6a369a6f3621cb25da014078684da9196b61977" @@ -193,11 +273,23 @@ dependencies: "@babel/types" "^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== + dependencies: + "@babel/types" "^7.14.5" + "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.13.0.tgz#806526ce125aed03373bc416a828321e3a6a33af" integrity sha512-ZPafIPSwzUlAoWT8DKs1W2VyF2gOWthGd5NGFMsBcMMol+ZhK+EQY/e6V96poa6PA/Bh+C9plWN0hXO1uB8AfQ== +"@babel/helper-plugin-utils@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9" + integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ== + "@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" @@ -217,6 +309,16 @@ "@babel/traverse" "^7.13.0" "@babel/types" "^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-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" @@ -238,16 +340,38 @@ dependencies: "@babel/types" "^7.12.13" +"@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-validator-identifier@^7.12.11", "@babel/helper-validator-identifier@^7.14.0": version "7.14.0" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.0.tgz#d26cad8a47c65286b15df1547319a5d0bcf27288" integrity sha512-V3ts7zMSu5lfiwWDVWzRDGIN+lnCEUdaXgtVHJgLb1rGaA6jMrtB9EmE7L18foXJIE8Un/A/h6NJfGQp/e1J4A== +"@babel/helper-validator-identifier@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.14.5.tgz#d0f0e277c512e0c938277faa85a3968c9a44c0e8" + integrity sha512-5lsetuxCLilmVGyiLEfoHBRX8UCFD+1m2x3Rj97WrW3V7H3u4RWRXA4evMjImCsin2J2YT0QaVDGf+z8ondbAg== + +"@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/helper-validator-option@^7.12.17": version "7.12.17" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.12.17.tgz#d1fbf012e1a79b7eebbfdc6d270baaf8d9eb9831" integrity sha512-TopkMDmLzq8ngChwRlyjR6raKD6gMSae4JdYDB8bByKreQgG0RBTuKe9LRxW3wFtUnjxOPRKBDwEH6Mg5KeDfw== +"@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.13.0": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.13.0.tgz#bdb5c66fda8526ec235ab894ad53a1235c79fcc4" @@ -276,11 +400,25 @@ chalk "^2.0.0" js-tokens "^4.0.0" +"@babel/highlight@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.14.5.tgz#6861a52f03966405001f6aa534a01a24d99e8cd9" + integrity sha512-qf9u2WFWVV0MppaL877j2dBtQIDgmidgjGk5VIMw3OadXvYaXn66U1BFlH2t4+t3i+8PhedppRv+i40ABzd+gg== + dependencies: + "@babel/helper-validator-identifier" "^7.14.5" + chalk "^2.0.0" + js-tokens "^4.0.0" + "@babel/parser@^7.12.13", "@babel/parser@^7.13.0", "@babel/parser@^7.13.4": version "7.13.9" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.13.9.tgz#ca34cb95e1c2dd126863a84465ae8ef66114be99" integrity sha512-nEUfRiARCcaVo3ny3ZQjURjHQZUo/JkEw7rLlSZy/psWGnvwXFtPcr6jb7Yb41DVW5LTe6KRq9LGleRNsg1Frw== +"@babel/parser@^7.14.5", "@babel/parser@^7.14.7": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.14.7.tgz#6099720c8839ca865a2637e6c85852ead0bdb595" + integrity sha512-X67Z5y+VBJuHB/RjwECp8kSl5uYi0BvRbNeWqkaJCVh+LiTPl19WBUfG627psSgp9rSf6ojuXghQM3ha6qHHdA== + "@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" @@ -346,7 +484,18 @@ "@babel/helper-plugin-utils" "^7.13.0" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-object-rest-spread@^7.13.8", "@babel/plugin-proposal-object-rest-spread@^7.9.6": +"@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== + dependencies: + "@babel/compat-data" "^7.14.7" + "@babel/helper-compilation-targets" "^7.14.5" + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.14.5" + +"@babel/plugin-proposal-object-rest-spread@^7.13.8": version "7.13.8" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.13.8.tgz#5d210a4d727d6ce3b18f9de82cc99a3964eed60a" integrity sha512-DhB2EuB1Ih7S3/IRX5AFVgZ16k3EzfRbq97CxAVI1KSYcW+lexV8VZb7G7L8zuPVSdQMRn0kiBpf/Yzu9ZKH0g== @@ -481,6 +630,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@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== + 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" @@ -657,6 +813,13 @@ dependencies: "@babel/helper-plugin-utils" "^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-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" @@ -758,6 +921,15 @@ dependencies: "@babel/helper-plugin-utils" "^7.12.13" +"@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== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.14.6" + "@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" @@ -870,10 +1042,19 @@ "@babel/plugin-transform-react-jsx-development" "^7.12.17" "@babel/plugin-transform-react-pure-annotations" "^7.12.1" +"@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== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-validator-option" "^7.14.5" + "@babel/plugin-transform-typescript" "^7.14.5" + "@babel/runtime@^7.0.0": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.15.4.tgz#fd17d16bfdf878e6dd02d19753a39fa8a8d9c84a" - integrity sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw== + version "7.14.6" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.6.tgz#535203bc0892efc7dec60bdc27b2ecf6e409062d" + integrity sha512-/PCB2uJ7oM44tz8YhC4Z/6PeOKXp4K588f+5M3clr1M4zbqztlo0XEfJ2LEzj/FgwfgGcIdl8n7YYjTCI0BYwg== dependencies: regenerator-runtime "^0.13.4" @@ -900,6 +1081,15 @@ "@babel/parser" "^7.12.13" "@babel/types" "^7.12.13" +"@babel/template@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.14.5.tgz#a9bc9d8b33354ff6e55a9c60d1109200a68974f4" + integrity sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g== + dependencies: + "@babel/code-frame" "^7.14.5" + "@babel/parser" "^7.14.5" + "@babel/types" "^7.14.5" + "@babel/traverse@^7.13.0", "@babel/traverse@^7.4.5": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.13.0.tgz#6d95752475f86ee7ded06536de309a65fc8966cc" @@ -915,6 +1105,21 @@ globals "^11.1.0" lodash "^4.17.19" +"@babel/traverse@^7.14.5": + version "7.14.7" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.14.7.tgz#64007c9774cfdc3abd23b0780bc18a3ce3631753" + integrity sha512-9vDr5NzHu27wgwejuKL7kIOm4bwEtaPQ4Z6cpCmjSuaRqpH/7xc4qcGEscwMqlkwgcXl6MvqoAjZkQ24uSdIZQ== + dependencies: + "@babel/code-frame" "^7.14.5" + "@babel/generator" "^7.14.5" + "@babel/helper-function-name" "^7.14.5" + "@babel/helper-hoist-variables" "^7.14.5" + "@babel/helper-split-export-declaration" "^7.14.5" + "@babel/parser" "^7.14.7" + "@babel/types" "^7.14.5" + debug "^4.1.0" + globals "^11.1.0" + "@babel/types@^7.12.1", "@babel/types@^7.12.13", "@babel/types@^7.12.17", "@babel/types@^7.13.0", "@babel/types@^7.4.4": version "7.13.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.13.0.tgz#74424d2816f0171b4100f0ab34e9a374efdf7f80" @@ -932,6 +1137,14 @@ "@babel/helper-validator-identifier" "^7.14.0" to-fast-properties "^2.0.0" +"@babel/types@^7.14.5": + 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" + "@date-io/core@1.x", "@date-io/core@^1.3.13": version "1.3.13" resolved "https://registry.yarnpkg.com/@date-io/core/-/core-1.3.13.tgz#90c71da493f20204b7a972929cc5c482d078b3fa" @@ -1326,6 +1539,13 @@ resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.1.1.tgz#3348564048e7a2d7398c935d466c0414ebb6a669" integrity sha512-Z6DoceYb/1xSg5+e+ZlPZ9v0N16ZvZ+wYMraFue4HYrE4ttONKtsvruIRf6t9TBR0YvSOfi1hUU0fJfBLCDYow== +"@types/classnames@^2.2.6": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@types/classnames/-/classnames-2.3.1.tgz#3c2467aa0f1a93f1f021e3b9bcf938bd5dfdc0dd" + integrity sha512-zeOWb0JGBoVmlQoznvqXbE0tEC/HONsnoUNH19Hc96NFsTAwTXbTqb8FMYkru1F/iqp7a18Ws3nWJvtA1sHD1A== + dependencies: + 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" @@ -1405,6 +1625,13 @@ resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24" integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug== +"@types/react-dom@^16.0.11": + version "16.9.13" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.13.tgz#5898f0ee68fe200685e6b61d3d7d8828692814d0" + integrity sha512-34Hr3XnmUSJbUVDxIw/e7dhQn2BJZhJmlAaPyPwfTQyuVS9mV/CeyghFcXyvkJXxI7notQJz8mF8FeCVvloJrA== + dependencies: + "@types/react" "^16" + "@types/react-transition-group@^4.2.0": version "4.4.1" resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.1.tgz#e1a3cb278df7f47f17b5082b1b3da17170bd44b1" @@ -1421,6 +1648,15 @@ "@types/scheduler" "*" csstype "^3.0.2" +"@types/react@^16", "@types/react@^16.7.18": + version "16.14.10" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.10.tgz#76bc1c42ed5ab0d2ab13e5c58faaccaad3449477" + integrity sha512-QadBsMyF6ldjEAXEhsmEW/L0uBDJT8yw7Qoe5sRnEKVrzMkiYoJwqoL5TKJOlArsn/wvIJM/XdVzkdL6+AS64Q== + 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" @@ -1696,7 +1932,12 @@ airbnb-prop-types@^2.16.0: prop-types-exact "^1.2.0" react-is "^16.13.1" -ajv-keywords@^3.5.2: +ajv-errors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== + +ajv-keywords@^3.1.0, ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== @@ -1711,7 +1952,7 @@ ajv@^5.0.0: fast-json-stable-stringify "^2.0.0" json-schema-traverse "^0.3.0" -ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5, ajv@^6.12.6: +ajv@^6.1.0, ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5, ajv@^6.12.6: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -1895,6 +2136,30 @@ asn1@~0.2.3: dependencies: 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== + dependencies: + notificar "^1.0.1" + p-series "^1.1.0" + path-fx "^2.1.1" + +aspen-decorations@^1.0.2, aspen-decorations@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/aspen-decorations/-/aspen-decorations-1.1.1.tgz#7d0ca740efab1aa4fd91a1f3db81ac29186607a3" + integrity sha512-Ej2tv0Gz3bnhkNCyzzjDeG2V5vd49T30ca0SKywHuLA5RKrZ1NutEyZnUYku4WmUV1/TdpHRiSJ759nbZK4xtQ== + dependencies: + notificar "^1.0.1" + +aspen-tree-model@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/aspen-tree-model/-/aspen-tree-model-1.0.5.tgz#23d5ce7a8fb7ab905d37b17b930cc6f92e4d366e" + integrity sha512-kcdL22iAT1sp1HTQ3wJnQqSeA2ANSQiOZJ86RMk9tKBZjb5EFSs2khEFQ6iYE7bvHcWTarGzD7X8XKfxe/zxXg== + dependencies: + aspen-core "^1.0.4" + notificar "^1.0.1" + assert-plus@1.0.0, assert-plus@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" @@ -1918,6 +2183,13 @@ async@0.9.x: resolved "https://registry.yarnpkg.com/async/-/async-0.9.2.tgz#aea74d5e61c1f899613bf64bda66d4c78f2fd17d" integrity sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0= +async@^2.1.4: + version "2.6.3" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" + integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== + dependencies: + lodash "^4.17.14" + async@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/async/-/async-3.2.0.tgz#b3a2685c5ebb641d3de02d161002c60fc9f85720" @@ -2391,6 +2663,14 @@ browser-resolve@^2.0.0: dependencies: resolve "^1.17.0" +browserfs@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/browserfs/-/browserfs-1.4.3.tgz#92ffc6063967612daccdb8566d3fc03f521205fb" + integrity sha512-tz8HClVrzTJshcyIu8frE15cjqjcBIu15Bezxsvl/i+6f59iNCN3kznlWjz0FEb3DlnDx3gW5szxeT6D1x0s0w== + dependencies: + async "^2.1.4" + pako "^1.0.4" + browserify-aes@^1.0.0, browserify-aes@^1.0.4: version "1.2.0" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" @@ -2809,6 +3089,11 @@ circular-json-es6@^2.0.1: resolved "https://registry.yarnpkg.com/circular-json-es6/-/circular-json-es6-2.0.2.tgz#e4f4a093e49fb4b6aba1157365746112a78bd344" integrity sha512-ODYONMMNb3p658Zv+Pp+/XPa5s6q7afhz3Tzyvo+VRh9WIrJ64J76ZC4GQxnlye/NesTn09jvOiuE8+xxfpwhQ== +classnames@*, classnames@^2.2.6: + version "2.3.1" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e" + integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA== + cliui@^7.0.2: version "7.0.4" resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" @@ -3026,6 +3311,13 @@ content-type@~1.0.4: resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== +context-menu@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/context-menu/-/context-menu-2.0.0.tgz#565f13210248e3442700e6b1a2d63406f2b08552" + integrity sha512-VQrkvcJDevuq+sde0QADRLOdIRpa4a1ti4knstrPILDLfWU/RB4ZIGpj32Chh/mURjrbi0CoLT1eonr3X86Khg== + dependencies: + tiny-emitter "^2.0.2" + convert-source-map@^1.1.3, convert-source-map@^1.5.0, convert-source-map@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" @@ -5290,6 +5582,11 @@ inline-style-parser@0.1.1: resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1" integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q== +insert-if@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/insert-if/-/insert-if-1.2.0.tgz#5b878ead294a727eb75598ef8cf9244f33e17157" + integrity sha512-UFXvgVVosbyfa7tsowU8nOLHp/fGe7oGi5vYMy9wEQio8olkf+P7sHssmYnUe991du5EDlD+n/5cW17WgM7Cog== + insert-module-globals@^7.2.1: version "7.2.1" resolved "https://registry.yarnpkg.com/insert-module-globals/-/insert-module-globals-7.2.1.tgz#d5e33185181a4e1f33b15f7bf100ee91890d5cb3" @@ -5535,6 +5832,13 @@ is-regex@^1.1.3: call-bind "^1.0.2" has-symbols "^1.0.2" +is-relative@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-relative/-/is-relative-1.0.0.tgz#a1bb6935ce8c5dba1e8b9754b9b2dcc020e2260d" + integrity sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA== + dependencies: + is-unc-path "^1.0.0" + is-resolvable@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" @@ -5595,6 +5899,13 @@ is-typedarray@~1.0.0: resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= +is-unc-path@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-unc-path/-/is-unc-path-1.0.0.tgz#d731e8898ed090a12c352ad2eaed5095ad322c9d" + integrity sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ== + dependencies: + unc-path-regex "^0.1.2" + is-utf8@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" @@ -6174,7 +6485,7 @@ loader-runner@^4.2.0: resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw== -loader-utils@^1.1.0, loader-utils@^1.4.0: +loader-utils@^1.0.3, loader-utils@^1.1.0, loader-utils@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== @@ -6496,7 +6807,7 @@ mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.19, mime-types@~2.1.24: dependencies: mime-db "1.46.0" -mime@^2.3.1, mime@^2.4.5: +mime@^2.0.3, mime@^2.3.1, mime@^2.4.5: version "2.5.2" resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe" integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg== @@ -6790,6 +7101,11 @@ normalize-url@^4.5.0: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== +notificar@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/notificar/-/notificar-1.0.1.tgz#11ba233c261eee02f5d688ee300ece5f72522887" + integrity sha512-jiCay0IY0N+gloyDks+v4WV+OKU4lIXUhQgxw4Iu9bXpw80cNXTezVv46OCK5+E8G8fkt1Bj76DNepULqlQS3Q== + npm-conf@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9" @@ -7064,6 +7380,14 @@ p-reduce@^1.0.0: resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo= +p-series@^1.0.0, p-series@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-series/-/p-series-1.1.0.tgz#f2d8522cdfd58b464eb9685651d465037ee3c957" + integrity sha512-356covArc9UCfj2twY/sxCJKGMzzO+pJJtucizsPC6aS1xKSTBc9PQrQhvFR3+7F+fa2KBKdJjdIcv6NEWDcIQ== + dependencies: + "@sindresorhus/is" "^0.7.0" + p-reduce "^1.0.0" + p-timeout@^1.1.1: version "1.2.1" resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386" @@ -7083,7 +7407,7 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== -pako@^1.0.0, pako@~1.0.5: +pako@^1.0.0, pako@^1.0.4, pako@~1.0.5: version "1.0.11" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== @@ -7174,6 +7498,13 @@ path-exists@^4.0.0: resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== +path-fx@^2.0.0, path-fx@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/path-fx/-/path-fx-2.1.1.tgz#51594f9f8223d5c1d5b74be55f20a7abb18dc9f6" + integrity sha512-YQeSXseFrHZtxesLJVK4AGv/J3bPmmb0mAMeUbf52b2MVwLlzTEY2NatLP8mUE7eR0F4EBOIRmrQjPPvHZI2+Q== + dependencies: + is-relative "^1.0.0" + path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" @@ -7246,6 +7577,26 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= +"pgadmin4-tree@git+https://github.com/EnterpriseDB/pgadmin4-treeview/#b09740eb89595f99a925aaca9be5afa4be0fa3cc": + version "1.0.0" + resolved "git+https://github.com/EnterpriseDB/pgadmin4-treeview/#b09740eb89595f99a925aaca9be5afa4be0fa3cc" + dependencies: + "@types/classnames" "^2.2.6" + "@types/react" "^16.7.18" + "@types/react-dom" "^16.0.11" + aspen-decorations "^1.1.1" + browserfs "^1.4.3" + classnames "^2.2.6" + context-menu "^2.0.0" + insert-if "^1.1.0" + lodash "4.*" + notificar "^1.0.1" + path-fx "^2.0.0" + react "^16.6.3" + react-aspen "^1.1.1" + react-dom "^16.6.3" + valid-filename "^2.0.1" + picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: version "2.3.0" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" @@ -7782,6 +8133,27 @@ raw-body@2.4.0: iconv-lite "0.4.24" unpipe "1.0.0" +react-aspen@^1.1.0, react-aspen@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/react-aspen/-/react-aspen-1.1.1.tgz#61a85ef43748158322c4a3b73faaa5e563edd038" + integrity sha512-m+r+UIAw29PKgt+2on7zR/fCa7dnvLeM/x2HorGPa39xm4ELHY0PhN0oyE2mO95yqha7mqexD7RXd6iKfVKv7g== + dependencies: + aspen-tree-model "^1.0.5" + notificar "^1.0.1" + p-series "^1.0.0" + path-fx "^2.1.1" + react-window "^1.3.1" + +react-dom@^16.6.3: + version "16.14.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.14.0.tgz#7ad838ec29a777fb3c75c3a190f661cf92ab8b89" + integrity sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + scheduler "^0.19.1" + react-dom@^17.0.1: version "17.0.2" resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" @@ -7869,7 +8241,7 @@ react-virtualized-auto-sizer@^1.0.6: resolved "https://registry.yarnpkg.com/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.6.tgz#66c5b1c9278064c5ef1699ed40a29c11518f97ca" integrity sha512-7tQ0BmZqfVF6YYEWcIGuoR3OdYe8I/ZFbNclFlGOC3pMqunkYF/oL30NCjSGl9sMEb17AnzixDz98Kqc3N76HQ== -react-window@^1.8.5: +react-window@^1.3.1, react-window@^1.8.5: version "1.8.6" resolved "https://registry.yarnpkg.com/react-window/-/react-window-1.8.6.tgz#d011950ac643a994118632665aad0c6382e2a112" integrity sha512-8VwEEYyjz6DCnGBsd+MgkD0KJ2/OXFULyDtorIiTz+QzwoP94tBoA7CnbtyXMm+cCeAUER5KJcPtWl9cpKbOBg== @@ -7877,6 +8249,15 @@ react-window@^1.8.5: "@babel/runtime" "^7.0.0" memoize-one ">=3.1.1 <6" +react@^16.6.3: + version "16.14.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d" + integrity sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + react@^17.0.1: version "17.0.2" resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" @@ -8246,6 +8627,14 @@ sax@^1.2.4, sax@~1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== +scheduler@^0.19.1: + version "0.19.1" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196" + integrity sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + scheduler@^0.20.2: version "0.20.2" resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" @@ -8261,6 +8650,15 @@ schema-utils@^0.3.0: dependencies: ajv "^5.0.0" +schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== + dependencies: + ajv "^6.1.0" + ajv-errors "^1.0.0" + ajv-keywords "^3.1.0" + schema-utils@^2.6.5: version "2.7.1" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" @@ -8963,7 +9361,15 @@ svgicons2svgfont@^9.0.3: string.prototype.codepointat "^0.2.1" svg-pathdata "^5.0.2" -svgo@^1.3.2: +svgo-loader@^2.2.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/svgo-loader/-/svgo-loader-2.2.2.tgz#5f54e3e0d77c36a84c42bcb42e812c4db534bf96" + integrity sha512-UeE/4yZEK96LoYqvxwh8YqCOJCjXwRY9K6YT99vXE+nYhs/W8hAY2hNf5zg/lRsyKshJkR79V+4beV3cbGL40Q== + dependencies: + js-yaml "^3.13.1" + loader-utils "^1.0.3" + +svgo@^1.1.1, svgo@^1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/svgo/-/svgo-1.3.2.tgz#b6dc511c063346c9e415b81e43401145b96d4167" integrity sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw== @@ -9150,6 +9556,11 @@ timsort@^0.3.0: resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= +tiny-emitter@^2.0.2: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423" + integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q== + tiny-warning@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" @@ -9305,6 +9716,11 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= +typescript@^3.2.2: + version "3.9.10" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.10.tgz#70f3910ac7a51ed6bef79da7800690b19bf778b8" + integrity sha512-w6fIxVE/H1PkLKcCPsFqKE7Kv7QUwhU8qQY2MueZXWx5cPZdwFupLgKK3vntcK98BtNHZtAF4LA/yl2a7k8R6Q== + ua-parser-js@^0.7.23: version "0.7.24" resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.24.tgz#8d3ecea46ed4f1f1d63ec25f17d8568105dc027c" @@ -9338,6 +9754,11 @@ unbzip2-stream@^1.0.9: buffer "^5.2.1" through "^2.3.8" +unc-path-regex@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz#e73dd3d7b0d7c5ed86fbac6b0ae7d8c6a69d50fa" + integrity sha1-5z3T17DXxe2G+6xrCufYxqadUPo= + undeclared-identifiers@^1.1.2: version "1.1.3" resolved "https://registry.yarnpkg.com/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz#9254c1d37bdac0ac2b52de4b6722792d2a91e30f" @@ -9409,6 +9830,15 @@ url-join@^4.0.0: resolved "https://registry.yarnpkg.com/url-join/-/url-join-4.0.1.tgz#b642e21a2646808ffa178c4c5fda39844e12cde7" integrity sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA== +url-loader@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-1.1.2.tgz#b971d191b83af693c5e3fea4064be9e1f2d7f8d8" + integrity sha512-dXHkKmw8FhPqu8asTc1puBfe3TehOCo2+RmOOev5suNCIYBcT626kxiWg1NBVkwc4rO8BGa7gP70W7VXuqHrjg== + dependencies: + loader-utils "^1.1.0" + mime "^2.0.3" + schema-utils "^1.0.0" + url-parse-lax@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" @@ -9485,6 +9915,13 @@ v8-compile-cache@^2.0.3, v8-compile-cache@^2.2.0: resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== +valid-filename@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/valid-filename/-/valid-filename-2.0.1.tgz#0768d6f364b1ed3bdf68f0d15abffb0d9d6cecaf" + integrity sha1-B2jW82Sx7TvfaPDRWr/7DZ1s7K8= + dependencies: + filename-reserved-regex "^2.0.0" + validate-npm-package-license@^3.0.1: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a"