2017-07-18 15:13:16 +01:00
define ( 'misc.depends' , [
2018-01-12 12:59:51 +05:30
'sources/gettext' , 'underscore' , 'underscore.string' , 'jquery' , 'backbone' ,
'pgadmin.browser' , 'pgadmin.alertifyjs' , 'pgadmin.backgrid' ,
] , function ( gettext , _ , S , $ , Backbone , pgBrowser , Alertify , Backgrid ) {
2016-02-22 13:07:16 +00:00
if ( pgBrowser . ShowNodeDepends )
return pgBrowser . ShowNodeDepends ;
2017-07-18 15:13:16 +01:00
var wcDocker = window . wcDocker ;
2016-02-22 13:07:16 +00:00
pgBrowser . ShowNodeDepends = pgBrowser . ShowNodeDepends || { } ;
_ . extend ( pgBrowser . ShowNodeDepends , {
init : function ( ) {
if ( this . initialized ) {
return ;
}
this . initialized = true ;
/ * P a r a m e t e r i s u s e d t o s e t t h e p r o p e r l a b e l o f t h e
* backgrid header cell .
* /
_ . bindAll ( this , 'showDependents' , 'dependentsPanelVisibilityChanged' ,
2018-01-12 12:59:51 +05:30
'showDependencies' , 'dependenciesPanelVisibilityChanged' , '__updateCollection'
2016-02-22 13:07:16 +00:00
) ;
// We will listened to the visibility change of the Dependencies and Dependents panel
pgBrowser . Events . on ( 'pgadmin-browser:panel-dependencies:' + wcDocker . EVENT . VISIBILITY _CHANGED ,
2018-01-12 12:59:51 +05:30
this . dependenciesPanelVisibilityChanged ) ;
2016-02-22 13:07:16 +00:00
pgBrowser . Events . on ( 'pgadmin-browser:panel-dependents:' + wcDocker . EVENT . VISIBILITY _CHANGED ,
2018-01-12 12:59:51 +05:30
this . dependentsPanelVisibilityChanged ) ;
2016-02-22 13:07:16 +00:00
// Defining Backbone Model for Dependencies and Dependents.
var Model = Backbone . Model . extend ( {
defaults : {
icon : 'icon-unknown' ,
type : undefined ,
name : undefined ,
/ * f i e l d c o n t a i n s ' D a t a b a s e N a m e ' f o r ' T a b l e s p a c e a n d R o l e n o d e ' ,
* for other node it contains 'Restriction' .
* /
2018-01-12 12:59:51 +05:30
field : undefined ,
2016-02-22 13:07:16 +00:00
} ,
// This function is used to fetch/set the icon for the type(Function, Role, Database, ....)
parse : function ( res ) {
var node = pgBrowser . Nodes [ res . type ] ;
res . icon = node ? ( _ . isFunction ( node [ 'node_image' ] ) ?
2018-01-12 12:59:51 +05:30
( node [ 'node_image' ] ) . apply ( node , [ null , null ] ) :
( node [ 'node_image' ] || ( 'icon-' + res . type ) ) ) :
( 'icon-' + res . type ) ;
res . type = S . titleize ( res . type . replace ( /_/g , ' ' ) , true ) ;
2016-02-22 13:07:16 +00:00
return res ;
2018-01-12 12:59:51 +05:30
} ,
2016-02-22 13:07:16 +00:00
} ) ;
// Defining Backbone Collection for Dependents.
2018-01-12 12:59:51 +05:30
this . dependentCollection = new ( Backbone . Collection . extend ( {
model : Model ,
2016-02-22 13:07:16 +00:00
} ) ) ( null ) ;
// Defining Backbone Collection for Dependencies.
2018-01-12 12:59:51 +05:30
this . dependenciesCollection = new ( Backbone . Collection . extend ( {
model : Model ,
2016-02-22 13:07:16 +00:00
} ) ) ( null ) ;
var self = this ;
/ * F u n c t i o n i s u s e d t o c r e a t e a n d r e n d e r b a c k g r i d w i t h
* empty collection . We just want to add backgrid into the
* panel only once .
* /
var appendGridToPanel = function ( collection , panel , is _dependent ) {
2016-02-29 19:34:06 +05:30
var $container = panel [ 0 ] . layout ( ) . scene ( ) . find ( '.pg-panel-content' ) ,
2018-01-12 12:59:51 +05:30
$gridContainer = $container . find ( '.pg-panel-depends-container' ) ,
grid = new Backgrid . Grid ( {
columns : [ {
name : 'type' ,
label : gettext ( 'Type' ) ,
// Extend it to render the icon as per the type.
cell : Backgrid . Cell . extend ( {
render : function ( ) {
Backgrid . Cell . prototype . render . apply ( this , arguments ) ;
this . $el . prepend ( $ ( '<i>' , {
class : 'wcTabIcon ' + this . model . get ( 'icon' ) ,
} ) ) ;
return this ;
2016-02-22 13:07:16 +00:00
} ,
2018-01-12 12:59:51 +05:30
} ) ,
editable : false ,
} ,
{
name : 'name' ,
label : gettext ( 'Name' ) ,
cell : 'string' ,
editable : false ,
} ,
{
name : 'field' ,
label : '' , // label kept blank, it will change dynamically
cell : 'string' ,
editable : false ,
} ,
] ,
collection : collection ,
className : 'backgrid presentation table backgrid-striped table-bordered table-hover' ,
} ) ;
2016-02-22 13:07:16 +00:00
// Condition is used to save grid object to change the label of the header.
if ( is _dependent )
self . dependentGrid = grid ;
else
self . dependenciesGrid = grid ;
$gridContainer . append ( grid . render ( ) . el ) ;
2016-02-29 19:34:06 +05:30
return true ;
2016-02-22 13:07:16 +00:00
} ;
2016-02-29 19:34:06 +05:30
// We will listened to the visibility change of the Dependencies and Dependents panel
pgBrowser . Events . on ( 'pgadmin-browser:panel-dependencies:' + wcDocker . EVENT . VISIBILITY _CHANGED ,
2018-01-12 12:59:51 +05:30
this . dependenciesPanelVisibilityChanged ) ;
2016-02-29 19:34:06 +05:30
pgBrowser . Events . on ( 'pgadmin-browser:panel-dependents:' + wcDocker . EVENT . VISIBILITY _CHANGED ,
2018-01-12 12:59:51 +05:30
this . dependentsPanelVisibilityChanged ) ;
2016-08-29 20:06:48 +05:30
pgBrowser . Events . on (
2018-01-12 12:59:51 +05:30
'pgadmin:browser:node:updated' ,
function ( ) {
2016-08-29 20:06:48 +05:30
if ( this . dependenciesPanels && this . dependenciesPanels . length ) {
$ ( this . dependenciesPanels [ 0 ] ) . data ( 'node-prop' , '' ) ;
this . dependenciesPanelVisibilityChanged ( this . dependenciesPanels [ 0 ] ) ;
}
if ( this . dependentsPanels && this . dependentsPanels . length ) {
$ ( this . dependentsPanels [ 0 ] ) . data ( 'node-prop' , '' ) ;
this . dependentsPanelVisibilityChanged ( this . dependentsPanels [ 0 ] ) ;
}
} , this
) ;
2016-02-29 19:34:06 +05:30
// We will render the grid objects in the panel after some time, because -
// it is possible, it is not yet available.
// Find the panels to render the grid.
var dependenciesPanels = this . dependenciesPanels = pgBrowser . docker . findPanels ( 'dependencies' ) ;
var dependentsPanels = this . dependentsPanels = pgBrowser . docker . findPanels ( 'dependents' ) ;
if ( dependenciesPanels . length == 0 ) {
pgBrowser . Events . on (
'pgadmin-browser:panel-dependencies:' + wcDocker . EVENT . INIT ,
function ( ) {
this . dependenciesPanels = pgBrowser . docker . findPanels ( 'dependencies' ) ;
appendGridToPanel ( this . dependenciesCollection , this . dependenciesPanels , false ) ;
// If Dependencies panel exists and is focused then we need to listen the browser tree selection events.
if ( ( dependenciesPanels [ 0 ] . isVisible ( ) ) || dependenciesPanels . length != 1 ) {
2018-01-12 12:59:51 +05:30
pgBrowser . Events . on ( 'pgadmin-browser:tree:selected' , this . showDependencies ) ;
2016-02-29 19:34:06 +05:30
}
} . bind ( this )
2018-01-12 12:59:51 +05:30
) ;
2016-02-29 19:34:06 +05:30
} else {
appendGridToPanel ( this . dependenciesCollection , this . dependenciesPanels , false ) ;
// If Dependencies panel exists and is focused then we need to listen the browser tree selection events.
if ( ( dependenciesPanels [ 0 ] . isVisible ( ) ) || dependenciesPanels . length != 1 ) {
pgBrowser . Events . on ( 'pgadmin-browser:tree:selected' , this . showDependencies ) ;
}
}
if ( dependentsPanels . length == 0 ) {
pgBrowser . Events . on (
'pgadmin-browser:panel-dependents:' + wcDocker . EVENT . INIT ,
function ( ) {
this . dependentsPanels = pgBrowser . docker . findPanels ( 'dependents' ) ;
appendGridToPanel ( this . dependentCollection , this . dependentsPanels , true ) ;
// If Dependents panel exists and is focused then we need to listen the browser tree selection events.
if ( ( dependentsPanels [ 0 ] . isVisible ( ) ) || dependentsPanels . length != 1 ) {
pgBrowser . Events . on ( 'pgadmin-browser:tree:selected' , this . showDependents ) ;
}
} . bind ( this )
2018-01-12 12:59:51 +05:30
) ;
2016-02-29 19:34:06 +05:30
} else {
appendGridToPanel ( this . dependentCollection , this . dependentsPanels , true ) ;
// If Dependents panel exists and is focused then we need to listen the browser tree selection events.
if ( ( dependentsPanels [ 0 ] . isVisible ( ) ) || dependentsPanels . length != 1 ) {
pgBrowser . Events . on ( 'pgadmin-browser:tree:selected' , this . showDependents ) ;
}
}
2016-02-22 13:07:16 +00:00
} ,
// Fetch the actual data and update the collection
2016-06-29 12:16:02 +01:00
_ _updateCollection : function ( collection , panel , url , messages , node , item , type ) {
2016-02-22 13:07:16 +00:00
var msg = messages [ 0 ] ,
2018-01-12 12:59:51 +05:30
$container = panel [ 0 ] . layout ( ) . scene ( ) . find ( '.pg-panel-content' ) ,
$msgContainer = $container . find ( '.pg-panel-depends-message' ) ,
$gridContainer = $container . find ( '.pg-panel-depends-container' ) ,
treeHierarchy = node . getTreeNodeHierarchy ( item ) ,
2018-02-01 14:44:12 +01:00
n _type = type ,
cache _flag = {
node _type : n _type ,
url : url ,
} ;
2016-06-29 12:16:02 +01:00
// Avoid unnecessary reloads
2018-02-01 14:44:12 +01:00
if ( _ . isEqual ( $ ( panel [ 0 ] ) . data ( 'node-prop' ) , cache _flag ) ) {
2016-06-29 12:16:02 +01:00
return ;
}
// Cache the current IDs for next time
2018-02-01 14:44:12 +01:00
$ ( panel [ 0 ] ) . data ( 'node-prop' , cache _flag ) ;
2016-02-22 13:07:16 +00:00
// Hide the grid container and show the default message container
if ( ! $gridContainer . hasClass ( 'hidden' ) )
$gridContainer . addClass ( 'hidden' ) ;
$msgContainer . removeClass ( 'hidden' ) ;
if ( node ) {
msg = messages [ 1 ] ;
/ * W e f e t c h t h e D e p e n d e n c i e s a n d D e p e n d e n t s t a b o n l y f o r
* those node who set the parameter hasDepends to true .
* /
if ( node . hasDepends ) {
/ * S e t t h e m e s s a g e b e c a u s e a j a x r e q u e s t m a y t a k e t i m e t o
* fetch the information from the server .
* /
msg = messages [ 2 ] ;
$msgContainer . text ( msg ) ;
2016-06-29 10:32:20 +01:00
2016-02-22 13:07:16 +00:00
/ * U p d a t i n g t h e l a b e l f o r t h e ' f i e l d ' t y p e o f t h e b a c k b o n e m o d e l .
* Label should be "Database" if the node type is tablespace or role
* and dependent tab is selected . For other nodes and dependencies tab
* it should be 'Restriction' .
* /
if ( this . dependent && ( node . type == 'tablespace' || node . type == 'role' ) )
2018-01-12 12:59:51 +05:30
this . dependentGrid . columns . models [ 2 ] . set ( {
'label' : gettext ( 'Database' ) ,
} ) ;
2016-02-22 13:07:16 +00:00
else {
2018-01-12 12:59:51 +05:30
this . dependenciesGrid . columns . models [ 2 ] . set ( {
'label' : gettext ( 'Restriction' ) ,
} ) ;
this . dependentGrid . columns . models [ 2 ] . set ( {
'label' : gettext ( 'Restriction' ) ,
} ) ;
2016-02-22 13:07:16 +00:00
}
2016-09-26 15:10:38 +01:00
// Hide message container and show grid container.
2016-06-29 12:16:02 +01:00
$msgContainer . addClass ( 'hidden' ) ;
$gridContainer . removeClass ( 'hidden' ) ;
2016-09-26 15:10:38 +01:00
2018-01-12 12:59:51 +05:30
var timer = setTimeout ( function ( ) {
2016-09-26 15:10:38 +01:00
// notify user if request is taking longer than 1 second
2018-01-12 12:59:51 +05:30
$msgContainer . text ( gettext ( 'Retrieving data from the server...' ) ) ;
2016-09-26 15:10:38 +01:00
$msgContainer . removeClass ( 'hidden' ) ;
if ( $gridContainer ) {
$gridContainer . addClass ( 'hidden' ) ;
}
} , 1000 ) ;
2016-02-22 13:07:16 +00:00
// Set the url, fetch the data and update the collection
collection . url = url ;
2016-08-29 11:52:50 +05:30
collection . fetch ( {
reset : true ,
2016-09-26 15:10:38 +01:00
success : function ( ) {
clearTimeout ( timer ) ;
$gridContainer . removeClass ( 'hidden' ) ;
if ( ! $msgContainer . hasClass ( 'hidden' ) ) {
$msgContainer . addClass ( 'hidden' ) ;
}
} ,
2016-08-29 11:52:50 +05:30
error : function ( coll , xhr , error , message ) {
var _label = treeHierarchy [ n _type ] . label ;
pgBrowser . Events . trigger (
2016-08-29 20:06:48 +05:30
'pgadmin:node:retrieval:error' , 'depends' , xhr , error , message
2016-08-29 11:52:50 +05:30
) ;
2018-01-12 12:59:51 +05:30
if ( ! Alertify . pgHandleItemError ( xhr , error , message , {
item : item ,
info : treeHierarchy ,
} ) ) {
2016-08-29 11:52:50 +05:30
Alertify . pgNotifier (
2016-08-29 20:06:48 +05:30
error , xhr ,
2016-08-29 11:52:50 +05:30
S (
2018-01-12 12:59:51 +05:30
gettext ( 'Error retrieving the information - %s' )
2016-08-29 11:52:50 +05:30
) . sprintf ( message || _label ) . value ( ) ,
function ( ) {
2018-01-12 12:59:51 +05:30
console . warn ( arguments ) ;
2016-08-29 11:52:50 +05:30
}
) ;
}
2016-09-26 15:10:38 +01:00
// show failed message.
2018-01-12 12:59:51 +05:30
$msgContainer . text ( gettext ( 'Failed to retrieve data from the server.' ) ) ;
} ,
2016-08-29 11:52:50 +05:30
} ) ;
2016-02-22 13:07:16 +00:00
}
}
if ( msg != '' ) {
$msgContainer . text ( msg ) ;
}
} ,
showDependents : function ( item , data , node ) {
/ * *
* We can ' t start fetching the Dependents immediately , it is possible the user
* is just using the keyboard to select the node , and just traversing
* through . We will wait for some time before fetching the Dependents
* * /
var self = this ;
2016-06-08 12:46:30 +01:00
if ( ! node ) {
return ;
}
2016-02-22 13:07:16 +00:00
self . dependent = true ;
if ( self . timeout ) {
clearTimeout ( self . timeout ) ;
}
2018-01-12 12:59:51 +05:30
self . timeout = setTimeout (
2016-02-22 13:07:16 +00:00
self . _ _updateCollection (
2018-01-12 12:59:51 +05:30
self . dependentCollection , self . dependentsPanels ,
node . generate _url ( item , 'dependent' , data , true ) , [
gettext ( 'No object selected.' ) ,
gettext ( 'No dependent information is available for the current object.' ) ,
gettext ( 'Fetching dependent information from the server...' ) ,
] , node , item , data . _type
2016-02-22 13:07:16 +00:00
) , 400
) ;
} ,
dependentsPanelVisibilityChanged : function ( panel ) {
if ( panel . isVisible ( ) ) {
var t = pgBrowser . tree ,
2018-01-12 12:59:51 +05:30
i = t . selected ( ) ,
d = i && t . itemData ( i ) ,
n = i && d && pgBrowser . Nodes [ d . _type ] ;
2016-02-22 13:07:16 +00:00
pgBrowser . ShowNodeDepends . showDependents . apply ( pgBrowser . ShowNodeDepends , [ i , d , n ] ) ;
// We will start listening the tree selection event.
pgBrowser . Events . on ( 'pgadmin-browser:tree:selected' , pgBrowser . ShowNodeDepends . showDependents ) ;
} else {
// We don't need to listen the tree item selection event.
pgBrowser . Events . off ( 'pgadmin-browser:tree:selected' , pgBrowser . ShowNodeDepends . showDependents ) ;
}
} ,
showDependencies : function ( item , data , node ) {
/ * *
* We can ' t start fetching the Dependencies immediately , it is possible the user
* is just using the keyboard to select the node , and just traversing
* through . We will wait for some time before fetching the Dependencies
* * /
var self = this ;
2016-06-08 12:46:30 +01:00
if ( ! node ) {
return ;
}
2016-02-22 13:07:16 +00:00
self . dependent = false ;
if ( self . timeout ) {
clearTimeout ( self . timeout ) ;
}
2018-01-12 12:59:51 +05:30
self . timeout = setTimeout (
2016-02-22 13:07:16 +00:00
self . _ _updateCollection (
self . dependenciesCollection ,
self . dependenciesPanels ,
2018-01-12 12:59:51 +05:30
node . generate _url ( item , 'dependency' , data , true ) , [ gettext ( 'Please select an object in the tree view.' ) , gettext ( 'No dependency information is available for the current object.' ) ,
gettext ( 'Fetching dependency information from the server...' ) ,
] ,
2016-06-29 12:16:02 +01:00
node ,
item ,
data . _type
2016-02-22 13:07:16 +00:00
) , 400
) ;
} ,
dependenciesPanelVisibilityChanged : function ( panel ) {
if ( panel . isVisible ( ) ) {
var t = pgBrowser . tree ,
2018-01-12 12:59:51 +05:30
i = t . selected ( ) ,
d = i && t . itemData ( i ) ,
n = i && d && pgBrowser . Nodes [ d . _type ] ;
2016-02-22 13:07:16 +00:00
pgBrowser . ShowNodeDepends . showDependencies . apply ( pgBrowser . ShowNodeDepends , [ i , d , n ] ) ;
// We will start listening the tree selection event.
pgBrowser . Events . on ( 'pgadmin-browser:tree:selected' , pgBrowser . ShowNodeDepends . showDependencies ) ;
} else {
// We don't need to listen the tree item selection event.
pgBrowser . Events . off ( 'pgadmin-browser:tree:selected' , pgBrowser . ShowNodeDepends . showDependencies ) ;
}
2018-01-12 12:59:51 +05:30
} ,
2016-02-22 13:07:16 +00:00
} ) ;
return pgBrowser . ShowNodeDepends ;
2018-02-01 14:44:12 +01:00
} ) ;