openrat-cms

OpenRat Content Management System
git clone http://git.code.weiherhei.de/openrat-cms.git
Log | Files | Refs | README

common.js (13590B)


      1 import Workbench from "./workbench.js";
      2 import Callback  from "./callback.js";
      3 import Notice    from "./notice.js";
      4 import View      from "./view.js";
      5 import '../jquery-global.js';
      6 
      7 
      8 // Execute after DOM ready:
      9 export default event => {
     10 	// JS is available.
     11 	$('html').removeClass('nojs');
     12 
     13 	/* Fade in all elements. */
     14 	$('.or--initial-hidden').removeClass('-initial-hidden');
     15 
     16 
     17 	registerWorkbenchEvents();
     18 
     19 	// Listening to the "popstate" event:
     20 	window.onpopstate = function (ev) {
     21 		Workbench.getInstance().loadNewActionState(ev.state);
     22 	};
     23 
     24 	Workbench.getInstance().initialize();
     25 
     26 	Workbench.getInstance().reloadAll().then( () => {
     27 			Callback.afterNewActionHandler.fire();
     28 		}
     29 	);
     30 
     31 }
     32 
     33 
     34 
     35 
     36 
     37 /**
     38  * Registriert alle Events, die in der Workbench laufen sollen.
     39  */
     40 function registerWorkbenchEvents() {
     41 
     42 	let registerWorkbenchGlobalEvents = function() {
     43 
     44         // Binding aller Sondertasten.
     45         $('.keystroke').each( function() {
     46             let keystrokeElement = $(this);
     47             let keystroke = keystrokeElement.text();
     48             if (keystroke.length == 0)
     49                 return; // No Keybinding.
     50             let keyaction = function() {
     51                 keystrokeElement.click();
     52             };
     53             // Keybinding ausfuehren.
     54             $(document).bind('keydown', keystroke, keyaction );
     55         } );
     56 
     57     }
     58 
     59     // Initial Notices
     60     $('.or-act-initial-notice').each( function() {
     61 
     62        let notice = new Notice();
     63        notice.setStatus('info');
     64        notice.msg = $(this).text();
     65        notice.show();
     66 
     67        $(this).remove();
     68     });
     69 
     70     registerWorkbenchGlobalEvents();
     71 
     72 
     73     let closeMenu = function() {
     74         // Mit der Maus irgendwo hin geklickt, das Menü muss schließen.
     75         $('body').click( function() {
     76             //$('.toolbar-icon.or-menu-category').parents('.or-menu').removeClass('menu--is-open');
     77             $('.or-menu').removeClass('menu--is-open');
     78         });
     79     };
     80     closeMenu();
     81 
     82     let closeMobileNavigation = function() {
     83         // Mobile navigation must close on a click on the workbench
     84         $('.or-act-navigation-close').click( function() {
     85             $('.or-workbench-navigation').removeClass('workbench-navigation--is-open');
     86 			$('.or-workbench').removeClass('workbench--navigation-is-open');
     87         });
     88     };
     89     closeMobileNavigation();
     90 
     91 	let closeDesktopNavigation = function() {
     92 
     93 		// Handler for desktop navigation
     94 		$('.or-workbench-title .or-act-nav-small').click(function () {
     95 			$('.or-workbench').addClass('workbench--navigation-is-small');
     96 			$('.or-workbench-navigation').addClass('workbench-navigation--is-small');
     97 		});
     98 	};
     99 	closeDesktopNavigation();
    100 
    101 
    102 	let registerGlobalSearch = function() {
    103 		$('.or-search-input .or-input').orSearch( {
    104 			onSearchActive: function() {
    105 				$('.or-search').addClass('search--is-active');
    106 			},
    107 			onSearchInactive: function() {
    108 				$('.or-search').removeClass('search--is-active');
    109 			},
    110 			dropdown    : '.or-act-search-result',
    111 			resultEntryClass: 'or-search-result-entry',
    112 			//openDropdown: true, // the dropdown is automatically opened by the menu.
    113 			select      : function(obj) {
    114 				// open the search result
    115 				Workbench.openNewAction( obj.name, obj.action, obj.id );
    116 			},
    117 			afterSelect: function() {
    118 				//$('.or-dropdown.or-act-selector-search-results').empty();
    119 			}
    120 		} );
    121 		$('.or-search .or-act-search-delete').click( function() {
    122 			$('.or-search .or-title-input').val('').change();
    123 		} );
    124 	};
    125 	registerGlobalSearch();
    126 
    127 
    128 	Callback.afterNewActionHandler.add( function() {
    129 
    130 		$('.or-sidebar').find('.or-sidebar-button').orLinkify();
    131 	  }
    132 	);
    133 
    134 	Callback.afterNewActionHandler.add( function() {
    135 
    136         let url = View.createUrl('tree','path',Workbench.state.id, {'type':Workbench.state.action} );
    137 
    138         // Die Inhalte des Zweiges laden.
    139         let loadPromise = fetch( url );
    140 
    141 		/**
    142 		 * open a object in the navigation tree.
    143 		 * @param action
    144 		 * @param id
    145 		 */
    146 		function openNavTree(action, id) {
    147 			let $navControl = $('.or-link[data-action='+action+'][data-id='+id+']').closest('.or-navtree-node');
    148 			if   ( $navControl.is( '.or-navtree-node--is-closed' ) )
    149 				$navControl.find('.or-navtree-node-control').click();
    150 		}
    151 
    152 		loadPromise
    153 			.then( response => response.text() )
    154 			.then( data => {
    155 
    156 			$('.or-breadcrumb').empty().append( data ).find('.or-act-clickable').orLinkify();
    157 
    158 			// Open the path in the navigator tree
    159 			$('.or-breadcrumb a').each( function () {
    160 				let action = $(this).data('action');
    161 				let id     = $(this).data('id'    );
    162 
    163 				openNavTree( action, id );
    164             });
    165 
    166 			$('.or-link--is-active').removeClass('link--is-active');
    167 
    168 			let action = Workbench.state.action;
    169 			let id     = Workbench.state.id;
    170 			if  (!id) id = '0';
    171 
    172 			// Mark the links to the actual object
    173 			$('.or-link[data-action=\''+action+'\'][data-id=\''+id+'\']').addClass('link--is-active');
    174 			// Open actual object
    175 			openNavTree( action,id );
    176 
    177 		}).catch( cause => {
    178             // Ups... aber was können wir hier schon tun, außer hässliche Meldungen anzeigen.
    179             console.warn( {
    180 				message : 'Failed to load path',
    181 				url     : url,
    182 				cause   : cause } );
    183         }).finally(function () {
    184 
    185         });
    186     } );
    187 
    188 
    189 	let filterMenus = function ()
    190 	{
    191 		let action = Workbench.state.action;
    192 		let id     = Workbench.state.id;
    193 		$('.or-workbench-title .or-dropdown-entry.or-act-clickable').addClass('dropdown-entry--active');
    194 		$('.or-workbench-title .or-filtered').removeClass('dropdown-entry--active').addClass('dropdown-entry--inactive');
    195 		// Jeder Menüeintrag bekommt die Id und Parameter.
    196 		$('.or-workbench-title .or-filtered .or-link').attr('data-id'    ,id    );
    197 
    198 		let url = View.createUrl('profile','available',id, {'queryaction':action},true );
    199 
    200 		// Die Inhalte des Zweiges laden.
    201 		let promise = fetch(url);
    202 
    203 		promise.then( response => response.json() )
    204 			.then( (data) => {
    205 
    206 				for( let method of Object.values(data.output.views) )
    207 					$('.or-workbench-title .or-filtered > .or-link[data-method=\'' + method + '\']' )
    208 						.parent()
    209 						.addClass('dropdown-entry--active')
    210 						.removeClass('dropdown-entry--inactive');
    211 		});
    212 
    213 
    214 	}
    215 
    216 
    217 	Callback.afterAllViewsLoaded.add( function() {
    218 		filterMenus();
    219 	} );
    220 
    221 	Callback.afterAllViewsLoaded.add( function() {
    222 		$('body').removeClass('loader');
    223 	} );
    224 
    225 
    226 
    227 
    228 	Callback.afterViewLoadedHandler.add( function(element) {
    229 		$(element).find('.or-button').orButton();
    230 	} );
    231 
    232 	Callback.afterViewLoadedHandler.add( function(element) {
    233 
    234 		// Refresh already opened popup windows.
    235 		if   ( Workbench.popupWindow )
    236 			$(element).find("a[data-type='popup']").each( function() {
    237 				Workbench.popupWindow.location.href = $(this).attr('data-url');
    238 			});
    239 
    240 	});
    241 
    242 
    243 	Callback.afterViewLoadedHandler.add( function(element) {
    244 
    245 			$(element).find(".or-input--password").dblclick( function() {
    246 				$(this).toggleAttr('type','text','password');
    247 			});
    248 
    249 			$(element).find(".or-act-make-visible").click( function() {
    250 				$(this).toggleClass('btn--is-active' );
    251 				$(this).parent().children('input').toggleAttr('type','text','password');
    252 			});
    253 	});
    254 
    255 
    256 
    257 	Callback.afterViewLoadedHandler.add( function($element) {
    258 
    259 		$element.find('.or-act-load-nav-tree').each( async function() {
    260 
    261 			let type = $(this).data('type') || 'root';
    262 			let loadBranchUrl = './?action=tree&subaction=branch&id=0&type='+type;
    263 			let $targetElement = $(this);
    264 
    265 			let response = await fetch( loadBranchUrl );
    266 			let html     = await response.text();
    267 
    268 			// Den neuen Unter-Zweig erzeugen.
    269 			let $ul = $('<ul class="or-navtree-list" />');
    270 			$ul.appendTo( $targetElement.empty() ).append( html );
    271 
    272 			$ul.find('li').orTree( {
    273 				'openAction': function( name,action,id) {
    274 					Workbench.getInstance().openNewAction( name,action,id );
    275 				}
    276 
    277 			} ); // All subnodes are getting event listener for open/close
    278 
    279 			// Die Navigationspunkte sind anklickbar, hier wird der Standardmechanismus benutzt.
    280 			$ul.find('.or-act-clickable').orLinkify();
    281 
    282 			// Open the first node.
    283 			$ul.find('.or-navtree-node-control').first().click();
    284 
    285 		} );
    286 
    287 	} );
    288 
    289 
    290 
    291 
    292 	/**
    293 	 * Registriert alle Handler für den Inhalt einer View.
    294 	 *
    295 	 * @param viewEl DOM-Element der View
    296 	 */
    297 	Callback.afterViewLoadedHandler.add( function(viewEl ) {
    298 
    299 		// Die Section deaktivieren, wenn die View keinen Inhalt hat.
    300 		var section = $(viewEl).closest('section');
    301 
    302 		//var viewHasContent = $(viewEl).children().length > 0;
    303 		//section.toggleClass('disabled',!viewHasContent);
    304 		section.toggleClass('is-empty',$(viewEl).is(':empty'));
    305 
    306 		/*
    307 		if   ( ! $(viewEl).is(':empty') )
    308 			section.slideDown('fast');
    309 		else
    310 			section.slideUp('fast');*/
    311 
    312 		// Untermenüpunkte aus der View in das Fenstermenü kopieren...
    313 		//$(viewEl).closest('div.panel').find('div.header div.dropdown div.entry.perview').remove(); // Alte Einträge löschen
    314 
    315 		// Handler for mobile navigation
    316 		$(viewEl).find('.or-act-nav-open-close').click( function() {
    317 			$('.or-workbench').toggleClass('workbench--navigation-is-open');
    318 			$('.or-workbench-navigation').toggleClass('workbench-navigation--is-open');
    319 		});
    320 
    321 		// Handler for desktop navigation
    322 		$(viewEl).find('.or-act-nav-small').click( function() {
    323 			$('.or-workbench').addClass('workbench--navigation-is-small');
    324 			$('.or-workbench-navigation').addClass('workbench-navigation--is-small');
    325 		});
    326 		$(viewEl).find('.or-act-nav-wide').click( function() {
    327 			$('.or-workbench').removeClass('workbench--navigation-is-small');
    328 			$('.or-workbench-navigation').removeClass('workbench-navigation--is-small');
    329 		});
    330 
    331 
    332 		// Selectors (Einzel-Ausahl für Dateien) initialisieren
    333 		// Wurzel des Baums laden
    334 		$(viewEl).find('.or-act-selector-tree-button').click( function() {
    335 
    336 			let $selector = $(this).parent('.or-selector');
    337 			let $targetElement = $selector.find('.or-act-load-selector-tree');
    338 
    339 			if   ( $selector.hasClass('selector--is-tree-active') ) {
    340 				$selector.removeClass('selector--is-tree-active');
    341 				$targetElement.empty();
    342 			}
    343 			else {
    344 				$selector.addClass('selector--is-tree-active');
    345 
    346 				var selectorEl = this;
    347 				/*
    348 				$(this).orTree( { type:'project',selectable:$(selectorEl).attr('data-types').split(','),id:$(selectorEl).attr('data-init-folderid'),onSelect:function(name,type,id) {
    349 
    350 					var selector = $(selectorEl).parent();
    351 
    352 					//console.log( 'Selected: '+name+" #"+id );
    353 					$(selector).find('input[type=text]'  ).attr( 'value',name );
    354 					$(selector).find('input[type=hidden]').attr( 'value',id   );
    355 				} });
    356 				*/
    357 
    358 				let id   = $(this).data('init-folder-id');
    359 				let type = id?'folder':'projects';
    360 				let loadBranchUrl = './?action=tree&subaction=branch&id='+id+'&type='+type;
    361 
    362 				let load = fetch( loadBranchUrl );
    363 				load
    364 					.then( response => response.text() )
    365 					.then( html => {
    366 
    367 						// Den neuen Unter-Zweig erzeugen.
    368 						let $ul = $('<ul class="or-navtree-list" />');
    369 						$ul.appendTo( $targetElement ).append( html );
    370 
    371 						$ul.find('li').orTree(
    372 							{
    373 								'openAction' : function(name,action,id) {
    374 									$selector.find('.or-selector-link-value').val(id  );
    375 									$selector.find('.or-selector-link-name' ).val('').attr('placeholder',name);
    376 
    377 									$selector.removeClass('selector--is-tree-active');
    378 									$targetElement.empty();
    379 								}
    380 							}
    381 						); // All subnodes are getting event listener for open/close
    382 
    383 						// Die Navigationspunkte sind anklickbar, hier wird der Standardmechanismus benutzt.
    384 						$ul.find('.or-act-clickable').orLinkify();
    385 
    386 						// Open the first node.
    387 						$ul.find('.or-navtree-node-control').first().click();
    388 					} );
    389 			}
    390 
    391 		} );
    392 
    393 
    394 		registerDragAndDrop(viewEl);
    395 
    396 
    397 		// Theme-Auswahl mit Preview
    398 		$(viewEl).find('.or-theme-chooser').change( function() {
    399 			Workbench.getInstance().setUserStyle( this.value );
    400 		});
    401 
    402 
    403 
    404 
    405 		function registerMenuEvents($element )
    406 		{
    407 			// Mit der Maus geklicktes Menü aktivieren.
    408 			$($element).find('.or-menu-category').click( function(event) {
    409 				event.stopPropagation();
    410 				$(this).parents('.or-menu').toggleClass('menu--is-open');
    411 			});
    412 
    413 			// Mit der Maus überstrichenes Menü aktivieren.
    414 			$($element).find('.or-menu-category').mouseover( function() {
    415 
    416 				// close other menus.
    417 				$(this).parents('.or-menu').find('.or-menu-category').removeClass('menu-category--is-open');
    418 				// open the mouse-overed menu.
    419 				$(this).addClass('menu-category--is-open');
    420 			});
    421 
    422 		}
    423 
    424 
    425 		function registerSelectorSearch( $element )
    426 		{
    427 			$($element).find('.or-act-selector-search').orSearch( {
    428 					onSearchActive: function() {
    429 						$(this).parent('or-selector').addClass('selector-search--is-active');
    430 					},
    431 					onSearchInactive: function() {
    432 						$(this).parent('or-selector').removeClass('selector-search--is-active' );
    433 					},
    434 
    435 					dropdown: '.or-act-selector-search-results',
    436 					resultEntryClass: 'or-search-result-entry',
    437 
    438 					select: function(obj) {
    439 						$($element).find('.or-selector-link-value').val(obj.id  );
    440 						$($element).find('.or-selector-link-name' ).val(obj.name).attr('placeholder',obj.name);
    441 					},
    442 
    443 					afterSelect: function() {
    444 						$('.or-dropdown.or-act-selector-search-results').empty();
    445 					}
    446 			} );
    447 		}
    448 
    449 
    450 
    451 		function registerTree(element) {
    452 
    453 			// Klick-Funktionen zum Öffnen/Schließen des Zweiges.
    454 			//$(element).find('.or-navtree-node').orTree();
    455 
    456 		}
    457 
    458 
    459 		registerMenuEvents    ( viewEl );
    460 		//registerGlobalSearch  ( viewEl );
    461 		registerSelectorSearch( viewEl );
    462 		registerTree          ( viewEl );
    463 
    464 		function registerDragAndDrop(viewEl)
    465 		{
    466 
    467 			Workbench.getInstance().registerDraggable(viewEl);
    468 			Workbench.getInstance().registerDroppable(viewEl);
    469 		}
    470 
    471 		registerDragAndDrop(viewEl);
    472 
    473 
    474 	} );
    475 };
    476