diff --git a/templates/web/admin/index.html.twig b/templates/web/admin/index.html.twig index a1cbd08ef7..380a20852a 100644 --- a/templates/web/admin/index.html.twig +++ b/templates/web/admin/index.html.twig @@ -8,202 +8,64 @@ {% endblock %} {% block stylesheet %} - + {% endblock %} {% block javascript %} - {% include "common/templates.html.twig" %} - {# note: Tinymce must be include here without minify else URL resolution for tinymce plugins will fail #} - - - + + {% endblock %} - {% block content %} -
+
+
- {% include 'admin/tree.html.twig' %} + {% include 'admin/tree.html.twig' %}
@@ -217,7 +79,7 @@ {% endif %}
-
+
@@ -245,4 +107,5 @@
+
{% endblock %} diff --git a/www/scripts/apps/admin/main/app.js b/www/scripts/apps/admin/main/app.js new file mode 100644 index 0000000000..34e96cf985 --- /dev/null +++ b/www/scripts/apps/admin/main/app.js @@ -0,0 +1,81 @@ +/* + * This file is part of Phraseanet + * + * (c) 2005-2014 Alchemy + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +define([ + "jquery", + "underscore", + "backbone", + "common/websockets/connection", + "apps/admin/main/views/leftPanel", + "apps/admin/main/views/rightPanel" +], function ($, _, Backbone, WSConnection, LeftPanel, RightPanel) { + window.AdminApp = { + $scope: $("#admin-app"), + $leftView : $(".left-view", this.$scope), + $rightView : $(".right-view", this.$scope), + eventManager: _.extend({}, Backbone.Events) + }; + + var sessionActive = function() { + $.ajax({ + type: "POST", + url: "/session/update/", + dataType: 'json', + data: { + module : 3, + usr : AdminApp.$scope.data("usr") + }, + error: function(){ + window.setTimeout(function() {sessionActive();}, 10000); + }, + timeout: function(){ + window.setTimeout(function() {sessionActive();}, 10000); + }, + success: function(data){ + if(data) { + manageSession(data); + var t = 120000; + if(data.apps && parseInt(data.apps)>1) { + t = Math.round((Math.sqrt(parseInt(data.apps)-1) * 1.3 * 120000)); + } + window.setTimeout(function() {sessionActive();}, t); + } + } + }) + }; + + var initialize = function (options) { + if (false === "wsurl" in options) { + throw "You must define a websocket url"; + } + + if (false === WSConnection.hasSession()) { + WSConnection.connect(options.wsurl); + } + + AdminApp.LeftView = new LeftPanel({ + el: AdminApp.$leftView, + eventManager: AdminApp.eventManager + }); + + AdminApp.RightView = new RightPanel({ + el: AdminApp.$rightView, + eventManager: AdminApp.eventManager + }); + + AdminApp.LeftView.activeTree(); + AdminApp.LeftView.clickSelected(); + + window.setTimeout(function() {sessionActive();}, 15000); + }; + + return { + initialize: initialize + }; +}); diff --git a/www/scripts/apps/admin/main/main.js b/www/scripts/apps/admin/main/main.js new file mode 100644 index 0000000000..c10990db8c --- /dev/null +++ b/www/scripts/apps/admin/main/main.js @@ -0,0 +1,56 @@ +/* + * This file is part of Phraseanet + * + * (c) 2005-2014 Alchemy + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +// configure AMD loading +require.config({ + baseUrl: "/scripts", + paths: { + jquery: "../assets/jquery/jquery", + "jquery.ui": "../assets/jquery.ui/jquery-ui", + underscore: "../assets/underscore-amd/underscore", + backbone: "../assets/backbone-amd/backbone", + "jquery.ui.widget": "../assets/jquery-file-upload/jquery.ui.widget", + "jquery.cookie": "../assets/jquery.cookie/jquery.cookie", + "jquery.treeview": "../assets/jquery.treeview/jquery.treeview", + "jquery.tooltip": "../assets/jquery.tooltip/jquery.tooltip", + "blueimp.loadimage" : "../assets/blueimp-load-image/load-image", + "jfu.iframe-transport": "../assets/jquery-file-upload/jquery.iframe-transport", + "jfu.fileupload": "../assets/jquery-file-upload/jquery.fileupload" + }, + shim: { + "jquery.treeview": { + deps: ['jquery', 'jquery.cookie'], + exports: '$.fn.treeview' + }, + "jquery.cookie": { + deps: ["jquery"], + exports: '$.fn.cookie' + }, + "jquery.tooltip": { + deps: ["jquery"], + exports: '$.fn.tooltip' + }, + "jquery.ui": { + deps: ["jquery"] + }, + "jquery.ui.widget": { + deps: ["jquery"] + }, + "jfu.fileupload": { + deps: ["jquery.ui.widget"] + } + } +}); + +// launch application +require(["jquery", "apps/admin/main/app"], function ($, App) { + App.initialize({ + "wsurl": $("#left").data("websocket") + }); +}); diff --git a/www/scripts/apps/admin/main/views/leftPanel.js b/www/scripts/apps/admin/main/views/leftPanel.js new file mode 100644 index 0000000000..cf98aedc81 --- /dev/null +++ b/www/scripts/apps/admin/main/views/leftPanel.js @@ -0,0 +1,106 @@ +/* + * This file is part of Phraseanet + * + * (c) 2005-2014 Alchemy + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +define([ + "jquery", + "underscore", + "backbone", + "common/websockets/subscriberManager", + "jquery.treeview" +], function ($, _, Backbone, SubscriberManager) { + var LeftPanelView = Backbone.View.extend({ + initialize: function (options) { + if (false === "eventManager" in options) { + throw "You must set en event manager"; + } + this.delegateEvents(this.events); + this.eventManager = options.eventManager; + this.$treeview = $("#FNDR", this.$el); + + var $this = this; + this.eventManager.on("panel:left:success", function(data, click) { + $this.render.append(data); + $this.activeTree(); + if (click) { + $this.clickSelected(); + } + }) + }, + render : function(data) { + this.$treeview.empty().append(data); + }, + events: { + "click a[target=right]": "clickAction" + }, + activeTree: function() { + // tree view jquery module is not loaded as a module + this.$treeview.treeview({ + collapsed: true, + animated: "medium" + }); + }, + clickSelected: function () { + if($('.selected', this.$el).length > 0) { + $('.selected a', this.$el).trigger('click'); + } else { + $('.zone_online_users', this.$el).trigger('click'); + } + }, + reloadTree: function (position, click) { + var $this = this; + $.ajax({ + type: "GET", + url: "/admin/tree/", + data: {position : position}, + success: function(data){ + $this.eventManager.trigger('panel:left:success', data , click) + }, + beforeSend: function(){ + $this.eventManager.trigger('panel:left:beforeSend'); + }, + complete: function(){ + $this.eventManager.trigger('panel:left:complete'); + } + }); + }, + clickAction: function(event) { + event.preventDefault(); + var $this = this; + var link = $(event.currentTarget); + + $.ajax({ + type: "GET", + url: link.attr('href'), + success: function(data) { + $this.eventManager.trigger('panel:right:success', data); + }, + beforeSend: function(){ + $this.eventManager.trigger('panel:right:beforeSend'); + }, + complete: function(){ + $this.eventManager.trigger('panel:right:complete'); + } + }); + + if ("undefined" !== typeof link.data("ws-topic")) { + console.log(link.data("ws-topic")); + SubscriberManager.register(link.data("ws-topic")); + } + + $this.selectLink(link); + link.removeAttr('target'); + }, + selectLink: function(link) { + $('.selected', this.$el).removeClass('selected'); + link.parent().addClass('selected'); + } + }); + + return LeftPanelView; +}); diff --git a/www/scripts/apps/admin/main/views/rightPanel.js b/www/scripts/apps/admin/main/views/rightPanel.js new file mode 100644 index 0000000000..5c91a77bdc --- /dev/null +++ b/www/scripts/apps/admin/main/views/rightPanel.js @@ -0,0 +1,104 @@ +/* + * This file is part of Phraseanet + * + * (c) 2005-2014 Alchemy + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +define([ + "jquery", + "underscore", + "backbone", + "jquery.tooltip", + "blueimp.loadimage", + "jfu.iframe-transport", + "jfu.fileupload", + "jquery.ui" +], function ($, _, Backbone) { + var RightPanelView = Backbone.View.extend({ + initialize: function (options) { + if (false === "eventManager" in options) { + throw "You must set en event manager"; + } + this.delegateEvents(this.events); + this.eventManager = options.eventManager; + + var $this = this; + this.eventManager.on("panel:right:beforeSend", function() { + $this.$el.empty(); + $this.loadingState(true); + }); + this.eventManager.on("panel:right:complete", function() { + $this.loadingState(false); + }); + this.eventManager.on("panel:right:success", function(data) { + $this.render(data); + }) + }, + events: { + "submit form:not(.no-ajax)": "submitAction", + "click a:not(.no-ajax)": "clickAction" + }, + render: function (data) { + this.$el.html(data); + + return this; + }, + clickAction: function(event) { + event.preventDefault(); + var $this = this; + var link = $(event.currentTarget); + var url = link.attr('href'); + + if(url && url.indexOf('#') !== 0) { + $.ajax({ + type: link.attr("method") || "GET", + url: url, + success: function(data) { + $this.eventManager.trigger('panel:right:success', data); + }, + beforeSend: function(){ + $this.eventManager.trigger('panel:right:beforeSend'); + }, + complete: function(){ + $this.eventManager.trigger('panel:right:complete'); + } + }); + } + }, + submitAction: function(event) { + event.preventDefault(); + var $this = this; + var link = $(event.currentTarget); + var url = link.attr('action') || 'GET'; + + if(url) { + $.ajax({ + type: link.attr('method'), + url: url, + data: link.serializeArray(), + success: function (data) { + $this.eventManager.trigger("panel:right:success", data); + }, + beforeSend: function(){ + $this.eventManager.trigger('panel:right:beforeSend'); + }, + complete: function(){ + $this.eventManager.trigger('panel:right:complete'); + } + }); + } + }, + loadingState: function(state) { + if (state) { + this.$el.addClass("loading"); + } else { + this.$el.removeClass("loading"); + } + } + }); + + return RightPanelView; +});