workbench.js (9859B)
1 2 3 Openrat.Workbench = new function() 4 { 5 'use strict'; // Strict mode 6 7 8 this.state = {}; 9 10 11 /** 12 * Initializes the Workbench. 13 */ 14 this.initialize = function() { 15 16 // Initialze Ping timer. 17 this.initializePingTimer(); 18 this.initializeState(); 19 this.openModalDialog(); 20 } 21 22 23 /** 24 * Starts a dialog, if necessary. 25 */ 26 this.openModalDialog = function () { 27 28 if ( $('#dialog').data('action') ) { 29 startDialog('',$('#dialog').data('action'),$('#dialog').data('action'),0,{}) 30 } 31 } 32 33 34 /** 35 * Sets the workbench state with action/id. 36 * 37 * Example: #/name/1 is translated to the state {action:name,id:1} 38 */ 39 this.initializeState = function () { 40 41 let parts = window.location.hash.split('/'); 42 let state = { action:'index',id:0 }; 43 44 if ( parts.length >= 2 ) 45 state.action = parts[1].toLowerCase(); 46 47 if ( parts.length >= 3 ) 48 // Only numbers and '_' allowed in the id. 49 state.id = parts[2].replace(/[^0-9_]/gim,""); 50 51 Openrat.Workbench.state = state; 52 53 // TODO: Remove this sometimes.... only state. 54 $('#editor').attr('data-action',state.action); 55 $('#editor').attr('data-id' ,state.id ); 56 $('#editor').attr('data-extra' ,'{}' ); 57 58 Openrat.Navigator.toActualHistory( state ); 59 60 } 61 62 /** 63 * Registriert den Ping-Timer für den Sitzungserhalt. 64 */ 65 this.initializePingTimer = function() { 66 67 /** 68 * Ping den Server. Führt keine Aktion aus, aber sorgt dafür, dass die Sitzung erhalten bleibt. 69 * 70 * "Geben Sie mir ein Ping, Vasily. Und bitte nur ein einziges Ping!" (aus: Jagd auf Roter Oktober) 71 */ 72 let ping = function() 73 { 74 let pingPromise = $.json( Openrat.View.createUrl('profile','ping',0, {}, true) ); 75 76 pingPromise.fail( function() { 77 console.warn('The server ping has failed.') 78 } ); 79 } 80 81 // Alle 5 Minuten pingen. 82 let timeoutMinutes = 5; 83 84 window.setInterval( ping, timeoutMinutes*60*1000 ); 85 } 86 87 88 89 this.loadNewActionState = function(state) { 90 91 Openrat.Workbench.state = state; 92 Openrat.Workbench.loadNewAction(state.action,state.id,state.data); 93 94 this.afterNewActionHandler.fire(); 95 } 96 97 98 this.afterNewActionHandler = $.Callbacks(); 99 100 101 /** 102 * 103 */ 104 105 this.loadNewAction = function(action, id, params ) { 106 107 $('#editor').attr('data-action',action); 108 $('#editor').attr('data-id' ,id ); 109 $('#editor').attr('data-extra' ,JSON.stringify(params)); 110 111 this.reloadViews(); 112 } 113 114 115 116 /** 117 * 118 */ 119 120 this.reloadViews = function() { 121 122 // View in geschlossenen Sektionen löschen, damit diese nicht stehen bleiben. 123 $('#workbench section.closed .view-loader').empty(); 124 125 Openrat.Workbench.loadViews( $('#workbench section.open .view-loader') ); 126 } 127 128 129 this.reloadAll = function() { 130 131 // View in geschlossenen Sektionen löschen, damit diese nicht stehen bleiben. 132 $('#workbench .view').empty(); 133 134 Openrat.Workbench.loadViews( $('#workbench .view.view-loader, #workbench .view.view-static') ); 135 136 this.loadUserStyle(); 137 this.loadLanguage(); 138 this.loadUISettings(); 139 } 140 141 142 this.loadUserStyle = function() { 143 144 let url = Openrat.View.createUrl('profile','userinfo',0, {},true ); 145 146 // Die Inhalte des Zweiges laden. 147 $.getJSON(url, function (response) { 148 149 let style = response.output['style']; 150 Openrat.Workbench.setUserStyle(style); 151 152 let color = response.output['theme-color']; 153 Openrat.Workbench.setThemeColor(color); 154 }); 155 } 156 157 158 this.settings = {}; 159 this.language = {}; 160 161 this.loadLanguage = function() { 162 163 let url = Openrat.View.createUrl('profile','language',0, {},true ); 164 165 // Die Inhalte des Zweiges laden. 166 $.getJSON(url, function (response) { 167 168 Openrat.Workbench.language = response.output.language; 169 }); 170 } 171 172 this.loadUISettings = function() { 173 174 let url = Openrat.View.createUrl('profile','uisettings',0, {},true ); 175 176 // Die Inhalte des Zweiges laden. 177 $.getJSON(url, function (response) { 178 179 Openrat.Workbench.settings = response.output.settings.settings; 180 }); 181 } 182 183 184 185 this.loadViews = function( $views ) 186 { 187 188 $views.each(function (idx) { 189 190 let $targetDOMElement = $(this); 191 192 Openrat.Workbench.loadNewActionIntoElement( $targetDOMElement ) 193 }); 194 } 195 196 197 198 this.loadNewActionIntoElement = function( $viewElement ) 199 { 200 let action; 201 if ( $viewElement.is('.view-static') ) 202 // Static views have always the same action. 203 action = $viewElement.attr('data-action'); 204 else 205 action = $('#editor').attr('data-action'); 206 207 let id = $('#editor').attr('data-id' ); 208 let params = $('#editor').attr('data-extra' ); 209 210 let method = $viewElement.data('method'); 211 212 let view = new Openrat.View( action,method,id,params ); 213 view.start( $viewElement ); 214 } 215 216 217 218 219 /** 220 * Sets a new theme. 221 * @param styleName 222 */ 223 this.setUserStyle = function( styleName ) 224 { 225 var html = $('html'); 226 var classList = html.attr('class').split(/\s+/); 227 $.each(classList, function(index, item) { 228 if (item.startsWith('theme-')) { 229 html.removeClass(item); 230 } 231 }); 232 html.addClass( 'theme-' + styleName.toLowerCase() ); 233 } 234 235 236 /** 237 * Sets a new theme color. 238 * @param color Theme-color 239 */ 240 this.setThemeColor = function( color ) 241 { 242 $('#theme-color').attr('content',color); 243 } 244 245 246 247 248 /** 249 * Show a notification in the browser. 250 * Source: https://developer.mozilla.org/en-US/docs/Web/API/notification 251 * @param text text of message 252 */ 253 let notifyBrowser = function(text) 254 { 255 // Let's check if the browser supports notifications 256 if (!("Notification" in window)) { 257 return; 258 } 259 260 // Let's check if the user is okay to get some notification 261 else if (Notification.permission === "granted") { 262 // If it's okay let's create a notification 263 let notification = new Notification(text); 264 } 265 266 // Otherwise, we need to ask the user for permission 267 else if (Notification.permission !== 'denied') { 268 Notification.requestPermission(function (permission) { 269 // If the user is okay, let's create a notification 270 if (permission === "granted") { 271 let notification = new Notification(text); 272 } 273 }); 274 } 275 276 // At last, if the user already denied any notification, and you 277 // want to be respectful there is no need to bother them any more. 278 } 279 280 281 282 /** 283 * Show a notice bubble in the UI. 284 * @param type 285 * @param name 286 * @param status 287 * @param msg 288 * @param log 289 */ 290 this.notify = function( type,name,status,msg,log=[],notifyTheBrowser=false ) 291 { 292 // Notice-Bar mit dieser Meldung erweitern. 293 294 if ( notifyTheBrowser ) 295 notifyBrowser( msg ); // Notify browser if wanted. 296 297 let notice = $('<div class="notice '+status+'"></div>'); 298 299 let toolbar = $('<div class="or-notice-toolbar"></div>'); 300 if ( log.length ) 301 $(toolbar).append('<i class="or-action-full image-icon image-icon--menu-fullscreen"></i>'); 302 $(toolbar).append('<i class="or-action-close image-icon image-icon--menu-close"></i>'); 303 $(notice).append(toolbar); 304 305 let id = 0; // TODO id of objects to click on 306 if (name) 307 $(notice).append('<div class="name clickable"><a href="" data-type="open" data-action="'+type+'" data-id="'+id+'"><i class="or-action-full image-icon image-icon--action-'+type+'"></i> '+name+'</a></div>'); 308 309 $(notice).append( '<div class="text">'+htmlEntities(msg)+'</div>'); 310 311 if (log.length) { 312 313 let logLi = log.reduce((result, item) => { 314 result += '<li><pre>'+htmlEntities(item)+'</pre></li>'; 315 return result; 316 }, ''); 317 $(notice).append('<div class="log"><ul>'+logLi+'</ul></div>'); 318 } 319 320 $('#noticebar').prepend(notice); // Notice anhängen. 321 $(notice).orLinkify(); // Enable links 322 323 324 // Toogle Fullscreen for notice 325 $(notice).find('.or-action-full').click( function() { 326 $(notice).toggleClass('full'); 327 }); 328 329 // Close the notice on click 330 $(notice).find('.or-action-close').click( function() { 331 $(notice).fadeOut('fast',function() { $(notice).remove(); } ); 332 }); 333 334 // Fadeout the notice after a while. 335 let timeout = 1; 336 if ( status == 'ok' ) timeout = 20; 337 if ( status == 'info' ) timeout = 60; 338 if ( status == 'warning') timeout = 120; 339 if ( status == 'error' ) timeout = 120; 340 341 if (timeout > 0) 342 setTimeout( function() { 343 $(notice).fadeOut('slow', function() { $(this).remove(); } ); 344 },timeout*1000 ); 345 } 346 347 348 349 this.dataChangedHandler = $.Callbacks(); 350 351 this.dataChangedHandler.add( function() { 352 if ( popupWindow !== undefined ) 353 popupWindow.location.reload(); 354 } ); 355 356 this.afterViewLoadedHandler = $.Callbacks(); 357 358 let afterViewFunctions = []; 359 360 this.registerAfterViewLoaded = function( f ) { 361 afterViewFunctions.push( f ); 362 } 363 364 this.afterViewLoaded = function( element ) { 365 366 afterViewFunctions.forEach( function( f ) { 367 f(element); 368 }); 369 } 370 371 } 372 373