]>
git.proxmox.com Git - pve-manager.git/blob - www/manager6/Utils.js
3 // avoid errors related to Accessible Rich Internet Applications
4 // (access for people with disabilities)
5 // TODO reenable after all components are upgraded
6 Ext
. enableAria
= false ;
7 Ext
. enableAriaButtons
= false ;
8 Ext
. enableAriaPanels
= false ;
10 // avoid errors when running without development tools
11 if (! Ext
. isDefined ( Ext
. global
. console
)) {
17 console
. log ( "Starting PVE Manager" );
19 Ext
. Ajax
. defaultHeaders
= {
20 'Accept' : 'application/json'
23 Ext
. define ( 'PVE.Utils' , { utilities
: {
25 // this singleton contains miscellaneous utilities
27 toolkit
: undefined , // (extjs|touch), set inside Toolkit.js
29 bus_match
: /^(ide|sata|virtio|scsi)\d+$/ ,
43 'c' : gettext ( 'Community' ),
44 'b' : gettext ( 'Basic' ),
45 's' : gettext ( 'Standard' ),
46 'p' : gettext ( 'Premium' )
49 noSubKeyHtml
: 'You do not have a valid subscription for this server. Please visit <a target="_blank" href="http://www.proxmox.com/products/proxmox-ve/subscription-service-plans">www.proxmox.com</a> to get a list of available options.' ,
53 { desc
: '4.X/3.X/2.6 Kernel' , val
: 'l26' },
54 { desc
: '2.4 Kernel' , val
: 'l24' }
56 'Microsoft Windows' : [
57 { desc
: '10/2016' , val
: 'win10' },
58 { desc
: '8.x/2012/2012r2' , val
: 'win8' },
59 { desc
: '7/2008r2' , val
: 'win7' },
60 { desc
: 'Vista/2008' , val
: 'w2k8' },
61 { desc
: 'XP/2003' , val
: 'wxp' },
62 { desc
: '2000' , val
: 'w2k' }
65 { desc
: '-' , val
: 'solaris' }
68 { desc
: '-' , val
: 'other' }
72 get_health_icon : function ( state
, circle
) {
73 if ( circle
=== undefined ) {
77 if ( state
=== undefined ) {
81 var icon
= 'faded fa-question' ;
84 icon
= 'good fa-check' ;
87 icon
= 'warning fa-exclamation' ;
90 icon
= 'critical fa-times' ;
104 'HEALTH_WARN' : 'warning' ,
105 'HEALTH_ERR' : 'critical'
108 render_ceph_health : function ( healthObj
) {
110 iconCls
: PVE
. Utils
. get_health_icon (),
114 if (! healthObj
|| ! healthObj
. status
) {
118 var health
= PVE
. Utils
. map_ceph_health
[ healthObj
. status
];
120 state
. iconCls
= PVE
. Utils
. get_health_icon ( health
, true );
121 state
. text
= healthObj
. status
;
126 get_kvm_osinfo : function ( value
) {
127 var info
= { base
: 'Other' }; // default
129 Ext
. each ( Object
. keys ( PVE
. Utils
. kvm_ostypes
), function ( k
) {
130 Ext
. each ( PVE
. Utils
. kvm_ostypes
[ k
], function ( e
) {
131 if ( e
. val
=== value
) {
132 info
= { desc
: e
. desc
, base
: k
};
140 render_kvm_ostype : function ( value
) {
141 var osinfo
= PVE
. Utils
. get_kvm_osinfo ( value
);
142 if ( osinfo
. desc
&& osinfo
. desc
!== '-' ) {
143 return osinfo
. base
+ ' ' + osinfo
. desc
;
149 render_hotplug_features : function ( value
) {
152 if (! value
|| ( value
=== '0' )) {
153 return gettext ( 'Disabled' );
157 value
= 'disk,network,usb' ;
160 Ext
. each ( value
. split ( ',' ), function ( el
) {
162 fa
. push ( gettext ( 'Disk' ));
163 } else if ( el
=== 'network' ) {
164 fa
. push ( gettext ( 'Network' ));
165 } else if ( el
=== 'usb' ) {
167 } else if ( el
=== 'memory' ) {
168 fa
. push ( gettext ( 'Memory' ));
169 } else if ( el
=== 'cpu' ) {
170 fa
. push ( gettext ( 'CPU' ));
176 return fa
. join ( ', ' );
179 render_qemu_bios : function ( value
) {
181 return Proxmox
. Utils
. defaultText
+ ' (SeaBIOS)' ;
182 } else if ( value
=== 'seabios' ) {
184 } else if ( value
=== 'ovmf' ) {
185 return "OVMF (UEFI)" ;
191 render_scsihw : function ( value
) {
193 return Proxmox
. Utils
. defaultText
+ ' (LSI 53C895A)' ;
194 } else if ( value
=== 'lsi' ) {
195 return 'LSI 53C895A' ;
196 } else if ( value
=== 'lsi53c810' ) {
198 } else if ( value
=== 'megasas' ) {
199 return 'MegaRAID SAS 8708EM2' ;
200 } else if ( value
=== 'virtio-scsi-pci' ) {
201 return 'VirtIO SCSI' ;
202 } else if ( value
=== 'virtio-scsi-single' ) {
203 return 'VirtIO SCSI single' ;
204 } else if ( value
=== 'pvscsi' ) {
205 return 'VMware PVSCSI' ;
211 // fixme: auto-generate this
212 // for now, please keep in sync with PVE::Tools::kvmkeymaps
217 'de-ch' : 'German (Swiss)' ,
218 'en-gb' : 'English (UK)' ,
219 'en-us' : 'English (USA)' ,
223 //fo: 'Faroe Islands',
225 'fr-be' : 'French (Belgium)' ,
226 'fr-ca' : 'French (Canada)' ,
227 'fr-ch' : 'French (Swiss)' ,
237 //'nl-be': 'Dutch (Belgium)',
241 'pt-br' : 'Portuguese (Brazil)' ,
250 std
: gettext ( 'Standard VGA' ),
251 vmware
: gettext ( 'VMware compatible' ),
253 qxl2
: 'SPICE dual monitor' ,
254 qxl3
: 'SPICE three monitors' ,
255 qxl4
: 'SPICE four monitors' ,
256 serial0
: gettext ( 'Serial terminal' ) + ' 0' ,
257 serial1
: gettext ( 'Serial terminal' ) + ' 1' ,
258 serial2
: gettext ( 'Serial terminal' ) + ' 2' ,
259 serial3
: gettext ( 'Serial terminal' ) + ' 3'
262 render_kvm_language : function ( value
) {
263 if (! value
|| value
=== '__default__' ) {
264 return Proxmox
. Utils
. defaultText
;
266 var text
= PVE
. Utils
. kvm_keymaps
[ value
];
268 return text
+ ' (' + value
+ ')' ;
273 kvm_keymap_array : function () {
274 var data
= [[ '__default__' , PVE
. Utils
. render_kvm_language ( '' )]];
275 Ext
. Object
. each ( PVE
. Utils
. kvm_keymaps
, function ( key
, value
) {
276 data
. push ([ key
, PVE
. Utils
. render_kvm_language ( value
)]);
282 render_console_viewer : function ( value
) {
283 if (! value
|| value
=== '__default__' ) {
284 return Proxmox
. Utils
. defaultText
+ ' (HTML5)' ;
285 } else if ( value
=== 'vv' ) {
286 return 'SPICE (remote-viewer)' ;
287 } else if ( value
=== 'html5' ) {
288 return 'HTML5 (noVNC)' ;
294 console_viewer_array : function () {
295 return Ext
. Array
. map ([ '__default__' , 'vv' , 'html5' ], function ( v
) {
296 return [ v
, PVE
. Utils
. render_console_viewer ( v
)];
300 render_kvm_vga_driver : function ( value
) {
302 return Proxmox
. Utils
. defaultText
;
304 var text
= PVE
. Utils
. kvm_vga_drivers
[ value
];
306 return text
+ ' (' + value
+ ')' ;
311 kvm_vga_driver_array : function () {
312 var data
= [[ '__default__' , PVE
. Utils
. render_kvm_vga_driver ( '' )]];
313 Ext
. Object
. each ( PVE
. Utils
. kvm_vga_drivers
, function ( key
, value
) {
314 data
. push ([ key
, PVE
. Utils
. render_kvm_vga_driver ( value
)]);
320 render_kvm_startup : function ( value
) {
321 var startup
= PVE
. Parser
. parseStartup ( value
);
324 if ( startup
. order
=== undefined ) {
327 res
+= startup
. order
;
329 if ( startup
. up
!== undefined ) {
330 res
+= ',up=' + startup
. up
;
332 if ( startup
. down
!== undefined ) {
333 res
+= ',down=' + startup
. down
;
339 extractFormActionError : function ( action
) {
341 switch ( action
. failureType
) {
342 case Ext
. form
. action
. Action
. CLIENT_INVALID
:
343 msg
= gettext ( 'Form fields may not be submitted with invalid values' );
345 case Ext
. form
. action
. Action
. CONNECT_FAILURE
:
346 msg
= gettext ( 'Connection error' );
347 var resp
= action
. response
;
348 if ( resp
. status
&& resp
. statusText
) {
349 msg
+= " " + resp
. status
+ ": " + resp
. statusText
;
352 case Ext
. form
. action
. Action
. LOAD_FAILURE
:
353 case Ext
. form
. action
. Action
. SERVER_INVALID
:
354 msg
= Proxmox
. Utils
. extractRequestError ( action
. result
, true );
360 format_duration_short : function ( ut
) {
363 return ut
. toFixed ( 1 ) + 's' ;
368 return mins
. toFixed ( 1 ) + 'm' ;
372 var hours
= ut
/ 3600 ;
373 return hours
. toFixed ( 1 ) + 'h' ;
376 var days
= ut
/ 86400 ;
377 return days
. toFixed ( 1 ) + 'd' ;
380 imagesText
: gettext ( 'Disk image' ),
381 backupFileText
: gettext ( 'VZDump backup file' ),
382 vztmplText
: gettext ( 'Container template' ),
383 isoImageText
: gettext ( 'ISO image' ),
384 containersText
: gettext ( 'Container' ),
386 format_storage_type : function ( value
, md
, record
) {
387 if ( value
=== 'rbd' && record
) {
388 value
= ( record
. get ( 'monhost' )? 'rbd_ext' : 'pveceph' );
390 if ( value
=== 'dir' ) {
391 return Proxmox
. Utils
. directoryText
;
392 } else if ( value
=== 'nfs' ) {
394 } else if ( value
=== 'glusterfs' ) {
396 } else if ( value
=== 'lvm' ) {
398 } else if ( value
=== 'lvmthin' ) {
400 } else if ( value
=== 'iscsi' ) {
402 } else if ( value
=== 'rbd' ) {
404 } else if ( value
=== 'rbd_ext' ) {
405 return 'RBD (external)' ;
406 } else if ( value
=== 'pveceph' ) {
408 } else if ( value
=== 'sheepdog' ) {
410 } else if ( value
=== 'zfs' ) {
411 return 'ZFS over iSCSI' ;
412 } else if ( value
=== 'zfspool' ) {
414 } else if ( value
=== 'iscsidirect' ) {
415 return 'iSCSIDirect' ;
416 } else if ( value
=== 'drbd' ) {
419 return Proxmox
. Utils
. unknownText
;
423 format_ha : function ( value
) {
424 var text
= Proxmox
. Utils
. noneText
;
427 text
= value
. state
|| Proxmox
. Utils
. noneText
;
429 text
+= ', ' + Proxmox
. Utils
. groupText
+ ': ' ;
430 text
+= value
. group
|| Proxmox
. Utils
. noneText
;
436 format_content_types : function ( value
) {
439 Ext
. each ( value
. split ( ',' ). sort (), function ( ct
) {
440 if ( ct
=== 'images' ) {
441 cta
. push ( PVE
. Utils
. imagesText
);
442 } else if ( ct
=== 'backup' ) {
443 cta
. push ( PVE
. Utils
. backupFileText
);
444 } else if ( ct
=== 'vztmpl' ) {
445 cta
. push ( PVE
. Utils
. vztmplText
);
446 } else if ( ct
=== 'iso' ) {
447 cta
. push ( PVE
. Utils
. isoImageText
);
448 } else if ( ct
=== 'rootdir' ) {
449 cta
. push ( PVE
. Utils
. containersText
);
453 return cta
. join ( ', ' );
456 render_storage_content : function ( value
, metaData
, record
) {
457 var data
= record
. data
;
458 if ( Ext
. isNumber ( data
. channel
) &&
459 Ext
. isNumber ( data
. id
) &&
460 Ext
. isNumber ( data
. lun
)) {
462 Ext
. String
. leftPad ( data
. channel
, 2 , '0' ) +
463 " ID " + data
. id
+ " LUN " + data
. lun
;
465 return data
. volid
. replace ( /^.*:(.*\/)?/ , '' );
468 render_serverity : function ( value
) {
469 return PVE
. Utils
. log_severity_hash
[ value
] || value
;
472 render_cpu : function ( value
, metaData
, record
, rowIndex
, colIndex
, store
) {
474 if (!( record
. data
. uptime
&& Ext
. isNumeric ( value
))) {
478 var maxcpu
= record
. data
. maxcpu
|| 1 ;
480 if (! Ext
. isNumeric ( maxcpu
) && ( maxcpu
>= 1 )) {
484 var per
= value
* 100 ;
486 return per
. toFixed ( 1 ) + '% of ' + maxcpu
. toString () + ( maxcpu
> 1 ? 'CPUs' : 'CPU' );
489 render_size : function ( value
, metaData
, record
, rowIndex
, colIndex
, store
) {
490 /*jslint confusion: true */
492 if (! Ext
. isNumeric ( value
)) {
496 return Proxmox
. Utils
. format_size ( value
);
499 render_bandwidth : function ( value
) {
500 if (! Ext
. isNumeric ( value
)) {
504 return Proxmox
. Utils
. format_size ( value
) + '/s' ;
507 render_timestamp_human_readable : function ( value
) {
508 return Ext
. Date
. format ( new Date ( value
* 1000 ), 'l d F Y H:i:s' );
511 render_duration : function ( value
) {
512 if ( value
=== undefined ) {
515 return PVE
. Utils
. format_duration_short ( value
);
518 calculate_mem_usage : function ( data
) {
519 if (! Ext
. isNumeric ( data
. mem
) ||
525 return ( data
. mem
/ data
. maxmem
);
528 render_mem_usage_percent : function ( value
, metaData
, record
, rowIndex
, colIndex
, store
) {
529 if (! Ext
. isNumeric ( value
) || value
=== - 1 ) {
533 // we got no percentage but bytes
535 var maxmem
= record
. data
. maxmem
;
536 if (! record
. data
. uptime
||
538 ! Ext
. isNumeric ( mem
)) {
542 return (( mem
* 100 )/ maxmem
). toFixed ( 1 ) + " %" ;
544 return ( value
* 100 ). toFixed ( 1 ) + " %" ;
547 render_mem_usage : function ( value
, metaData
, record
, rowIndex
, colIndex
, store
) {
550 var maxmem
= record
. data
. maxmem
;
552 if (! record
. data
. uptime
) {
556 if (!( Ext
. isNumeric ( mem
) && maxmem
)) {
560 return PVE
. Utils
. render_size ( value
);
563 calculate_disk_usage : function ( data
) {
565 if (! Ext
. isNumeric ( data
. disk
) ||
566 data
. type
=== 'qemu' ||
567 ( data
. type
=== 'lxc' && data
. uptime
=== 0 ) ||
568 data
. maxdisk
=== 0 ) {
572 return ( data
. disk
/ data
. maxdisk
);
575 render_disk_usage_percent : function ( value
, metaData
, record
, rowIndex
, colIndex
, store
) {
576 if (! Ext
. isNumeric ( value
) || value
=== - 1 ) {
580 return ( value
* 100 ). toFixed ( 1 ) + " %" ;
583 render_disk_usage : function ( value
, metaData
, record
, rowIndex
, colIndex
, store
) {
586 var maxdisk
= record
. data
. maxdisk
;
587 var type
= record
. data
. type
;
589 if (! Ext
. isNumeric ( disk
) ||
592 ( type
=== 'lxc' && record
. data
. uptime
=== 0 )) {
596 return PVE
. Utils
. render_size ( value
);
599 get_object_icon_class : function ( type
, record
) {
603 if ( type
=== 'type' ) {
605 objType
= record
. groupbyid
;
606 } else if ( record
. template
) {
608 objType
= 'template' ;
612 status
= record
. status
+ ' ha-' + record
. hastate
;
615 var defaults
= PVE
. tree
. ResourceTree
. typeDefaults
[ objType
];
616 if ( defaults
&& defaults
. iconCls
) {
617 var retVal
= defaults
. iconCls
+ ' ' + status
;
624 render_resource_type : function ( value
, metaData
, record
, rowIndex
, colIndex
, store
) {
626 var cls
= PVE
. Utils
. get_object_icon_class ( value
, record
. data
);
628 var fa
= '<i class="fa-fw x-grid-icon-custom ' + cls
+ '"></i> ' ;
632 render_support_level : function ( value
, metaData
, record
) {
633 return PVE
. Utils
. support_level_hash
[ value
] || '-' ;
636 render_upid : function ( value
, metaData
, record
) {
637 var type
= record
. data
. type
;
638 var id
= record
. data
. id
;
640 return Proxmox
. Utils
. format_task_description ( type
, id
);
643 /* render functions for new status panel */
645 render_usage : function ( val
) {
646 return ( val
* 100 ). toFixed ( 2 ) + '%' ;
649 render_cpu_usage : function ( val
, max
) {
650 return Ext
. String
. format ( gettext ( '{0}% of {1}' ) +
651 ' ' + gettext ( 'CPU(s)' ), ( val
* 100 ). toFixed ( 2 ), max
);
654 render_size_usage : function ( val
, max
) {
656 return gettext ( 'N/A' );
658 return ( val
* 100 / max
). toFixed ( 2 ) + '% ' + '(' +
659 Ext
. String
. format ( gettext ( '{0} of {1}' ),
660 PVE
. Utils
. render_size ( val
), PVE
. Utils
. render_size ( max
)) + ')' ;
663 /* this is different for nodes */
664 render_node_cpu_usage : function ( value
, record
) {
665 return PVE
. Utils
. render_cpu_usage ( value
, record
. cpus
);
668 /* this is different for nodes */
669 render_node_size_usage : function ( record
) {
670 return PVE
. Utils
. render_size_usage ( record
. used
, record
. total
);
673 windowHostname : function () {
674 return window
. location
. hostname
. replace ( Proxmox
. Utils
. IP6_bracket_match
,
675 function ( m
, addr
, offset
, original
) { return addr
; });
678 openDefaultConsoleWindow : function ( allowSpice
, vmtype
, vmid
, nodename
, vmname
) {
679 var dv
= PVE
. Utils
. defaultViewer ( allowSpice
);
680 PVE
. Utils
. openConsoleWindow ( dv
, vmtype
, vmid
, nodename
, vmname
);
683 openConsoleWindow : function ( viewer
, vmtype
, vmid
, nodename
, vmname
) {
684 // kvm, lxc, shell, upgrade
686 if ( vmid
== undefined && ( vmtype
=== 'kvm' || vmtype
=== 'lxc' )) {
687 throw "missing vmid" ;
691 throw "no nodename specified" ;
694 if ( viewer
=== 'html5' ) {
695 PVE
. Utils
. openVNCViewer ( vmtype
, vmid
, nodename
, vmname
);
696 } else if ( viewer
=== 'xtermjs' ) {
697 Proxmox
. Utils
. openXtermJsViewer ( vmtype
, vmid
, nodename
, vmname
);
698 } else if ( viewer
=== 'vv' ) {
700 var params
= { proxy
: PVE
. Utils
. windowHostname () };
701 if ( vmtype
=== 'kvm' ) {
702 url
= '/nodes/' + nodename
+ '/qemu/' + vmid
. toString () + '/spiceproxy' ;
703 PVE
. Utils
. openSpiceViewer ( url
, params
);
704 } else if ( vmtype
=== 'lxc' ) {
705 url
= '/nodes/' + nodename
+ '/lxc/' + vmid
. toString () + '/spiceproxy' ;
706 PVE
. Utils
. openSpiceViewer ( url
, params
);
707 } else if ( vmtype
=== 'shell' ) {
708 url
= '/nodes/' + nodename
+ '/spiceshell' ;
709 PVE
. Utils
. openSpiceViewer ( url
, params
);
710 } else if ( vmtype
=== 'upgrade' ) {
711 url
= '/nodes/' + nodename
+ '/spiceshell' ;
713 PVE
. Utils
. openSpiceViewer ( url
, params
);
716 throw "unknown viewer type" ;
720 defaultViewer : function ( allowSpice
) {
721 var vncdefault
= 'html5' ;
722 var dv
= PVE
. VersionInfo
. console
|| vncdefault
;
723 if ( dv
=== 'vv' && ! allowSpice
) {
730 openVNCViewer : function ( vmtype
, vmid
, nodename
, vmname
) {
731 var url
= Ext
. urlEncode ({
732 console
: vmtype
, // kvm, lxc, upgrade or shell
738 var nw
= window
. open ( "?" + url
, '_blank' , "innerWidth=745,innerheight=427" );
742 openSpiceViewer : function ( url
, params
){
744 var downloadWithName = function ( uri
, name
) {
745 var link
= Ext
. DomHelper
. append ( document
. body
, {
748 css
: 'display:none;visibility:hidden;height:0px;'
751 // Note: we need to tell android the correct file name extension
752 // but we do not set 'download' tag for other environments, because
753 // It can have strange side effects (additional user prompt on firefox)
754 var andriod
= navigator
. userAgent
. match ( /Android/i ) ? true : false ;
756 link
. download
= name
;
759 if ( link
. fireEvent
) {
760 link
. fireEvent ( 'onclick' );
762 var evt
= document
. createEvent ( "MouseEvents" );
763 evt
. initMouseEvent ( 'click' , true , true , window
, 1 , 0 , 0 , 0 , 0 , false , false , false , false , 0 , null );
764 link
. dispatchEvent ( evt
);
768 Proxmox
. Utils
. API2Request ({
772 failure : function ( response
, opts
){
773 Ext
. Msg
. alert ( 'Error' , response
. htmlStatus
);
775 success : function ( response
, opts
){
776 var raw
= "[virt-viewer] \n " ;
777 Ext
. Object
. each ( response
. result
. data
, function ( k
, v
) {
778 raw
+= k
+ "=" + v
+ " \n " ;
780 var url
= 'data:application/x-virt-viewer;charset=UTF-8,' +
781 encodeURIComponent ( raw
);
783 downloadWithName ( url
, "pve-spice.vv" );
788 openTreeConsole : function ( tree
, record
, item
, index
, e
) {
790 var nodename
= record
. data
. node
;
791 var vmid
= record
. data
. vmid
;
792 var vmname
= record
. data
. name
;
793 if ( record
. data
. type
=== 'qemu' && ! record
. data
. template
) {
794 Proxmox
. Utils
. API2Request ({
795 url
: '/nodes/' + nodename
+ '/qemu/' + vmid
+ '/status/current' ,
796 failure : function ( response
, opts
) {
797 Ext
. Msg
. alert ( 'Error' , response
. htmlStatus
);
799 success : function ( response
, opts
) {
800 var allowSpice
= response
. result
. data
. spice
;
801 PVE
. Utils
. openDefaultConsoleWindow ( allowSpice
, 'kvm' , vmid
, nodename
, vmname
);
804 } else if ( record
. data
. type
=== 'lxc' && ! record
. data
. template
) {
805 PVE
. Utils
. openDefaultConsoleWindow ( true , 'lxc' , vmid
, nodename
, vmname
);
809 // test automation helper
810 call_menu_handler : function ( menu
, text
) {
812 var list
= menu
. query ( 'menuitem' );
814 Ext
. Array
. each ( list
, function ( item
) {
815 if ( item
. text
=== text
) {
826 createCmdMenu : function ( v
, record
, item
, index
, event
) {
828 if (!( v
instanceof Ext
. tree
. View
)) {
833 if ( record
. data
. type
=== 'qemu' && ! record
. data
. template
) {
834 menu
= Ext
. create ( 'PVE.qemu.CmdMenu' , {
837 } else if ( record
. data
. type
=== 'qemu' && record
. data
. template
) {
838 menu
= Ext
. create ( 'PVE.qemu.TemplateMenu' , {
841 } else if ( record
. data
. type
=== 'lxc' && ! record
. data
. template
) {
842 menu
= Ext
. create ( 'PVE.lxc.CmdMenu' , {
845 } else if ( record
. data
. type
=== 'lxc' && record
. data
. template
) {
846 /* since clone does not work reliably, disable for now
847 menu = Ext.create('PVE.lxc.TemplateMenu', {
853 } else if ( record
. data
. type
=== 'node' ){
854 menu
= Ext
. create ( 'PVE.node.CmdMenu' , {
855 nodename
: record
. data
. node
862 menu
. showAt ( event
. getXY ());
865 // helper for deleting field which are set to there default values
866 delete_if_default : function ( values
, fieldname
, default_val
, create
) {
867 if ( values
[ fieldname
] === '' || values
[ fieldname
] === default_val
) {
869 if ( values
[ 'delete' ]) {
870 values
[ 'delete' ] += ',' + fieldname
;
872 values
[ 'delete' ] = fieldname
;
876 delete values
[ fieldname
];
882 constructor : function () {
884 Ext
. apply ( me
, me
. utilities
);