]>
git.proxmox.com Git - proxmox-widget-toolkit.git/blob - Utils.js
2 Ext
. ns ( 'Proxmox.Setup' );
4 // TODO: implement gettext
5 function gettext ( buf
) { return buf
; }
8 if (! Ext
. isDefined ( Proxmox
. Setup
. auth_cookie_name
)) {
9 throw "Proxmox library not initialized" ;
12 // avoid errors related to Accessible Rich Internet Applications
13 // (access for people with disabilities)
14 // TODO reenable after all components are upgraded
15 Ext
. enableAria
= false ;
16 Ext
. enableAriaButtons
= false ;
17 Ext
. enableAriaPanels
= false ;
19 // avoid errors when running without development tools
20 if (! Ext
. isDefined ( Ext
. global
. console
)) {
27 Ext
. Ajax
. defaultHeaders
= {
28 'Accept' : 'application/json'
31 Ext
. Ajax
. on ( 'beforerequest' , function ( conn
, options
) {
32 if ( Proxmox
. CSRFPreventionToken
) {
33 if (! options
. headers
) {
36 options
. headers
. CSRFPreventionToken
= Proxmox
. CSRFPreventionToken
;
40 Ext
. define ( 'Proxmox.Utils' , { utilities
: {
42 // this singleton contains miscellaneous utilities
44 yesText
: gettext ( 'Yes' ),
45 noText
: gettext ( 'No' ),
46 enabledText
: gettext ( 'Enabled' ),
47 disabledText
: gettext ( 'Disabled' ),
48 noneText
: gettext ( 'none' ),
49 errorText
: gettext ( 'Error' ),
50 unknownText
: gettext ( 'Unknown' ),
51 defaultText
: gettext ( 'Default' ),
52 daysText
: gettext ( 'days' ),
53 dayText
: gettext ( 'day' ),
54 runningText
: gettext ( 'running' ),
55 stoppedText
: gettext ( 'stopped' ),
56 neverText
: gettext ( 'never' ),
57 totalText
: gettext ( 'Total' ),
58 usedText
: gettext ( 'Used' ),
59 directoryText
: gettext ( 'Directory' ),
60 stateText
: gettext ( 'State' ),
61 groupText
: gettext ( 'Group' ),
63 getNoSubKeyHtml : function ( url
) {
64 // url http://www.proxmox.com/products/proxmox-ve/subscription-service-plans
65 return Ext
. String
. format ( 'You do not have a valid subscription for this server. Please visit <a target="_blank" href="{0}">www.proxmox.com</a> to get a list of available options.' , url
|| 'http://www.proxmox.com' );
68 format_boolean_with_default : function ( value
) {
69 if ( Ext
. isDefined ( value
) && value
!== '__default__' ) {
70 return value
? Proxmox
. Utils
. yesText
: Proxmox
. Utils
. noText
;
72 return Proxmox
. Utils
. defaultText
;
75 format_boolean : function ( value
) {
76 return value
? Proxmox
. Utils
. yesText
: Proxmox
. Utils
. noText
;
79 format_neg_boolean : function ( value
) {
80 return ! value
? Proxmox
. Utils
. yesText
: Proxmox
. Utils
. noText
;
83 format_enabled_toggle : function ( value
) {
84 return value
? Proxmox
. Utils
. enabledText
: Proxmox
. Utils
. disabledText
;
87 format_expire : function ( date
) {
89 return Proxmox
. Utils
. neverText
;
91 return Ext
. Date
. format ( date
, "Y-m-d" );
94 format_duration_long : function ( ut
) {
96 var days
= Math
. floor ( ut
/ 86400 );
98 var hours
= Math
. floor ( ut
/ 3600 );
100 var mins
= Math
. floor ( ut
/ 60 );
103 var hours_str
= '00' + hours
. toString ();
104 hours_str
= hours_str
. substr ( hours_str
. length
- 2 );
105 var mins_str
= "00" + mins
. toString ();
106 mins_str
= mins_str
. substr ( mins_str
. length
- 2 );
107 var ut_str
= "00" + ut
. toString ();
108 ut_str
= ut_str
. substr ( ut_str
. length
- 2 );
111 var ds
= days
> 1 ? Proxmox
. Utils
. daysText
: Proxmox
. Utils
. dayText
;
112 return days
. toString () + ' ' + ds
+ ' ' +
113 hours_str
+ ':' + mins_str
+ ':' + ut_str
;
115 return hours_str
+ ':' + mins_str
+ ':' + ut_str
;
119 format_duration_short : function ( ut
) {
122 return ut
. toString () + 's' ;
127 return mins
. toFixed ( 0 ) + 'm' ;
131 var hours
= ut
/ 3600 ;
132 return hours
. toFixed ( 0 ) + 'h' ;
135 var days
= ut
/ 86400 ;
136 return days
. toFixed ( 0 ) + 'd' ;
139 format_subscription_level : function ( level
) {
142 } else if ( level
=== 'b' ) {
144 } else if ( level
=== 's' ) {
146 } else if ( level
=== 'p' ) {
149 return Proxmox
. Utils
. noneText
;
153 compute_min_label_width : function ( text
, width
) {
155 if ( width
=== undefined ) { width
= 100 ; }
157 var tm
= new Ext
. util
. TextMetrics ();
158 var min
= tm
. getWidth ( text
+ ':' );
160 return min
< width
? width
: min
;
164 return ( Proxmox
. UserName
!== '' ) && Ext
. util
. Cookies
. get ( Proxmox
. Setup
. auth_cookie_name
);
167 authClear : function () {
168 Ext
. util
. Cookies
. clear ( Proxmox
. Setup
. auth_cookie_name
);
171 // comp.setLoading() is buggy in ExtJS 4.0.7, so we
172 // use el.mask() instead
173 setErrorMask : function ( comp
, msg
) {
182 el
. mask ( gettext ( "Loading..." ));
189 monStoreErrors : function ( me
, store
, clearMaskBeforeLoad
) {
190 if ( clearMaskBeforeLoad
) {
191 me
. mon ( store
, 'beforeload' , function ( s
, operation
, eOpts
) {
192 Proxmox
. Utils
. setErrorMask ( me
, false );
195 me
. mon ( store
, 'beforeload' , function ( s
, operation
, eOpts
) {
197 me
. loadCount
= 0 ; // make sure it is numeric
198 Proxmox
. Utils
. setErrorMask ( me
, true );
203 // only works with 'proxmox' proxy
204 me
. mon ( store
. proxy
, 'afterload' , function ( proxy
, request
, success
) {
208 Proxmox
. Utils
. setErrorMask ( me
, false );
213 /*jslint nomen: true */
214 var operation
= request
. _operation
;
215 var error
= operation
. getError ();
216 if ( error
. statusText
) {
217 msg
= error
. statusText
+ ' (' + error
. status
+ ')' ;
219 msg
= gettext ( 'Connection error' );
221 Proxmox
. Utils
. setErrorMask ( me
, msg
);
225 extractRequestError : function ( result
, verbose
) {
226 var msg
= gettext ( 'Successful' );
228 if (! result
. success
) {
229 msg
= gettext ( "Unknown error" );
230 if ( result
. message
) {
231 msg
= result
. message
;
233 msg
+= ' (' + result
. status
+ ')' ;
236 if ( verbose
&& Ext
. isObject ( result
. errors
)) {
238 Ext
. Object
. each ( result
. errors
, function ( prop
, desc
) {
239 msg
+= "<br><b>" + Ext
. htmlEncode ( prop
) + "</b>: " +
240 Ext
. htmlEncode ( desc
);
249 API2Request : function ( reqOpts
) {
251 var newopts
= Ext
. apply ({
252 waitMsg
: gettext ( 'Please wait...' )
255 if (! newopts
. url
. match ( /^\/api2/ )) {
256 newopts
. url
= '/api2/extjs' + newopts
. url
;
258 delete newopts
. callback
;
260 var createWrapper = function ( successFn
, callbackFn
, failureFn
) {
262 success : function ( response
, options
) {
263 if ( options
. waitMsgTarget
) {
264 options
. waitMsgTarget
. setLoading ( false );
266 var result
= Ext
. decode ( response
. responseText
);
267 response
. result
= result
;
268 if (! result
. success
) {
269 response
. htmlStatus
= Proxmox
. Utils
. extractRequestError ( result
, true );
270 Ext
. callback ( callbackFn
, options
. scope
, [ options
, false , response
]);
271 Ext
. callback ( failureFn
, options
. scope
, [ response
, options
]);
274 Ext
. callback ( callbackFn
, options
. scope
, [ options
, true , response
]);
275 Ext
. callback ( successFn
, options
. scope
, [ response
, options
]);
277 failure : function ( response
, options
) {
278 if ( options
. waitMsgTarget
) {
279 options
. waitMsgTarget
. setLoading ( false );
281 response
. result
= {};
283 response
. result
= Ext
. decode ( response
. responseText
);
285 var msg
= gettext ( 'Connection error' ) + ' - server offline?' ;
286 if ( response
. aborted
) {
287 msg
= gettext ( 'Connection error' ) + ' - aborted.' ;
288 } else if ( response
. timedout
) {
289 msg
= gettext ( 'Connection error' ) + ' - Timeout.' ;
290 } else if ( response
. status
&& response
. statusText
) {
291 msg
= gettext ( 'Connection error' ) + ' ' + response
. status
+ ': ' + response
. statusText
;
293 response
. htmlStatus
= msg
;
294 Ext
. callback ( callbackFn
, options
. scope
, [ options
, false , response
]);
295 Ext
. callback ( failureFn
, options
. scope
, [ response
, options
]);
300 createWrapper ( reqOpts
. success
, reqOpts
. callback
, reqOpts
. failure
);
302 var target
= newopts
. waitMsgTarget
;
304 // Note: ExtJS bug - this does not work when component is not rendered
305 target
. setLoading ( newopts
. waitMsg
);
307 Ext
. Ajax
. request ( newopts
);
310 checked_command : function ( orig_cmd
) {
311 Proxmox
. Utils
. API2Request ({
312 url
: '/nodes/localhost/subscription' ,
315 failure : function ( response
, opts
) {
316 Ext
. Msg
. alert ( gettext ( 'Error' ), response
. htmlStatus
);
318 success : function ( response
, opts
) {
319 var data
= response
. result
. data
;
321 if ( data
. status
!== 'Active' ) {
323 title
: gettext ( 'No valid subscription' ),
324 icon
: Ext
. Msg
. WARNING
,
325 msg
: Proxmox
. Utils
. getNoSubKeyHtml ( data
. url
),
327 callback : function ( btn
) {
341 assemble_field_data : function ( values
, data
) {
342 if ( Ext
. isObject ( data
)) {
343 Ext
. Object
. each ( data
, function ( name
, val
) {
344 if ( values
. hasOwnProperty ( name
)) {
345 var bucket
= values
[ name
];
346 if (! Ext
. isArray ( bucket
)) {
347 bucket
= values
[ name
] = [ bucket
];
349 if ( Ext
. isArray ( val
)) {
350 values
[ name
] = bucket
. concat ( val
);
361 dialog_title : function ( subject
, create
, isAdd
) {
364 return gettext ( 'Add' ) + ': ' + subject
;
366 return gettext ( 'Create' ) + ': ' + subject
;
369 return gettext ( 'Edit' ) + ': ' + subject
;
373 network_iface_types
: {
374 eth
: gettext ( "Network Device" ),
375 bridge
: 'Linux Bridge' ,
377 OVSBridge
: 'OVS Bridge' ,
380 OVSIntPort
: 'OVS IntPort'
383 render_network_iface_type : function ( value
) {
384 return Proxmox
. Utils
. network_iface_types
[ value
] ||
385 Proxmox
. Utils
. unknownText
;
388 // you can override this to provide nicer task descriptions
389 format_task_description : function ( type
, id
) {
390 return type
+ ' ' + id
;
393 render_upid : function ( value
, metaData
, record
) {
394 var type
= record
. data
. type
;
395 var id
= record
. data
. id
;
397 return Proxmox
. Utils
. format_task_description ( type
, id
);
400 render_uptime : function ( value
) {
404 if ( uptime
=== undefined ) {
412 return Proxmox
. Utils
. format_duration_long ( uptime
);
415 parse_task_upid : function ( upid
) {
418 var res
= upid
. match ( /^UPID:(\S+):([0-9A-Fa-f]{8}):([0-9A-Fa-f]{8,9}):([0-9A-Fa-f]{8}):([^:\s]+):([^:\s]*):([^:\s]+):$/ );
420 throw "unable to parse upid '" + upid
+ "'" ;
423 task
. pid
= parseInt ( res
[ 2 ], 16 );
424 task
. pstart
= parseInt ( res
[ 3 ], 16 );
425 task
. starttime
= parseInt ( res
[ 4 ], 16 );
430 task
. desc
= Proxmox
. Utils
. format_task_description ( task
. type
, task
. id
);
435 render_timestamp : function ( value
, metaData
, record
, rowIndex
, colIndex
, store
) {
436 var servertime
= new Date ( value
* 1000 );
437 return Ext
. Date
. format ( servertime
, 'Y-m-d H:i:s' );
443 constructor : function () {
445 Ext
. apply ( me
, me
. utilities
);
447 var IPV4_OCTET
= "(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])" ;
448 var IPV4_REGEXP
= "(?:(?:" + IPV4_OCTET
+ " \\ .){3}" + IPV4_OCTET
+ ")" ;
449 var IPV6_H16
= "(?:[0-9a-fA-F]{1,4})" ;
450 var IPV6_LS32
= "(?:(?:" + IPV6_H16
+ ":" + IPV6_H16
+ ")|" + IPV4_REGEXP
+ ")" ;
453 me
. IP4_match
= new RegExp ( "^(?:" + IPV4_REGEXP
+ ")$" );
454 me
. IP4_cidr_match
= new RegExp ( "^(?:" + IPV4_REGEXP
+ ")\/([0-9]{1,2})$" );
456 var IPV6_REGEXP
= "(?:" +
457 "(?:(?:" + "(?:" + IPV6_H16
+ ":){6})" + IPV6_LS32
+ ")|" +
458 "(?:(?:" + "::" + "(?:" + IPV6_H16
+ ":){5})" + IPV6_LS32
+ ")|" +
459 "(?:(?:(?:" + IPV6_H16
+ ")?::" + "(?:" + IPV6_H16
+ ":){4})" + IPV6_LS32
+ ")|" +
460 "(?:(?:(?:(?:" + IPV6_H16
+ ":){0,1}" + IPV6_H16
+ ")?::" + "(?:" + IPV6_H16
+ ":){3})" + IPV6_LS32
+ ")|" +
461 "(?:(?:(?:(?:" + IPV6_H16
+ ":){0,2}" + IPV6_H16
+ ")?::" + "(?:" + IPV6_H16
+ ":){2})" + IPV6_LS32
+ ")|" +
462 "(?:(?:(?:(?:" + IPV6_H16
+ ":){0,3}" + IPV6_H16
+ ")?::" + "(?:" + IPV6_H16
+ ":){1})" + IPV6_LS32
+ ")|" +
463 "(?:(?:(?:(?:" + IPV6_H16
+ ":){0,4}" + IPV6_H16
+ ")?::" + ")" + IPV6_LS32
+ ")|" +
464 "(?:(?:(?:(?:" + IPV6_H16
+ ":){0,5}" + IPV6_H16
+ ")?::" + ")" + IPV6_H16
+ ")|" +
465 "(?:(?:(?:(?:" + IPV6_H16
+ ":){0,7}" + IPV6_H16
+ ")?::" + ")" + ")" +
468 me
. IP6_match
= new RegExp ( "^(?:" + IPV6_REGEXP
+ ")$" );
469 me
. IP6_cidr_match
= new RegExp ( "^(?:" + IPV6_REGEXP
+ ")\/([0-9]{1,3})$" );
470 me
. IP6_bracket_match
= new RegExp ( "^ \\ [(" + IPV6_REGEXP
+ ") \\ ]" );
472 me
. IP64_match
= new RegExp ( "^(?:" + IPV6_REGEXP
+ "|" + IPV4_REGEXP
+ ")$" );
474 var DnsName_REGEXP
= "(?:(([a-zA-Z0-9]([a-zA-Z0-9 \\ -]*[a-zA-Z0-9])?) \\ .)*([A-Za-z0-9]([A-Za-z0-9 \\ -]*[A-Za-z0-9])?))" ;
475 me
. DnsName_match
= new RegExp ( "^" + DnsName_REGEXP
+ "$" );
477 me
. HostPort_match
= new RegExp ( "^(" + IPV4_REGEXP
+ "|" + DnsName_REGEXP
+ ")(: \\ d+)?$" );
478 me
. HostPortBrackets_match
= new RegExp ( "^ \\ [(?:" + IPV6_REGEXP
+ "|" + IPV4_REGEXP
+ "|" + DnsName_REGEXP
+ ") \\ ](: \\ d+)?$" );
479 me
. IP6_dotnotation_match
= new RegExp ( "^" + IPV6_REGEXP
+ "( \\ . \\ d+)?$" );