From 0a0cb86e9f916f913c65da3b8a37bbbee7dd5709 Mon Sep 17 00:00:00 2001 From: Alex Coles Date: Fri, 16 May 2014 17:27:55 +0200 Subject: [PATCH 01/43] Combine ERB partials back into work_packages/index Signed-off-by: Alex Coles --- app/views/work_packages/_list.html.erb | 61 -------------------- app/views/work_packages/_query_form.html.erb | 43 -------------- app/views/work_packages/index.html.erb | 50 ++++++++++++++-- 3 files changed, 46 insertions(+), 108 deletions(-) delete mode 100644 app/views/work_packages/_list.html.erb delete mode 100644 app/views/work_packages/_query_form.html.erb diff --git a/app/views/work_packages/_list.html.erb b/app/views/work_packages/_list.html.erb deleted file mode 100644 index 565201efc2..0000000000 --- a/app/views/work_packages/_list.html.erb +++ /dev/null @@ -1,61 +0,0 @@ -<%#-- copyright -OpenProject is a project management system. -Copyright (C) 2012-2014 the OpenProject Foundation (OPF) - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License version 3. - -OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -Copyright (C) 2006-2013 Jean-Philippe Lang -Copyright (C) 2010-2013 the ChiliProject Team - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -See doc/COPYRIGHT.rdoc for more details. - -++#%> - -<%= form_tag({}) do -%> - -
- - - - - - - - - - - - -
-<% end -%> diff --git a/app/views/work_packages/_query_form.html.erb b/app/views/work_packages/_query_form.html.erb deleted file mode 100644 index be15a3bdbe..0000000000 --- a/app/views/work_packages/_query_form.html.erb +++ /dev/null @@ -1,43 +0,0 @@ -<%#-- copyright -OpenProject is a project management system. -Copyright (C) 2012-2014 the OpenProject Foundation (OPF) - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License version 3. - -OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -Copyright (C) 2006-2013 Jean-Philippe Lang -Copyright (C) 2010-2013 the ChiliProject Team - -This program is free software; you can redistribute it and/or -modify it under the terms of the GNU General Public License -as published by the Free Software Foundation; either version 2 -of the License, or (at your option) any later version. - -This program is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program; if not, write to the Free Software -Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - -See doc/COPYRIGHT.rdoc for more details. - -++#%> - -<%= form_tag({ controller: '/queries', action: 'new' }, id: 'query_form', name: 'queryForm', novalidate: true) do %> - <%= hidden_field_tag('project_id', project.to_param) if project %> - - - -

- - - - <% if query.new_record? && User.current.allowed_to?(:save_queries, project, :global => true) %> - Save - <% end %> -

-<% end %> diff --git a/app/views/work_packages/index.html.erb b/app/views/work_packages/index.html.erb index cdf3a16e04..a5d2fb5b56 100644 --- a/app/views/work_packages/index.html.erb +++ b/app/views/work_packages/index.html.erb @@ -94,13 +94,55 @@ end
<%= error_messages_for 'query' %> - <%= render partial: 'query_form', locals: { project: project, query: query } %> + <%= form_tag({ controller: '/queries', action: 'new' }, id: 'query_form', name: 'queryForm', novalidate: true) do %> + <%= hidden_field_tag('project_id', project.to_param) if project %> + + + +

+ + + + <% if query.new_record? && User.current.allowed_to?(:save_queries, project, :global => true) %> + Save + <% end %> +

+ <% end %>
- <% if query.valid? %> - <%= render :partial => 'work_packages/list', :locals => { :query => query } %> - <% end %> + <%= form_tag({}) do -%> + +
+ + + + + + + + + + + + +
+ <% end -%> <%= call_hook(:view_work_packages_index_bottom, { :project => project, :query => query }) %> From 97f9b1d458e550594cb03d1189cfc96574c29cb2 Mon Sep 17 00:00:00 2001 From: Alex Coles Date: Fri, 16 May 2014 17:40:22 +0200 Subject: [PATCH 02/43] Strip most ERB from work_packages/index view Signed-off-by: Alex Coles --- app/views/work_packages/index.html.erb | 82 ++++++++++++-------------- 1 file changed, 38 insertions(+), 44 deletions(-) diff --git a/app/views/work_packages/index.html.erb b/app/views/work_packages/index.html.erb index a5d2fb5b56..a7a850fb3a 100644 --- a/app/views/work_packages/index.html.erb +++ b/app/views/work_packages/index.html.erb @@ -93,56 +93,50 @@ end
- <%= error_messages_for 'query' %> - <%= form_tag({ controller: '/queries', action: 'new' }, id: 'query_form', name: 'queryForm', novalidate: true) do %> - <%= hidden_field_tag('project_id', project.to_param) if project %> + - +

+ + -

- - - - <% if query.new_record? && User.current.allowed_to?(:save_queries, project, :global => true) %> - Save - <% end %> -

- <% end %> + <%# TODO: serialize permission checks %> + <%# User.current.allowed_to?(:save_queries, project, :global => true) %> + Save + <%# end %> +

- <%= form_tag({}) do -%> - -
- - - - - - - - - - - + +
+ + + + + + + + + + + -
- <% end -%> +
<%= call_hook(:view_work_packages_index_bottom, { :project => project, :query => query }) %> From 541833ca65dd74d03639b14242e873e59cc7a58a Mon Sep 17 00:00:00 2001 From: Alex Coles Date: Fri, 16 May 2014 18:02:13 +0200 Subject: [PATCH 03/43] Move work packages HTML to ng templates directory Include with ng-include only until we have a routing solution in place Signed-off-by: Alex Coles --- app/views/work_packages/index.html.erb | 93 +------------------------- public/templates/work_packages.html | 91 +++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 91 deletions(-) create mode 100644 public/templates/work_packages.html diff --git a/app/views/work_packages/index.html.erb b/app/views/work_packages/index.html.erb index a7a850fb3a..0188541538 100644 --- a/app/views/work_packages/index.html.erb +++ b/app/views/work_packages/index.html.erb @@ -47,97 +47,8 @@ end <%= include_gon %> -
- -
- - - - -
    -
  • -
  • - -
  • -
  • -
-
-
- - - - - -
-
- - -

- - - - <%# TODO: serialize permission checks %> - <%# User.current.allowed_to?(:save_queries, project, :global => true) %> - Save - <%# end %> -

-
-
- - -
- - - - - - - - - - - - -
-
+ + <%= call_hook(:view_work_packages_index_bottom, { :project => project, :query => query }) %> diff --git a/public/templates/work_packages.html b/public/templates/work_packages.html new file mode 100644 index 0000000000..3587b04182 --- /dev/null +++ b/public/templates/work_packages.html @@ -0,0 +1,91 @@ +
+ +
+ + + + +
    +
  • +
  • + +
  • +
  • +
+
+
+ + + + + +
+
+ + +

+ + + + + + Save + +

+
+
+ + +
+ + + + + + + + + + + + +
+
From 09a4d7b9774397e4936a1da53786f953f32729ee Mon Sep 17 00:00:00 2001 From: Christoph Zierz - zzmedia Date: Mon, 19 May 2014 15:35:55 +0200 Subject: [PATCH 04/43] Add styles to settings dropdown-menu - added new styles to the dropdown menu - added icons to menu items --- .../fonts/openproject_icon_font.css.sass | 17 ++++++++++++-- .../stylesheets/layout/_drop_down.css.sass | 23 ++++++++++++++----- app/views/work_packages/index.html.erb | 17 +++++++------- 3 files changed, 41 insertions(+), 16 deletions(-) diff --git a/app/assets/stylesheets/fonts/openproject_icon_font.css.sass b/app/assets/stylesheets/fonts/openproject_icon_font.css.sass index 49ea0fb4a2..0c6859b7c9 100644 --- a/app/assets/stylesheets/fonts/openproject_icon_font.css.sass +++ b/app/assets/stylesheets/fonts/openproject_icon_font.css.sass @@ -67,12 +67,16 @@ font-size: 12px @mixin icon-dropdown-rules - padding: 0 0px 0 3px + padding: 0 0 0 3px font-size: 13px @mixin icon-button-rules - padding: 0 5px 0 0px + padding: 0 5px 0 0 font-size: 13px + +@mixin icon-dropdown-menu-rules + padding: 0 8px 0 0 + font-size: 14px @mixin icon-context-rules padding: 0 4px 0 0 @@ -108,6 +112,11 @@ content: attr(data-icon-dropdown) @include icon-dropdown-rules +[data-icon-dropdown-menu]:before + @include icon-common + content: attr(data-icon-dropdown-menu) + @include icon-dropdown-menu-rules + [data-icon-button]:before @include icon-common content: attr(data-icon-button) @@ -144,6 +153,10 @@ .icon-dropdown:before @include icon-dropdown-rules +// used for icons dropdown-menus +.icon-dropdown-menu:before + @include icon-dropdown-menu-rules + // used for icons in buttons .icon-buttons:before @include icon-button-rules diff --git a/app/assets/stylesheets/layout/_drop_down.css.sass b/app/assets/stylesheets/layout/_drop_down.css.sass index 35595d4903..31f07da0d9 100644 --- a/app/assets/stylesheets/layout/_drop_down.css.sass +++ b/app/assets/stylesheets/layout/_drop_down.css.sass @@ -32,6 +32,10 @@ // https://github.com/plapier/jquery-dropdown // (dual MIT/GPL-Licensed) + +#settingsDropdown + margin: 10px 0 0 0 + .dropdown position: absolute z-index: 9999999 @@ -45,7 +49,7 @@ background: #FFF border: solid 1px #DDD border: solid 1px rgba(0, 0, 0, .2) - border-radius: 6px + border-radius: 0px box-shadow: 0 5px 10px rgba(0, 0, 0, .2) overflow: visible padding: 4px 0 @@ -103,21 +107,28 @@ color: #555 text-decoration: none line-height: 18px - padding: 3px 15px + padding: 3px 32px white-space: nowrap - + .dropdown .dropdown-menu LI > A:hover, .dropdown .dropdown-menu LABEL:hover - background-color: #08C - color: #FFF + background-color: #F0F0F0 cursor: pointer +.dropdown LI > A.dropdown-menu-hasicons + display: block + color: #555 + text-decoration: none + line-height: 18px + padding: 3px 10px + white-space: nowrap + .dropdown .dropdown-menu .dropdown-divider font-size: 1px border-top: solid 1px #E5E5E5 padding: 0 - margin: 5px 0 + margin: 4px 0 /* Icon Examples - icons courtesy of http://p.yusukekamiyamane.com/ */ .dropdown.has-icons LI > A diff --git a/app/views/work_packages/index.html.erb b/app/views/work_packages/index.html.erb index 45d9a9e12d..15a0cf8c7d 100644 --- a/app/views/work_packages/index.html.erb +++ b/app/views/work_packages/index.html.erb @@ -58,9 +58,10 @@ end
    -
  • -
  • -
  • +
  • +
  • +
@@ -77,11 +78,11 @@ end
  • Sorting…
  • Display sums
  • -
  • Save
  • -
  • Save as
  • -
  • Export
  • -
  • Share
  • -
  • Page settings
  • +
  • <%=icon_wrapper("icon-save1 icon-dropdown-menu", "Save")%>Save
  • +
  • <%=icon_wrapper("icon-save1 icon-dropdown-menu", "Save as")%>Save as
  • +
  • <%=icon_wrapper("icon-excel icon-dropdown-menu", "Export")%>Export
  • +
  • <%=icon_wrapper("icon-move icon-dropdown-menu", "Share")%>Share
  • +
  • <%=icon_wrapper("icon-settings3 icon-dropdown-menu", "Page settings")%>Page settings
  • From 7f49e0562ccea6c16f2167d3814eb9e497a28117 Mon Sep 17 00:00:00 2001 From: Alex Coles Date: Tue, 20 May 2014 16:32:38 +0200 Subject: [PATCH 05/43] Reformat openproject module dependencies array Attempt to make the array "patch-friendlier". Signed-off-by: Alex Coles --- app/assets/javascripts/angular/openproject-app.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/angular/openproject-app.js b/app/assets/javascripts/angular/openproject-app.js index bf4615e1a9..13447397a7 100644 --- a/app/assets/javascripts/angular/openproject-app.js +++ b/app/assets/javascripts/angular/openproject-app.js @@ -57,7 +57,17 @@ angular.module('openproject.timeEntries', ['openproject.timeEntries.controllers' angular.module('openproject.timeEntries.controllers', []); // main app -var openprojectApp = angular.module('openproject', ['ui.select2', 'ui.date', 'openproject.uiComponents', 'openproject.timelines', 'openproject.workPackages', 'openproject.messages', 'openproject.timeEntries', 'ngAnimate', 'ngSanitize']); +var openprojectApp = angular.module('openproject', [ + 'ui.select2', + 'ui.date', + 'openproject.uiComponents', + 'openproject.timelines', + 'openproject.workPackages', + 'openproject.messages', + 'openproject.timeEntries', + 'ngAnimate', + 'ngSanitize' +]); window.appBasePath = jQuery('meta[name=app_base_path]').attr('content') || ''; From 21aa9e7dfb6a87d7b5fe788a6e02c8e167b6a7c4 Mon Sep 17 00:00:00 2001 From: Alex Coles Date: Tue, 20 May 2014 16:38:36 +0200 Subject: [PATCH 06/43] Reformat openproject.* module dependencies arrays Attempt to make the arrays "patch-friendlier". Signed-off-by: Alex Coles --- .../javascripts/angular/openproject-app.js | 75 +++++++++++++---- app/assets/javascripts/application.js.erb | 83 ++++++++++--------- 2 files changed, 102 insertions(+), 56 deletions(-) diff --git a/app/assets/javascripts/angular/openproject-app.js b/app/assets/javascripts/angular/openproject-app.js index 13447397a7..e370bbeeb2 100644 --- a/app/assets/javascripts/angular/openproject-app.js +++ b/app/assets/javascripts/angular/openproject-app.js @@ -27,40 +27,85 @@ //++ // global -angular.module('openproject.services', ['openproject.uiComponents', 'openproject.helpers', 'openproject.workPackages.config', 'openproject.workPackages.helpers']); +angular.module('openproject.services', [ + 'openproject.uiComponents', + 'openproject.helpers', + 'openproject.workPackages.config', + 'openproject.workPackages.helpers' +]); angular.module('openproject.helpers', ['openproject.services']); -angular.module('openproject.models', ['openproject.workPackages.config', 'openproject.services']); +angular.module('openproject.models', [ + 'openproject.workPackages.config', + 'openproject.services' +]); // timelines -angular.module('openproject.timelines', ['openproject.timelines.controllers', 'openproject.timelines.directives', 'openproject.uiComponents']); +angular.module('openproject.timelines', [ + 'openproject.timelines.controllers', + 'openproject.timelines.directives', + 'openproject.uiComponents' +]); angular.module('openproject.timelines.models', ['openproject.helpers']); angular.module('openproject.timelines.helpers', []); -angular.module('openproject.timelines.controllers', ['openproject.timelines.models']); -angular.module('openproject.timelines.services', ['openproject.timelines.models', 'openproject.timelines.helpers']); -angular.module('openproject.timelines.directives', ['openproject.timelines.models', 'openproject.timelines.services', 'openproject.uiComponents', 'openproject.helpers']); +angular.module('openproject.timelines.controllers', [ + 'openproject.timelines.models' +]); +angular.module('openproject.timelines.services', [ + 'openproject.timelines.models', + 'openproject.timelines.helpers' +]); +angular.module('openproject.timelines.directives', [ + 'openproject.timelines.models', + 'openproject.timelines.services', + 'openproject.uiComponents', + 'openproject.helpers' +]); // work packages -angular.module('openproject.workPackages', ['openproject.workPackages.controllers', 'openproject.workPackages.filters', 'openproject.workPackages.directives', 'openproject.uiComponents']); +angular.module('openproject.workPackages', [ + 'openproject.workPackages.controllers', + 'openproject.workPackages.filters', + 'openproject.workPackages.directives', + 'openproject.uiComponents' +]); angular.module('openproject.workPackages.services', []); -angular.module('openproject.workPackages.helpers', ['openproject.helpers', 'openproject.workPackages.services']); -angular.module('openproject.workPackages.filters', ['openproject.workPackages.helpers']); +angular.module('openproject.workPackages.helpers', [ + 'openproject.helpers', + 'openproject.workPackages.services' +]); +angular.module('openproject.workPackages.filters', [ + 'openproject.workPackages.helpers' +]); angular.module('openproject.workPackages.config', []); -angular.module('openproject.workPackages.controllers', ['openproject.models', 'openproject.workPackages.helpers', 'openproject.services', 'openproject.workPackages.config', 'btford.modal']); -angular.module('openproject.workPackages.directives', ['openproject.uiComponents', 'openproject.services', 'openproject.workPackages.services', 'ng-context-menu']); +angular.module('openproject.workPackages.controllers', [ + 'openproject.models', + 'openproject.workPackages.helpers', + 'openproject.services', + 'openproject.workPackages.config', + 'btford.modal' +]); +angular.module('openproject.workPackages.directives', [ + 'openproject.uiComponents', + 'openproject.services', + 'openproject.workPackages.services', + 'ng-context-menu' +]); // messages angular.module('openproject.messages', ['openproject.messages.controllers']); angular.module('openproject.messages.controllers', []); // time entries -angular.module('openproject.timeEntries', ['openproject.timeEntries.controllers']); +angular.module('openproject.timeEntries', [ + 'openproject.timeEntries.controllers' +]); angular.module('openproject.timeEntries.controllers', []); // main app var openprojectApp = angular.module('openproject', [ - 'ui.select2', - 'ui.date', - 'openproject.uiComponents', + 'ui.select2', + 'ui.date', + 'openproject.uiComponents', 'openproject.timelines', 'openproject.workPackages', 'openproject.messages', diff --git a/app/assets/javascripts/application.js.erb b/app/assets/javascripts/application.js.erb index 58a97a3239..eb90c47bb7 100644 --- a/app/assets/javascripts/application.js.erb +++ b/app/assets/javascripts/application.js.erb @@ -56,6 +56,7 @@ //= require angular //= require angular-animate //= require angular-modal +//= require angular-ui-router //= require angular-ui-select2 //= require angular-ui-date/src/date //= require angular-sanitize @@ -143,19 +144,19 @@ jQuery(document).ready(function ($) { }); function checkAll (id, checked) { - var els = Element.descendants(id); - for (var i = 0; i < els.length; i++) { + var els = Element.descendants(id); + for (var i = 0; i < els.length; i++) { if (els[i].disabled==false) { els[i].checked = checked; } - } + } } function toggleCheckboxesBySelector(selector) { - boxes = $$(selector); - var all_checked = true; - for (i = 0; i < boxes.length; i++) { if (boxes[i].checked == false) { all_checked = false; } } - for (i = 0; i < boxes.length; i++) { boxes[i].checked = !all_checked; } + boxes = $$(selector); + var all_checked = true; + for (i = 0; i < boxes.length; i++) { if (boxes[i].checked == false) { all_checked = false; } } + for (i = 0; i < boxes.length; i++) { boxes[i].checked = !all_checked; } } function setCheckboxesBySelector(checked, selector) { @@ -166,9 +167,9 @@ function setCheckboxesBySelector(checked, selector) { } function showAndScrollTo(id, focus) { - Element.show(id); - if (focus!=null) { Form.Element.focus(focus); } - Element.scrollTo(id); + Element.show(id); + if (focus!=null) { Form.Element.focus(focus); } + Element.scrollTo(id); } // TODO de-implement once table component has been used @@ -216,9 +217,9 @@ function toggleAllRowGroups(el) { } function hideFieldset(el) { - var fieldset = Element.up(el, 'fieldset'); - fieldset.toggleClassName('collapsed'); - fieldset.down('>div').hide(); + var fieldset = Element.up(el, 'fieldset'); + fieldset.toggleClassName('collapsed'); + fieldset.down('>div').hide(); } var fileFieldCount = 1; @@ -251,10 +252,10 @@ function promptToRemote(text, param, url) { function collapseScmEntry(id) { var els = document.getElementsByClassName(id, 'browser'); - for (var i = 0; i < els.length; i++) { - if (els[i].hasClassName('open')) { - collapseScmEntry(els[i].id); - } + for (var i = 0; i < els.length; i++) { + if (els[i].hasClassName('open')) { + collapseScmEntry(els[i].id); + } Element.hide(els[i]); } $(id).removeClassName('open'); @@ -262,7 +263,7 @@ function collapseScmEntry(id) { function expandScmEntry(id) { var els = document.getElementsByClassName(id, 'browser'); - for (var i = 0; i < els.length; i++) { + for (var i = 0; i < els.length; i++) { Element.show(els[i]); if (els[i].hasClassName('loaded') && !els[i].hasClassName('collapsed')) { expandScmEntry(els[i].id); @@ -296,12 +297,12 @@ function scmEntryLoaded(id) { } function randomKey(size) { - var chars = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'); - var key = ''; - for (i = 0; i < size; i++) { - key += chars[Math.floor(Math.random() * chars.length)]; - } - return key; + var chars = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'); + var key = ''; + for (i = 0; i < size; i++) { + key += chars[Math.floor(Math.random() * chars.length)]; + } + return key; } // Automatic project identifier generation @@ -681,27 +682,27 @@ jQuery(document).ready(function($) { }); }); - // file table thumbnails - $("table a.has-thumb").hover(function() { - $(this).removeAttr("title").toggleClass("active"); + // file table thumbnails + $("table a.has-thumb").hover(function() { + $(this).removeAttr("title").toggleClass("active"); - // grab the image dimensions to position it properly - var thumbImg = $(this).find("img"); - var thumbImgLeft = -(thumbImg.outerWidth() ); - var thumbImgTop = -(thumbImg.height() / 2 ); - thumbImg.css({top: thumbImgTop, left: thumbImgLeft}).show(); + // grab the image dimensions to position it properly + var thumbImg = $(this).find("img"); + var thumbImgLeft = -(thumbImg.outerWidth() ); + var thumbImgTop = -(thumbImg.height() / 2 ); + thumbImg.css({top: thumbImgTop, left: thumbImgLeft}).show(); - }, function() { - $(this).toggleClass("active").find("img").hide(); - }); + }, function() { + $(this).toggleClass("active").find("img").hide(); + }); - // show/hide the files table - $(".attachments h4").click(function() { - $(this).toggleClass("closed").next().slideToggle(animationRate); - }); + // show/hide the files table + $(".attachments h4").click(function() { + $(this).toggleClass("closed").next().slideToggle(animationRate); + }); - // deal with potentially problematic super-long titles - $(".title-bar h2").css({paddingRight: $(".title-bar-actions").outerWidth() + 15 }); + // deal with potentially problematic super-long titles + $(".title-bar h2").css({paddingRight: $(".title-bar-actions").outerWidth() + 15 }); $(window).resize(function() { // wait 200 milliseconds for no further resize event From fec8c75000a8716cbbfbf2a04cc6d7a0dcd72b18 Mon Sep 17 00:00:00 2001 From: Alex Coles Date: Tue, 20 May 2014 13:51:52 +0200 Subject: [PATCH 07/43] Add AngularUI Router for client-side routing Signed-off-by: Alex Coles --- bower.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bower.json b/bower.json index 4339b9e3c6..1af210674c 100644 --- a/bower.json +++ b/bower.json @@ -23,7 +23,8 @@ "mocha": "~1.14.0", "angular-mocks": "~1.2.14", "angular-scenario": "~1.2.14", - "chai": "~1.9.0" + "chai": "~1.9.0", + "angular-ui-router": "~0.2.10" }, "resolutions": { "select2": "3.3.2" From 5209e04c4f63525a1e2af0a323712984c5127e81 Mon Sep 17 00:00:00 2001 From: Alex Coles Date: Tue, 20 May 2014 16:46:04 +0200 Subject: [PATCH 08/43] Create initial work package list/detail routing Integrate angular-ui-router, adding nested template structure. Add separate Rails layout that renders minimal "chrome" for Angular. User Story # 7570 Signed-off-by: Alex Coles --- .../javascripts/angular/openproject-app.js | 4 + app/assets/javascripts/angular/routing.js | 53 +++++++ app/controllers/work_packages_controller.rb | 2 +- app/views/layouts/angular.html.erb | 143 ++++++++++++++++++ app/views/work_packages/index.html.erb | 3 +- public/templates/work_packages.html | 29 +--- .../templates/work_packages.list.details.html | 3 + public/templates/work_packages.list.html | 31 ++++ 8 files changed, 238 insertions(+), 30 deletions(-) create mode 100644 app/assets/javascripts/angular/routing.js create mode 100644 app/views/layouts/angular.html.erb create mode 100644 public/templates/work_packages.list.details.html create mode 100644 public/templates/work_packages.list.html diff --git a/app/assets/javascripts/angular/openproject-app.js b/app/assets/javascripts/angular/openproject-app.js index e370bbeeb2..5fac66eb41 100644 --- a/app/assets/javascripts/angular/openproject-app.js +++ b/app/assets/javascripts/angular/openproject-app.js @@ -105,6 +105,7 @@ angular.module('openproject.timeEntries.controllers', []); var openprojectApp = angular.module('openproject', [ 'ui.select2', 'ui.date', + 'ui.router', 'openproject.uiComponents', 'openproject.timelines', 'openproject.workPackages', @@ -116,6 +117,9 @@ var openprojectApp = angular.module('openproject', [ window.appBasePath = jQuery('meta[name=app_base_path]').attr('content') || ''; +// FIXME: replace with actual data +window.gon = { project_types: [] }; + openprojectApp .config(['$locationProvider', '$httpProvider', function($locationProvider, $httpProvider) { // Note: Not using this because we want to use $location to get the url params and html5Mode prevents all the links from working normally. diff --git a/app/assets/javascripts/angular/routing.js b/app/assets/javascripts/angular/routing.js new file mode 100644 index 0000000000..aa9da766f4 --- /dev/null +++ b/app/assets/javascripts/angular/routing.js @@ -0,0 +1,53 @@ +//-- copyright +// OpenProject is a project management system. +// Copyright (C) 2012-2014 the OpenProject Foundation (OPF) +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License version 3. +// +// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +// Copyright (C) 2006-2013 Jean-Philippe Lang +// Copyright (C) 2010-2013 the ChiliProject Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// See doc/COPYRIGHT.rdoc for more details. +//++ + +openprojectApp.config(['$stateProvider', '$urlRouterProvider', + function($stateProvider, $urlRouterProvider) { + + $urlRouterProvider.otherwise("/wp"); + + $stateProvider + .state('work-packages', { + url: "/wp", + templateUrl: "/templates/work_packages.html" + }) + .state('work-packages.list', { + url: "/list", + templateUrl: "/templates/work_packages.list.html", + controller: function($scope) { + // + } + }) + .state('work-packages.list.details', { + url: "/details", + templateUrl: "/templates/work_packages.list.details.html", + controller: function($scope) { + // + } + }) +}]); diff --git a/app/controllers/work_packages_controller.rb b/app/controllers/work_packages_controller.rb index f182e85fae..8cb6da7d2a 100644 --- a/app/controllers/work_packages_controller.rb +++ b/app/controllers/work_packages_controller.rb @@ -206,7 +206,7 @@ class WorkPackagesController < ApplicationController format.html do render :index, :locals => { :query => @query, :project => @project }, - :layout => !request.xhr? + :layout => 'angular' # !request.xhr? end format.csv do serialized_work_packages = WorkPackage::Exporter.csv(@work_packages, @project) diff --git a/app/views/layouts/angular.html.erb b/app/views/layouts/angular.html.erb new file mode 100644 index 0000000000..a654252fc8 --- /dev/null +++ b/app/views/layouts/angular.html.erb @@ -0,0 +1,143 @@ +<%#-- copyright +OpenProject is a project management system. +Copyright (C) 2012-2014 the OpenProject Foundation (OPF) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License version 3. + +OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +Copyright (C) 2006-2013 Jean-Philippe Lang +Copyright (C) 2010-2013 the ChiliProject Team + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +See doc/COPYRIGHT.rdoc for more details. + +++#%> +<% show_decoration = params["layout"].nil? %> + + + +<%= html_title %> + + + + + +<%= csrf_meta_tags %> +<%= favicon_link_tag 'favicon.ico' %> +<%= stylesheet_link_tag current_theme.stylesheet_manifest, :media => "all" %> +<% if User.current.impaired? && accessibility_css_enabled? %> + <%= stylesheet_link_tag 'accessibility' %> +<% end %> + +<%= javascript_include_tag 'application' %> +<%= javascript_include_tag 'angular-i18n/angular-locale_de-de' if I18n.locale == :de %> + +<%= user_specific_javascript_includes %> + +<%= call_hook :view_layouts_base_html_head %> + +<%= content_for(:header_tags) if content_for?(:header_tags) %> + + + +<% main_menu = render_main_menu(@project) %> +<% side_displayed = content_for?(:sidebar) || content_for?(:main_menu) || !main_menu.blank? %> + +
    <%= (show_decoration) ? '' : 'nomenus' %>"> + <% if show_decoration %> +
    + +
    + <% end %> + +
    <%= (show_decoration) ? '' : 'nomenus' %>"> + <% if (side_displayed && show_decoration) %> + + <% end %> + + <% if show_decoration %> + + <% end %> + +
    <%= (show_decoration) ? '' : 'nomenus' %>" id="content"> + +
    + + <%= call_hook :view_layouts_base_content %> +
     
    +
    +
    + + <% if (show_decoration) %> + + <% end %> + + + +
    +<%= call_hook :view_layouts_base_body_bottom %> + + diff --git a/app/views/work_packages/index.html.erb b/app/views/work_packages/index.html.erb index 0188541538..eb613beaa9 100644 --- a/app/views/work_packages/index.html.erb +++ b/app/views/work_packages/index.html.erb @@ -47,8 +47,7 @@ end <%= include_gon %> - - + <%= call_hook(:view_work_packages_index_bottom, { :project => project, :query => query }) %> diff --git a/public/templates/work_packages.html b/public/templates/work_packages.html index 3587b04182..615f3cdc67 100644 --- a/public/templates/work_packages.html +++ b/public/templates/work_packages.html @@ -17,6 +17,7 @@ Filter +
  • @@ -59,33 +60,7 @@ -
    - - +
    - - - - - - - - -
    diff --git a/public/templates/work_packages.list.details.html b/public/templates/work_packages.list.details.html new file mode 100644 index 0000000000..ea93c0a38b --- /dev/null +++ b/public/templates/work_packages.list.details.html @@ -0,0 +1,3 @@ +

    TODO: details panel goes here

    + + diff --git a/public/templates/work_packages.list.html b/public/templates/work_packages.list.html new file mode 100644 index 0000000000..fb485a624c --- /dev/null +++ b/public/templates/work_packages.list.html @@ -0,0 +1,31 @@ +
    + + + + + + + + + + + + +
    + +
    From 1011b4a4e754115ada496c63791a4ecd7c6cd7c2 Mon Sep 17 00:00:00 2001 From: Alex Coles Date: Tue, 20 May 2014 18:42:45 +0200 Subject: [PATCH 09/43] Show both list/details buttons in toolbar (requires styling - this should appear as a segmented control) Signed-off-by: Alex Coles --- public/templates/work_packages.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/public/templates/work_packages.html b/public/templates/work_packages.html index 615f3cdc67..7a8aa75182 100644 --- a/public/templates/work_packages.html +++ b/public/templates/work_packages.html @@ -17,7 +17,10 @@ Filter -
  • +
  • + + +
  • From 4018b5bb7b1bdb2ff055e98808749530cb78ae13 Mon Sep 17 00:00:00 2001 From: Alex Coles Date: Tue, 20 May 2014 13:35:21 +0200 Subject: [PATCH 10/43] Apply new styles to work packages table Signed-off-by: Alex Coles --- public/templates/work_packages.list.html | 1 - .../work_packages/work_packages_table.html | 16 +++++++++------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/public/templates/work_packages.list.html b/public/templates/work_packages.list.html index fb485a624c..a660249d72 100644 --- a/public/templates/work_packages.list.html +++ b/public/templates/work_packages.list.html @@ -11,7 +11,6 @@ display-sums="query.displaySums" total-sums="totalSums" group-sums="groupSums" - class="list issues" update-results="updateResults()" with-loading="withLoading" update-back-url="updateBackUrl"> diff --git a/public/templates/work_packages/work_packages_table.html b/public/templates/work_packages/work_packages_table.html index eb2da3db9f..58ead97301 100644 --- a/public/templates/work_packages/work_packages_table.html +++ b/public/templates/work_packages/work_packages_table.html @@ -1,4 +1,4 @@ - +
    - + + + @@ -146,7 +148,7 @@ - + From 0dc35ef38bbf1fb71115079c468cf7f4ac299fa0 Mon Sep 17 00:00:00 2001 From: Alex Coles Date: Tue, 20 May 2014 19:40:26 +0200 Subject: [PATCH 11/43] [wip] Wire up info button to display wp details Signed-off-by: Alex Coles --- app/assets/javascripts/angular/routing.js | 19 +++++++++++++++---- .../templates/work_packages.list.details.html | 9 +++++++++ .../work_packages/work_packages_table.html | 2 +- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/angular/routing.js b/app/assets/javascripts/angular/routing.js index aa9da766f4..24ec42628c 100644 --- a/app/assets/javascripts/angular/routing.js +++ b/app/assets/javascripts/angular/routing.js @@ -44,10 +44,21 @@ openprojectApp.config(['$stateProvider', '$urlRouterProvider', } }) .state('work-packages.list.details', { - url: "/details", + url: "/:workPackageId", templateUrl: "/templates/work_packages.list.details.html", - controller: function($scope) { - // - } + controller: ['$scope', '$stateParams', + function($scope, $stateParams) { + $scope.workPackageId = $stateParams.workPackageId + + $scope.$watch('rows', function(rows){ + if (rows && rows.length > 0) { + var row = $scope.rows.find(function(row) { + return row.object.id == $scope.workPackageId; + }); + $scope.workPackage = row ? row.object : {}; + } + }); + + }] }) }]); diff --git a/public/templates/work_packages.list.details.html b/public/templates/work_packages.list.details.html index ea93c0a38b..b8372836cd 100644 --- a/public/templates/work_packages.list.details.html +++ b/public/templates/work_packages.list.details.html @@ -1,3 +1,12 @@ +
    + +

    {{ workPackage.type.name }}

    +

    {{ workPackage.subject }}

    TODO: details panel goes here

    +

    Debug

    +
    +{{ workPackage | json }}
    +
    + diff --git a/public/templates/work_packages/work_packages_table.html b/public/templates/work_packages/work_packages_table.html index 58ead97301..beaa1b1eed 100644 --- a/public/templates/work_packages/work_packages_table.html +++ b/public/templates/work_packages/work_packages_table.html @@ -102,7 +102,7 @@
    @@ -11,7 +11,7 @@ icon-name="yes"> - + 0 && 'child idnt' || '', row.level > 0 && ('idnt-' + row.level) || '' @@ -103,6 +101,10 @@ model="row.checked"/> +

    +
    @@ -132,7 +134,7 @@ 'issue', 'work_package' ]"> - + {{ I18n.t('js.label_sum_for') }}
    {{ I18n.t('js.label_sum_for') }} {{ I18n.t('js.label_all_work_packages') }}{{ I18n.t('js.label_sum_for') }} {{ I18n.t('js.label_all_work_packages') }} {{ column.total_sum }} -

    +

    From fc4735591b215e9964b2d5f1e40142d3582b1d73 Mon Sep 17 00:00:00 2001 From: Christoph Zierz - zzmedia Date: Tue, 20 May 2014 19:54:24 +0200 Subject: [PATCH 12/43] Add styles for headings h1 h2 h3 h4 - added styles for headlines h1, h2, h3, h4 --- app/assets/stylesheets/content/_headings.md | 12 +++++++ app/assets/stylesheets/content/_headings.sass | 12 +++++++ app/assets/stylesheets/global/_mixins.sass | 34 +++++++++++++++++++ app/assets/stylesheets/global/_variables.sass | 9 +++++ 4 files changed, 67 insertions(+) diff --git a/app/assets/stylesheets/content/_headings.md b/app/assets/stylesheets/content/_headings.md index 7ab8b064b8..b37bc18c1d 100644 --- a/app/assets/stylesheets/content/_headings.md +++ b/app/assets/stylesheets/content/_headings.md @@ -1 +1,13 @@ # Headings + +``` +

    Headline H1

    +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem.

    +

    Headline H2

    +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem.

    +

    Headline H3

    +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem.

    +

    Headline H4

    +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem.

    + +``` diff --git a/app/assets/stylesheets/content/_headings.sass b/app/assets/stylesheets/content/_headings.sass index 935f07e7cc..57ac1501e7 100644 --- a/app/assets/stylesheets/content/_headings.sass +++ b/app/assets/stylesheets/content/_headings.sass @@ -29,3 +29,15 @@ #content h2 padding-right: 340px + + +h1 + @include default-headline-h1 +h2 + @include default-headline-h2 +h3 + @include default-headline-h3 +h4 + @include default-headline-h4 + + \ No newline at end of file diff --git a/app/assets/stylesheets/global/_mixins.sass b/app/assets/stylesheets/global/_mixins.sass index 2991f196a0..a902c67c0f 100644 --- a/app/assets/stylesheets/global/_mixins.sass +++ b/app/assets/stylesheets/global/_mixins.sass @@ -37,6 +37,40 @@ $button_gray_font_color: #222222 @each $vendor in $vendors #{$vendor}transition: all 200ms ease-in-out 0s +@mixin default-headline-h1 + color: $headline_h1_font-color + font-size: $headline_h1_font_size + font-family: $font_family_normal + font-weight: normal + padding: 0 0 8px 0 + margin: 0 + +@mixin default-headline-h2 + color: $headline_h2_font-color + font-size: $headline_h2_font_size + font-family: $font_family_normal + font-weight: normal + text-transform: uppercase + padding: 0 0 8px 0 + margin: 0 + +@mixin default-headline-h3 + color: $headline_h3_font-color + font-size: $headline_h3_font_size + font-family: $font_family_normal + font-weight: normal + border-bottom: 1px solid #dddddd + padding: 0 0 8px 0 + margin: 0 0 20px 0 + +@mixin default-headline-h4 + color: $headline_h4_font-color + font-size: $headline_h4_font_size + font-family: $font_family_normal + font-weight: normal + padding: 0 0 5px 0 + margin: 0 0 20px 0 + @mixin default-font-normal($color, $font-size: 13px) color: $color font-size: $font-size diff --git a/app/assets/stylesheets/global/_variables.sass b/app/assets/stylesheets/global/_variables.sass index a497618d1c..6fc951b8a9 100644 --- a/app/assets/stylesheets/global/_variables.sass +++ b/app/assets/stylesheets/global/_variables.sass @@ -30,6 +30,15 @@ $global_font_color: #555555 !default $global_font_size: 13px !default $global_line_height: 1.5 !default +$headline_h1_font_size: 28px !default +$headline_h1_font-color: #555555 !default +$headline_h2_font_size: 22px !default +$headline_h2_font-color: #06799F !default +$headline_h3_font_size: 19px !default +$headline_h3_font-color: #555555 !default +$headline_h4_font_size: 17px !default +$headline_h4_font-color: #555555 !default + $header_height: 55px !default $header_bg_color: #3493B3 !default $header_border_bottom_color: #3493B3 !default From b21ccda101dc398d0a4ddb523094e33c31d1635c Mon Sep 17 00:00:00 2001 From: Richard Date: Wed, 14 May 2014 16:14:55 +0200 Subject: [PATCH 13/43] WIP Made a basic sort dialog which is wired up to queries service set sortation. Once the refactor is done and the wp table is wired directly to the query then hopefully this should update the sortation. --- .../angular/controllers/dialogs/sorting.js | 31 ++++++++++++- .../angular/services/query-service.js | 4 ++ .../work_packages/modals/sorting.html | 44 +++++++++++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/angular/controllers/dialogs/sorting.js b/app/assets/javascripts/angular/controllers/dialogs/sorting.js index 99d6e2e8e0..331830a205 100644 --- a/app/assets/javascripts/angular/controllers/dialogs/sorting.js +++ b/app/assets/javascripts/angular/controllers/dialogs/sorting.js @@ -36,7 +36,36 @@ angular.module('openproject.workPackages.controllers') }); }]) -.controller('SortingModalController', ['sortingModal', function(sortingModal) { +.controller('SortingModalController', ['sortingModal', + '$scope', + 'QueryService', + function(sortingModal, $scope, QueryService) { this.name = 'Sorting'; this.closeMe = sortingModal.deactivate; + + $scope.sortByOptions = {}; + + $scope.getAvailableColumnsData = function(term, result) { + result($scope.availableColumnsData); + } + + $scope.getDirectionsData = function(term, result) { + result([{ id: 'asc', label: 'Ascending'}, { id: 'desc', label: 'Descending'}]); + } + + $scope.updateSortation = function(){ + // TODO RS: Clean this up once we have a sortation directive + var sortation = [[ $scope.selectedColumn1.id, $scope.selectedDirection1.id ], + [ $scope.selectedColumn2.id, $scope.selectedDirection2.id ], + [ $scope.selectedColumn3.id, $scope.selectedDirection3.id ]]; + QueryService.setSortation(sortation); + } + + QueryService.getAvailableColumns() + .then(function(data){ + $scope.availableColumns = data.available_columns + $scope.availableColumnsData = data.available_columns.map(function(column){ + return { id: column.name, label: column.title, other: column.title }; + }); + }); }]); diff --git a/app/assets/javascripts/angular/services/query-service.js b/app/assets/javascripts/angular/services/query-service.js index 74644b994c..3ac01e47a7 100644 --- a/app/assets/javascripts/angular/services/query-service.js +++ b/app/assets/javascripts/angular/services/query-service.js @@ -148,6 +148,10 @@ angular.module('openproject.services') this.showColumns(selectedColumnNames); }, + setSortation: function(sortation) { + return query.setSortation(new Sortation(sortation)); + }, + getAvailableFilters: function(projectIdentifier){ // TODO once this is becoming more single-page-app-like keep the available filters of the query model in sync when the project identifier is changed on the scope but the page isn't reloaded var identifier = 'global'; diff --git a/public/templates/work_packages/modals/sorting.html b/public/templates/work_packages/modals/sorting.html index 5dbf9c5cea..458f16fa90 100644 --- a/public/templates/work_packages/modals/sorting.html +++ b/public/templates/work_packages/modals/sorting.html @@ -4,5 +4,49 @@

    Sorting

    +
    + + +
    + +
    + + +
    + +
    + + +
    + +
    + + +
    + From 504237f08dfe7673879e9536ead6c4516c406f6f Mon Sep 17 00:00:00 2001 From: Richard Date: Wed, 14 May 2014 17:37:26 +0200 Subject: [PATCH 14/43] WIP wiring up initial filter values. --- Gemfile.lock | 7 +++++++ .../javascripts/angular/controllers/dialogs/sorting.js | 10 ++++++++++ app/assets/javascripts/angular/models/query.js | 4 ++++ .../javascripts/angular/services/query-service.js | 4 ++++ 4 files changed, 25 insertions(+) diff --git a/Gemfile.lock b/Gemfile.lock index 4b59111e3e..d8665ccaa9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -81,6 +81,9 @@ GEM arel (3.0.3) awesome_nested_set (2.1.6) activerecord (>= 3.0.0) + better_errors (1.1.0) + coderay (>= 1.0.0) + erubis (>= 2.6.6) binding_of_caller (0.7.2) debug_inspector (>= 0.0.1) bourbon (4.0.0) @@ -324,6 +327,8 @@ GEM multi_json (~> 1.0) rubyzip websocket (~> 1.0.4) + sextant (0.2.4) + rails (>= 3.2) shoulda (3.5.0) shoulda-context (~> 1.0, >= 1.0.1) shoulda-matchers (>= 1.4.1, < 3.0) @@ -387,6 +392,7 @@ DEPENDENCIES activerecord-tableless (~> 1.0) acts_as_list (~> 0.2.0) awesome_nested_set + better_errors bourbon (~> 4.0) capybara capybara-screenshot @@ -450,6 +456,7 @@ DEPENDENCIES sass (~> 3.3.6) sass-rails! selenium-webdriver + sextant shoulda shoulda-matchers simplecov (= 0.8.0.pre) diff --git a/app/assets/javascripts/angular/controllers/dialogs/sorting.js b/app/assets/javascripts/angular/controllers/dialogs/sorting.js index 331830a205..3c348fe539 100644 --- a/app/assets/javascripts/angular/controllers/dialogs/sorting.js +++ b/app/assets/javascripts/angular/controllers/dialogs/sorting.js @@ -45,6 +45,15 @@ angular.module('openproject.workPackages.controllers') $scope.sortByOptions = {}; + $scope.initSortation = function(){ + var currentSortation = QueryService.getSortation(); + + var element = currentSortation.sortElements[0]; + $scope.selectedColumn1 = $scope.availableColumnsData.filter(function(column) { + return column.id == element.field; + })[0]; + } + $scope.getAvailableColumnsData = function(term, result) { result($scope.availableColumnsData); } @@ -67,5 +76,6 @@ angular.module('openproject.workPackages.controllers') $scope.availableColumnsData = data.available_columns.map(function(column){ return { id: column.name, label: column.title, other: column.title }; }); + $scope.initSortation(); }); }]); diff --git a/app/assets/javascripts/angular/models/query.js b/app/assets/javascripts/angular/models/query.js index 7fe3be3d7d..36575c8eac 100644 --- a/app/assets/javascripts/angular/models/query.js +++ b/app/assets/javascripts/angular/models/query.js @@ -90,6 +90,10 @@ angular.module('openproject.models') return UrlParamsHelper.buildQueryString(this.toParams()); }, + getSortation: function(){ + return this.sortation; + }, + setSortation: function(sortation){ this.sortation = sortation; }, diff --git a/app/assets/javascripts/angular/services/query-service.js b/app/assets/javascripts/angular/services/query-service.js index 3ac01e47a7..5b7254c7e2 100644 --- a/app/assets/javascripts/angular/services/query-service.js +++ b/app/assets/javascripts/angular/services/query-service.js @@ -152,6 +152,10 @@ angular.module('openproject.services') return query.setSortation(new Sortation(sortation)); }, + getSortation: function() { + return query.getSortation(); + }, + getAvailableFilters: function(projectIdentifier){ // TODO once this is becoming more single-page-app-like keep the available filters of the query model in sync when the project identifier is changed on the scope but the page isn't reloaded var identifier = 'global'; From 1351608befc204fa85fbef1ee002bcb85082f069 Mon Sep 17 00:00:00 2001 From: Richard Date: Thu, 15 May 2014 15:27:04 +0200 Subject: [PATCH 15/43] Wired up sorting modal to current query sortation. Not yet updating table when sortation is changed. --- .../angular/controllers/dialogs/sorting.js | 21 +++++----- .../controllers/work-packages-controller.js | 34 ++++++++++++++++- .../options-dropdown-directive.js | 32 +--------------- .../javascripts/angular/models/query.js | 8 ++++ .../angular/services/query-service.js | 4 +- .../work_packages/modals/sorting.html | 38 +++---------------- 6 files changed, 61 insertions(+), 76 deletions(-) diff --git a/app/assets/javascripts/angular/controllers/dialogs/sorting.js b/app/assets/javascripts/angular/controllers/dialogs/sorting.js index 3c348fe539..58933e23b5 100644 --- a/app/assets/javascripts/angular/controllers/dialogs/sorting.js +++ b/app/assets/javascripts/angular/controllers/dialogs/sorting.js @@ -48,10 +48,10 @@ angular.module('openproject.workPackages.controllers') $scope.initSortation = function(){ var currentSortation = QueryService.getSortation(); - var element = currentSortation.sortElements[0]; - $scope.selectedColumn1 = $scope.availableColumnsData.filter(function(column) { - return column.id == element.field; - })[0]; + $scope.sortElements = currentSortation.sortElements.map(function(element){ + return [$scope.availableColumnsData.filter(function(column) { return column.id == element.field; })[0], + $scope.availableDirectionsData.filter(function(direction) { return direction.id == element.direction; })[0]] + }); } $scope.getAvailableColumnsData = function(term, result) { @@ -63,11 +63,12 @@ angular.module('openproject.workPackages.controllers') } $scope.updateSortation = function(){ - // TODO RS: Clean this up once we have a sortation directive - var sortation = [[ $scope.selectedColumn1.id, $scope.selectedDirection1.id ], - [ $scope.selectedColumn2.id, $scope.selectedDirection2.id ], - [ $scope.selectedColumn3.id, $scope.selectedDirection3.id ]]; - QueryService.setSortation(sortation); + var sortElements = $scope.sortElements.map(function(element){ + return { field: element[0].id, direction: element[1].id } + }) + QueryService.updateSortElements(sortElements); + + sortingModal.deactivate(); } QueryService.getAvailableColumns() @@ -78,4 +79,6 @@ angular.module('openproject.workPackages.controllers') }); $scope.initSortation(); }); + + $scope.availableDirectionsData = [{ id: 'desc', label: 'Descending'}, { id: 'asc', label: 'Ascending'}]; }]); diff --git a/app/assets/javascripts/angular/controllers/work-packages-controller.js b/app/assets/javascripts/angular/controllers/work-packages-controller.js index 8d47fde316..554c97af8d 100644 --- a/app/assets/javascripts/angular/controllers/work-packages-controller.js +++ b/app/assets/javascripts/angular/controllers/work-packages-controller.js @@ -41,11 +41,19 @@ angular.module('openproject.workPackages.controllers') 'WorkPackageLoadingHelper', 'INITIALLY_SELECTED_COLUMNS', 'OPERATORS_AND_LABELS_BY_FILTER_TYPE', + 'columnsModal', + 'exportModal', + 'saveModal', + 'settingsModal', + 'shareModal', + 'sortingModal', function($scope, $q, $window, $location, WorkPackagesTableHelper, WorkPackagesTableService, WorkPackageService, QueryService, PaginationService, WorkPackageLoadingHelper, INITIALLY_SELECTED_COLUMNS, - OPERATORS_AND_LABELS_BY_FILTER_TYPE) { + OPERATORS_AND_LABELS_BY_FILTER_TYPE, columnsModal, + exportModal, saveModal, settingsModal, shareModal, + sortingModal) { $scope.projectTypes = $window.gon.project_types; $scope.showFiltersOptions = false; @@ -202,6 +210,30 @@ angular.module('openproject.workPackages.controllers') return false; }; + // Modals + + $scope.showColumnsModal = columnsModal.activate; + $scope.showExportModal = exportModal.activate; + $scope.showSettingsModal = settingsModal.activate; + $scope.showShareModal = shareModal.activate; + + $scope.showSortingModal = function(){ + $scope.$emit('hideAllDropdowns'); + sortingModal.activate(); + }; + + $scope.showSaveModal = function(saveAs){ + $scope.$emit('hideAllDropdowns'); + if( saveAs || $scope.query.isNew() ){ + saveModal.activate(); + } else { + QueryService.saveQuery() + .then(function(data){ + $scope.$emit('flashMessage', data.status); + }); + } + }; + // Go initialSetup(); diff --git a/app/assets/javascripts/angular/directives/work_packages/options-dropdown-directive.js b/app/assets/javascripts/angular/directives/work_packages/options-dropdown-directive.js index a1692506d8..b7cb0557c8 100644 --- a/app/assets/javascripts/angular/directives/work_packages/options-dropdown-directive.js +++ b/app/assets/javascripts/angular/directives/work_packages/options-dropdown-directive.js @@ -29,43 +29,13 @@ angular.module('openproject.workPackages.directives') .directive('optionsDropdown', ['I18n', - 'columnsModal', - 'exportModal', - 'saveModal', - 'settingsModal', - 'shareModal', - 'sortingModal', - function(I18n, columnsModal, exportModal, saveModal, settingsModal, shareModal, sortingModal){ + function(I18n){ return { restrict: 'AE', scope: true, link: function(scope, element, attributes) { - // Modals - scope.showColumnsModal = columnsModal.activate; - scope.showExportModal = exportModal.activate; - scope.showSettingsModal = settingsModal.activate; - scope.showShareModal = shareModal.activate; - scope.showSortingModal = sortingModal.activate; - - scope.showSaveModal = function(saveAs){ - scope.$emit('hideAllDropdowns'); - if( saveAs || scope.query.isNew() ){ - saveModal.activate(); - } else { - QueryService.saveQuery() - .then(function(data){ - scope.$emit('flashMessage', data.status); - }); - } - }; - - scope.showColumnsModal = function(){ - scope.$emit('hideAllDropdowns'); - columnsModal.activate(); - }; - scope.toggleDisplaySums = function(){ scope.query.displaySums = !scope.query.displaySums; }; diff --git a/app/assets/javascripts/angular/models/query.js b/app/assets/javascripts/angular/models/query.js index 36575c8eac..19a0f0b360 100644 --- a/app/assets/javascripts/angular/models/query.js +++ b/app/assets/javascripts/angular/models/query.js @@ -98,6 +98,14 @@ angular.module('openproject.models') this.sortation = sortation; }, + updateSortElements: function(sortElements){ + this.sortation.sortElements.length = 0; + var self = this; + angular.forEach(sortElements, function(sortElement){ + self.sortation.addSortElement(sortElement); + }) + }, + setName: function(name) { this.name = name; }, diff --git a/app/assets/javascripts/angular/services/query-service.js b/app/assets/javascripts/angular/services/query-service.js index 5b7254c7e2..88a365e91b 100644 --- a/app/assets/javascripts/angular/services/query-service.js +++ b/app/assets/javascripts/angular/services/query-service.js @@ -148,8 +148,8 @@ angular.module('openproject.services') this.showColumns(selectedColumnNames); }, - setSortation: function(sortation) { - return query.setSortation(new Sortation(sortation)); + updateSortElements: function(sortation) { + return query.updateSortElements(sortation); }, getSortation: function() { diff --git a/public/templates/work_packages/modals/sorting.html b/public/templates/work_packages/modals/sorting.html index 458f16fa90..8147c299cd 100644 --- a/public/templates/work_packages/modals/sorting.html +++ b/public/templates/work_packages/modals/sorting.html @@ -4,43 +4,15 @@

    Sorting

    -
    - - -
    - -
    - - -
    - -
    - + - + + ng-model="element[1]">
    From dac8a1ca44e3eca1b9b3766cbd7a562b05220d33 Mon Sep 17 00:00:00 2001 From: Richard Date: Thu, 15 May 2014 16:13:09 +0200 Subject: [PATCH 16/43] Temp solution - moved sortation watcher to wp controller. Also copied over available columns caching from columns branch. --- .../javascripts/angular/controllers/dialogs/sorting.js | 6 +++--- .../angular/controllers/work-packages-controller.js | 9 +++++++++ app/assets/javascripts/angular/services/query-service.js | 4 ++++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/angular/controllers/dialogs/sorting.js b/app/assets/javascripts/angular/controllers/dialogs/sorting.js index 58933e23b5..276b08006a 100644 --- a/app/assets/javascripts/angular/controllers/dialogs/sorting.js +++ b/app/assets/javascripts/angular/controllers/dialogs/sorting.js @@ -72,9 +72,9 @@ angular.module('openproject.workPackages.controllers') } QueryService.getAvailableColumns() - .then(function(data){ - $scope.availableColumns = data.available_columns - $scope.availableColumnsData = data.available_columns.map(function(column){ + .then(function(available_columns){ + $scope.availableColumns = available_columns + $scope.availableColumnsData = available_columns.map(function(column){ return { id: column.name, label: column.title, other: column.title }; }); $scope.initSortation(); diff --git a/app/assets/javascripts/angular/controllers/work-packages-controller.js b/app/assets/javascripts/angular/controllers/work-packages-controller.js index 554c97af8d..053e3b14ac 100644 --- a/app/assets/javascripts/angular/controllers/work-packages-controller.js +++ b/app/assets/javascripts/angular/controllers/work-packages-controller.js @@ -245,4 +245,13 @@ angular.module('openproject.workPackages.controllers') } }); + // Note: Again, this was in the work packages table directive but in an isolated scope so it wasn't picking up the changes to sortation. + // Think it would probably be a good idea to have the table directive just share the scope but that requires a refactor. + $scope.$watch('query.sortation.sortElements', function(oldValue, newValue) { + if (JSON.stringify(newValue) != JSON.stringify(oldValue)) { + $scope.updateResults(); + $scope.updateBackUrl(); + } + }, true); + }]); diff --git a/app/assets/javascripts/angular/services/query-service.js b/app/assets/javascripts/angular/services/query-service.js index 88a365e91b..20e8deaa61 100644 --- a/app/assets/javascripts/angular/services/query-service.js +++ b/app/assets/javascripts/angular/services/query-service.js @@ -134,6 +134,7 @@ angular.module('openproject.services') return QueryService.doGet(url, function(response){ availableColumns = response.data.available_columns; return availableColumns; +<<<<<<< HEAD }); }, @@ -146,6 +147,9 @@ angular.module('openproject.services') this.hideColumns(currentColumns.map(function(column) { return column.name; })); this.showColumns(selectedColumnNames); +======= + }) +>>>>>>> Temp solution - moved sortation watcher to wp controller. }, updateSortElements: function(sortation) { From 932d7fe0da4d2d66e81d6b3cf9cd4490c64af4e7 Mon Sep 17 00:00:00 2001 From: Richard Date: Wed, 21 May 2014 14:15:31 +0200 Subject: [PATCH 17/43] Always have 3 sort elements in sort selection modal. --- .../angular/controllers/dialogs/sorting.js | 14 +++++++++++--- .../javascripts/angular/services/query-service.js | 4 ---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/angular/controllers/dialogs/sorting.js b/app/assets/javascripts/angular/controllers/dialogs/sorting.js index 276b08006a..fb07efd8be 100644 --- a/app/assets/javascripts/angular/controllers/dialogs/sorting.js +++ b/app/assets/javascripts/angular/controllers/dialogs/sorting.js @@ -52,6 +52,10 @@ angular.module('openproject.workPackages.controllers') return [$scope.availableColumnsData.filter(function(column) { return column.id == element.field; })[0], $scope.availableDirectionsData.filter(function(direction) { return direction.id == element.direction; })[0]] }); + + while($scope.sortElements.length < 3) { + $scope.sortElements.push([]); + } } $scope.getAvailableColumnsData = function(term, result) { @@ -63,9 +67,13 @@ angular.module('openproject.workPackages.controllers') } $scope.updateSortation = function(){ - var sortElements = $scope.sortElements.map(function(element){ - return { field: element[0].id, direction: element[1].id } - }) + var sortElements = $scope.sortElements + .filter(function(element){ + return element.length == 2; + }) + .map(function(element){ + return { field: element[0].id, direction: element[1].id } + }) QueryService.updateSortElements(sortElements); sortingModal.deactivate(); diff --git a/app/assets/javascripts/angular/services/query-service.js b/app/assets/javascripts/angular/services/query-service.js index 20e8deaa61..88a365e91b 100644 --- a/app/assets/javascripts/angular/services/query-service.js +++ b/app/assets/javascripts/angular/services/query-service.js @@ -134,7 +134,6 @@ angular.module('openproject.services') return QueryService.doGet(url, function(response){ availableColumns = response.data.available_columns; return availableColumns; -<<<<<<< HEAD }); }, @@ -147,9 +146,6 @@ angular.module('openproject.services') this.hideColumns(currentColumns.map(function(column) { return column.name; })); this.showColumns(selectedColumnNames); -======= - }) ->>>>>>> Temp solution - moved sortation watcher to wp controller. }, updateSortElements: function(sortation) { From 9deaf2f55c900c8d5ca18b01acb4a49b1f809a9f Mon Sep 17 00:00:00 2001 From: Richard Date: Wed, 21 May 2014 14:37:46 +0200 Subject: [PATCH 18/43] Moved modals back into dropdown directive...:> --- .../controllers/work-packages-controller.js | 34 +------------------ .../options-dropdown-directive.js | 32 ++++++++++++++++- 2 files changed, 32 insertions(+), 34 deletions(-) diff --git a/app/assets/javascripts/angular/controllers/work-packages-controller.js b/app/assets/javascripts/angular/controllers/work-packages-controller.js index 053e3b14ac..f085c9a2b2 100644 --- a/app/assets/javascripts/angular/controllers/work-packages-controller.js +++ b/app/assets/javascripts/angular/controllers/work-packages-controller.js @@ -41,19 +41,11 @@ angular.module('openproject.workPackages.controllers') 'WorkPackageLoadingHelper', 'INITIALLY_SELECTED_COLUMNS', 'OPERATORS_AND_LABELS_BY_FILTER_TYPE', - 'columnsModal', - 'exportModal', - 'saveModal', - 'settingsModal', - 'shareModal', - 'sortingModal', function($scope, $q, $window, $location, WorkPackagesTableHelper, WorkPackagesTableService, WorkPackageService, QueryService, PaginationService, WorkPackageLoadingHelper, INITIALLY_SELECTED_COLUMNS, - OPERATORS_AND_LABELS_BY_FILTER_TYPE, columnsModal, - exportModal, saveModal, settingsModal, shareModal, - sortingModal) { + OPERATORS_AND_LABELS_BY_FILTER_TYPE) { $scope.projectTypes = $window.gon.project_types; $scope.showFiltersOptions = false; @@ -210,30 +202,6 @@ angular.module('openproject.workPackages.controllers') return false; }; - // Modals - - $scope.showColumnsModal = columnsModal.activate; - $scope.showExportModal = exportModal.activate; - $scope.showSettingsModal = settingsModal.activate; - $scope.showShareModal = shareModal.activate; - - $scope.showSortingModal = function(){ - $scope.$emit('hideAllDropdowns'); - sortingModal.activate(); - }; - - $scope.showSaveModal = function(saveAs){ - $scope.$emit('hideAllDropdowns'); - if( saveAs || $scope.query.isNew() ){ - saveModal.activate(); - } else { - QueryService.saveQuery() - .then(function(data){ - $scope.$emit('flashMessage', data.status); - }); - } - }; - // Go initialSetup(); diff --git a/app/assets/javascripts/angular/directives/work_packages/options-dropdown-directive.js b/app/assets/javascripts/angular/directives/work_packages/options-dropdown-directive.js index b7cb0557c8..a1692506d8 100644 --- a/app/assets/javascripts/angular/directives/work_packages/options-dropdown-directive.js +++ b/app/assets/javascripts/angular/directives/work_packages/options-dropdown-directive.js @@ -29,13 +29,43 @@ angular.module('openproject.workPackages.directives') .directive('optionsDropdown', ['I18n', - function(I18n){ + 'columnsModal', + 'exportModal', + 'saveModal', + 'settingsModal', + 'shareModal', + 'sortingModal', + function(I18n, columnsModal, exportModal, saveModal, settingsModal, shareModal, sortingModal){ return { restrict: 'AE', scope: true, link: function(scope, element, attributes) { + // Modals + scope.showColumnsModal = columnsModal.activate; + scope.showExportModal = exportModal.activate; + scope.showSettingsModal = settingsModal.activate; + scope.showShareModal = shareModal.activate; + scope.showSortingModal = sortingModal.activate; + + scope.showSaveModal = function(saveAs){ + scope.$emit('hideAllDropdowns'); + if( saveAs || scope.query.isNew() ){ + saveModal.activate(); + } else { + QueryService.saveQuery() + .then(function(data){ + scope.$emit('flashMessage', data.status); + }); + } + }; + + scope.showColumnsModal = function(){ + scope.$emit('hideAllDropdowns'); + columnsModal.activate(); + }; + scope.toggleDisplaySums = function(){ scope.query.displaySums = !scope.query.displaySums; }; From 67f581db1b3072bf008b7d5f441d4f5125c19659 Mon Sep 17 00:00:00 2001 From: Alex Coles Date: Tue, 20 May 2014 22:46:03 +0200 Subject: [PATCH 19/43] Make work-packages router state abstract Signed-off-by: Alex Coles --- app/assets/javascripts/angular/routing.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/angular/routing.js b/app/assets/javascripts/angular/routing.js index 24ec42628c..6bc5ca30f9 100644 --- a/app/assets/javascripts/angular/routing.js +++ b/app/assets/javascripts/angular/routing.js @@ -34,10 +34,11 @@ openprojectApp.config(['$stateProvider', '$urlRouterProvider', $stateProvider .state('work-packages', { url: "/wp", + abstract: true, templateUrl: "/templates/work_packages.html" }) .state('work-packages.list', { - url: "/list", + url: "", templateUrl: "/templates/work_packages.list.html", controller: function($scope) { // From d348f226488cfde2ec7ef7fefe64843884194008 Mon Sep 17 00:00:00 2001 From: Alex Coles Date: Tue, 20 May 2014 22:53:56 +0200 Subject: [PATCH 20/43] Attach WorkPackagesController in router Signed-off-by: Alex Coles --- app/assets/javascripts/angular/routing.js | 3 ++- public/templates/work_packages.html | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/assets/javascripts/angular/routing.js b/app/assets/javascripts/angular/routing.js index 6bc5ca30f9..e8d210c99e 100644 --- a/app/assets/javascripts/angular/routing.js +++ b/app/assets/javascripts/angular/routing.js @@ -35,7 +35,8 @@ openprojectApp.config(['$stateProvider', '$urlRouterProvider', .state('work-packages', { url: "/wp", abstract: true, - templateUrl: "/templates/work_packages.html" + templateUrl: "/templates/work_packages.html", + controller: 'WorkPackagesController' }) .state('work-packages.list', { url: "", diff --git a/public/templates/work_packages.html b/public/templates/work_packages.html index 7a8aa75182..e13ae44b65 100644 --- a/public/templates/work_packages.html +++ b/public/templates/work_packages.html @@ -1,4 +1,4 @@ -
    +
    From 6e90cdab25fa5df7c430bb018e5e49e92b622341 Mon Sep 17 00:00:00 2001 From: Alex Coles Date: Wed, 21 May 2014 17:11:32 +0200 Subject: [PATCH 21/43] Allow v3 ProjectsController to find by identifier Not tested as this controller will go away soon. Signed-off-by: Alex Coles --- app/controllers/api/v3/projects_controller.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/controllers/api/v3/projects_controller.rb b/app/controllers/api/v3/projects_controller.rb index 6f19caf2a6..3bb958701f 100644 --- a/app/controllers/api/v3/projects_controller.rb +++ b/app/controllers/api/v3/projects_controller.rb @@ -64,7 +64,8 @@ module Api private def find_project - @project = Project.find(params[:project_id]) + @project = Project.where(identifier: params[:project_id]).first || + Project.find(params[:id]) end end From 5062f61d08063d63d585b66fe98eca3902aa7717 Mon Sep 17 00:00:00 2001 From: Alex Coles Date: Wed, 21 May 2014 17:50:43 +0200 Subject: [PATCH 22/43] Fix ProjectService.getProject() response handling * Add Karma test. Signed-off-by: Alex Coles --- .../angular/services/project-service.js | 4 +- karma/tests/services/project-service-test.js | 83 +++++++++++++++++++ 2 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 karma/tests/services/project-service-test.js diff --git a/app/assets/javascripts/angular/services/project-service.js b/app/assets/javascripts/angular/services/project-service.js index c3b6a637db..888436c4a1 100644 --- a/app/assets/javascripts/angular/services/project-service.js +++ b/app/assets/javascripts/angular/services/project-service.js @@ -6,7 +6,9 @@ angular.module('openproject.services') getProject: function(projectIdentifier) { var url = PathHelper.apiV3ProjectPath(projectIdentifier); - return ProjectService.doQuery(url); + return $http.get(url).then(function(response) { + return response.data.project; + }); }, getProjects: function() { diff --git a/karma/tests/services/project-service-test.js b/karma/tests/services/project-service-test.js new file mode 100644 index 0000000000..dbd384ac36 --- /dev/null +++ b/karma/tests/services/project-service-test.js @@ -0,0 +1,83 @@ +//-- copyright +// OpenProject is a project management system. +// Copyright (C) 2012-2014 the OpenProject Foundation (OPF) +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License version 3. +// +// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +// Copyright (C) 2006-2013 Jean-Philippe Lang +// Copyright (C) 2010-2013 the ChiliProject Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// See doc/COPYRIGHT.rdoc for more details. +//++ + +/*jshint expr: true*/ + +describe('ProjectService', function() { + + var $httpBackend, ProjectService; + beforeEach(module('openproject.services', 'openproject.models')); + + beforeEach(inject(function(_$httpBackend_, _ProjectService_) { + $httpBackend = _$httpBackend_; + ProjectService = _ProjectService_; + })); + + afterEach(function() { + $httpBackend.verifyNoOutstandingExpectation(); + $httpBackend.verifyNoOutstandingRequest(); + }); + + describe('getProject', function() { + beforeEach(function() { + $httpBackend.when('GET', '/api/v3/projects/superProject') + .respond({ + "project": { + "id": 99, + "name": "Super-Duper Project", + "parent_id": null, + "leaf?": true + } + }); + }) + + it('sends a successful get request', function() { + $httpBackend.expectGET('/api/v3/projects/superProject'); + + var callback = sinon.spy(), + project = ProjectService.getProject('superProject').then(callback); + + $httpBackend.flush(); + expect(callback).to.have.been.calledWith(sinon.match({ + name: "Super-Duper Project" + })); + }); + + it('sends a unsuccessful get request', function() { + $httpBackend.expectGET('/api/v3/projects/superProject').respond(401); + + var success = sinon.spy(), + error = sinon.spy(), + project = ProjectService.getProject('superProject').then(success, error); + + $httpBackend.flush(); + expect(success).not.to.have.been.called; + expect(error).to.have.been.called; + }); + }); +}); From f97f57e2175330e629dee5899e183eae3554c4dd Mon Sep 17 00:00:00 2001 From: Richard Date: Thu, 22 May 2014 09:53:23 +0200 Subject: [PATCH 23/43] Reverted Gemfile.lock to that from dev-angular. Must have accidentally committed it. --- Gemfile.lock | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index d8665ccaa9..d92961ab97 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -81,9 +81,6 @@ GEM arel (3.0.3) awesome_nested_set (2.1.6) activerecord (>= 3.0.0) - better_errors (1.1.0) - coderay (>= 1.0.0) - erubis (>= 2.6.6) binding_of_caller (0.7.2) debug_inspector (>= 0.0.1) bourbon (4.0.0) @@ -113,13 +110,6 @@ GEM codeclimate-test-reporter (0.1.1) simplecov (>= 0.7.1, < 1.0.0) coderay (1.0.9) - coffee-rails (3.2.2) - coffee-script (>= 2.2.0) - railties (~> 3.2.0) - coffee-script (2.2.0) - coffee-script-source - execjs - coffee-script-source (1.6.2) color-tools (1.3.0) columnize (0.8.9) compass (1.0.0.alpha.19) @@ -327,8 +317,6 @@ GEM multi_json (~> 1.0) rubyzip websocket (~> 1.0.4) - sextant (0.2.4) - rails (>= 3.2) shoulda (3.5.0) shoulda-context (~> 1.0, >= 1.0.1) shoulda-matchers (>= 1.4.1, < 3.0) @@ -392,14 +380,12 @@ DEPENDENCIES activerecord-tableless (~> 1.0) acts_as_list (~> 0.2.0) awesome_nested_set - better_errors bourbon (~> 4.0) capybara capybara-screenshot cocaine codeclimate-test-reporter coderay (~> 1.0.5) - coffee-rails (~> 3.2.1) color-tools (~> 1.3.0) compass (= 1.0.0.alpha.19) compass-rails! @@ -456,7 +442,6 @@ DEPENDENCIES sass (~> 3.3.6) sass-rails! selenium-webdriver - sextant shoulda shoulda-matchers simplecov (= 0.8.0.pre) From 6c3772066cc2135b8f082992dd1d636d931699f7 Mon Sep 17 00:00:00 2001 From: Alex Coles Date: Wed, 21 May 2014 18:43:48 +0200 Subject: [PATCH 24/43] [wip] Make WorkPackagesController load Project(s) Extract available work package Types from Project data. Remove gon (and global). Signed-off-by: Alex Coles --- .../controllers/work-packages-controller.js | 29 +++++++++++++++++-- .../work-packages-controller-test.js | 22 ++++++++++++-- public/templates/work_packages.html | 2 +- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/angular/controllers/work-packages-controller.js b/app/assets/javascripts/angular/controllers/work-packages-controller.js index 8d47fde316..93af5e6f94 100644 --- a/app/assets/javascripts/angular/controllers/work-packages-controller.js +++ b/app/assets/javascripts/angular/controllers/work-packages-controller.js @@ -33,6 +33,7 @@ angular.module('openproject.workPackages.controllers') '$q', '$window', '$location', + 'ProjectService', 'WorkPackagesTableHelper', 'WorkPackagesTableService', 'WorkPackageService', @@ -41,13 +42,12 @@ angular.module('openproject.workPackages.controllers') 'WorkPackageLoadingHelper', 'INITIALLY_SELECTED_COLUMNS', 'OPERATORS_AND_LABELS_BY_FILTER_TYPE', - function($scope, $q, $window, $location, + function($scope, $q, $window, $location, ProjectService, WorkPackagesTableHelper, WorkPackagesTableService, WorkPackageService, QueryService, PaginationService, WorkPackageLoadingHelper, INITIALLY_SELECTED_COLUMNS, OPERATORS_AND_LABELS_BY_FILTER_TYPE) { - $scope.projectTypes = $window.gon.project_types; $scope.showFiltersOptions = false; @@ -55,6 +55,7 @@ angular.module('openproject.workPackages.controllers') function initialSetup() { setUrlParams($window.location); + initProject(); $scope.selectedTitle = "Work Packages"; $scope.operatorsAndLabelsByFilterType = OPERATORS_AND_LABELS_BY_FILTER_TYPE; @@ -83,6 +84,30 @@ angular.module('openproject.workPackages.controllers') if(match) $scope.query_id = match[1]; } + + function initProject() { + if ($scope.projectIdentifier) { + ProjectService.getProject($scope.projectIdentifier).then(function(project) { + $scope.project = project; + $scope.projects = [ $scope.project ]; + $scope.availableTypes = $scope.project.embedded.types; + }); + } else { + ProjectService.getProjects().then(function(projects) { + var allTypes, availableTypes; + + $scope.projects = projects; + allTypes = projects.map(function(project) { + return project.embedded.types; + }).reduce(function(a, b) { + return a.concat(b); + }, []); + + $scope.availableTypes = allTypes; // TODO remove duplicates + }); + } + } + function setupPage(json) { initQuery(json.meta); setupWorkPackagesTable(json); diff --git a/karma/tests/controllers/work-packages-controller-test.js b/karma/tests/controllers/work-packages-controller-test.js index e2e956ce2a..fd340e3a18 100644 --- a/karma/tests/controllers/work-packages-controller-test.js +++ b/karma/tests/controllers/work-packages-controller-test.js @@ -29,15 +29,14 @@ /*jshint expr: true*/ describe('WorkPackagesController', function() { - var scope, ctrl, win, testWorkPackageService, testQueryService, testPaginationService; + var scope, ctrl, win, testProjectService, testWorkPackageService, testQueryService, testPaginationService; var buildController; beforeEach(module('openproject.workPackages.controllers', 'openproject.workPackages.services', 'ng-context-menu', 'btford.modal')); beforeEach(inject(function($rootScope, $controller, $timeout) { scope = $rootScope.$new(); win = { - location: { pathname: "" }, - gon: { project_types: [] } + location: { pathname: "" } }; var workPackageData = { @@ -49,6 +48,22 @@ describe('WorkPackagesController', function() { var availableQueryiesData = { }; + var projectData = { embedded: { types: [] } }; + var projectsData = [ projectData ]; + + testProjectService = { + getProject: function(identifier) { + return $timeout(function() { + return projectData; + }, 10); + }, + getProjects: function(identifier) { + return $timeout(function() { + return projectsData; + }, 10); + } + } + testWorkPackageService = { getWorkPackages: function () { }, @@ -115,6 +130,7 @@ describe('WorkPackagesController', function() { settingsModal: {}, shareModal: {}, sortingModal: {}, + ProjectService: testProjectService, QueryService: testQueryService, PaginationService: testPaginationService, WorkPackageService: testWorkPackageService diff --git a/public/templates/work_packages.html b/public/templates/work_packages.html index e13ae44b65..124dff96fc 100644 --- a/public/templates/work_packages.html +++ b/public/templates/work_packages.html @@ -28,7 +28,7 @@ From b9777f0d4fbf5a979bb8961f2b107b1983b20398 Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Thu, 22 May 2014 11:22:33 +0200 Subject: [PATCH 25/43] Merge branch 'dev-angular' into feature/ng-toolbar-sort-by --- Gemfile | 3 +- .../angular/controllers/dialogs/columns.js | 2 +- .../angular/controllers/dialogs/share.js | 11 +- .../angular/controllers/dialogs/sorting.js | 2 +- .../controllers/work-packages-controller.js | 8 +- .../components/selectable-title-directive.js | 5 + .../options-dropdown-directive.js | 8 +- .../helpers/work-packages-table-helper.js | 2 +- .../javascripts/angular/models/query.js | 6 +- .../javascripts/angular/openproject-app.js | 2 +- .../angular/services/query-service.js | 17 ++- .../services/work-packages-table-service.js | 7 +- app/assets/javascripts/application.js.erb | 2 +- .../stylesheets/content/_context_menu.sass | 101 +----------------- app/assets/stylesheets/context_menu_rtl.css | 2 + .../fonts/_openproject_icon_font.sass | 20 ++-- app/controllers/api/v3/queries_controller.rb | 1 + app/views/work_packages/index.html.erb | 2 +- .../moves/work_package_moves_new_copy.feature | 2 +- .../work-packages-controller-test.js | 4 +- .../templates/work_packages/modals/share.html | 9 ++ 21 files changed, 82 insertions(+), 134 deletions(-) diff --git a/Gemfile b/Gemfile index 98ae905d4e..faf1e37d4a 100644 --- a/Gemfile +++ b/Gemfile @@ -110,8 +110,7 @@ gem 'sprockets-rails', '2.0.0.backport1' gem 'sass-rails', git: 'https://github.com/guilleiguaran/sass-rails.git', branch: 'backport' gem 'sass', '~> 3.3.6' gem 'bourbon', '~> 4.0' -gem 'coffee-rails', '~> 3.2.1' -gem 'uglifier', '>= 1.0.3' +gem 'uglifier', '>= 1.0.3', require: false gem 'compass', '1.0.0.alpha.19' gem 'compass-rails', git: 'https://github.com/Compass/compass-rails' gem 'livingstyleguide' diff --git a/app/assets/javascripts/angular/controllers/dialogs/columns.js b/app/assets/javascripts/angular/controllers/dialogs/columns.js index ed35566a8a..b99a7effa7 100644 --- a/app/assets/javascripts/angular/controllers/dialogs/columns.js +++ b/app/assets/javascripts/angular/controllers/dialogs/columns.js @@ -77,7 +77,7 @@ angular.module('openproject.workPackages.controllers') $scope.selectedColumnsData = convertColumnsForSelect2(selectedColumns); // Available selectable Columns - QueryService.getAvailableUnusedColumns() + QueryService.loadAvailableUnusedColumns() .then(function(availableUnusedColumns){ $scope.availableUnusedColumns = availableUnusedColumns; $scope.availableColumnsData = convertColumnsForSelect2(availableUnusedColumns); diff --git a/app/assets/javascripts/angular/controllers/dialogs/share.js b/app/assets/javascripts/angular/controllers/dialogs/share.js index 39ec1eb4c5..d13780d9f4 100644 --- a/app/assets/javascripts/angular/controllers/dialogs/share.js +++ b/app/assets/javascripts/angular/controllers/dialogs/share.js @@ -36,7 +36,16 @@ angular.module('openproject.workPackages.controllers') }); }]) -.controller('ShareModalController', ['shareModal', function(shareModal) { +.controller('ShareModalController', ['$scope', 'shareModal', 'QueryService', function($scope, shareModal, QueryService) { this.name = 'Share'; this.closeMe = shareModal.deactivate; + $scope.query = QueryService.getQuery(); + + $scope.saveQuery = function() { + QueryService.saveQuery() + .then(function(data){ + shareModal.deactivate(); + $scope.$emit('flashMessage', data.status); + }); + } }]); diff --git a/app/assets/javascripts/angular/controllers/dialogs/sorting.js b/app/assets/javascripts/angular/controllers/dialogs/sorting.js index fb07efd8be..4f6a805235 100644 --- a/app/assets/javascripts/angular/controllers/dialogs/sorting.js +++ b/app/assets/javascripts/angular/controllers/dialogs/sorting.js @@ -79,7 +79,7 @@ angular.module('openproject.workPackages.controllers') sortingModal.deactivate(); } - QueryService.getAvailableColumns() + QueryService.loadAvailableColumns() .then(function(available_columns){ $scope.availableColumns = available_columns $scope.availableColumnsData = available_columns.map(function(column){ diff --git a/app/assets/javascripts/angular/controllers/work-packages-controller.js b/app/assets/javascripts/angular/controllers/work-packages-controller.js index f085c9a2b2..2df6434a0d 100644 --- a/app/assets/javascripts/angular/controllers/work-packages-controller.js +++ b/app/assets/javascripts/angular/controllers/work-packages-controller.js @@ -33,7 +33,6 @@ angular.module('openproject.workPackages.controllers') '$q', '$window', '$location', - 'WorkPackagesTableHelper', 'WorkPackagesTableService', 'WorkPackageService', 'QueryService', @@ -41,8 +40,7 @@ angular.module('openproject.workPackages.controllers') 'WorkPackageLoadingHelper', 'INITIALLY_SELECTED_COLUMNS', 'OPERATORS_AND_LABELS_BY_FILTER_TYPE', - function($scope, $q, $window, $location, - WorkPackagesTableHelper, WorkPackagesTableService, + function($scope, $q, $window, $location, WorkPackagesTableService, WorkPackageService, QueryService, PaginationService, WorkPackageLoadingHelper, INITIALLY_SELECTED_COLUMNS, OPERATORS_AND_LABELS_BY_FILTER_TYPE) { @@ -115,8 +113,8 @@ angular.module('openproject.workPackages.controllers') // table data WorkPackagesTableService.setColumns($scope.query.columns); WorkPackagesTableService.addColumnMetaData(meta); - WorkPackagesTableService.setRows(WorkPackagesTableHelper.getRows(workPackages, $scope.query.groupBy)); WorkPackagesTableService.setGroupBy($scope.query.groupBy); + WorkPackagesTableService.buildRows(workPackages, $scope.query.groupBy); WorkPackagesTableService.setBulkLinks(bulkLinks); // query data @@ -140,7 +138,7 @@ angular.module('openproject.workPackages.controllers') } function initAvailableColumns() { - return QueryService.getAvailableUnusedColumns($scope.projectIdentifier) + return QueryService.loadAvailableUnusedColumns($scope.projectIdentifier) .then(function(data){ $scope.availableUnusedColumns = data; }); diff --git a/app/assets/javascripts/angular/directives/components/selectable-title-directive.js b/app/assets/javascripts/angular/directives/components/selectable-title-directive.js index d485242346..91842ed04a 100644 --- a/app/assets/javascripts/angular/directives/components/selectable-title-directive.js +++ b/app/assets/javascripts/angular/directives/components/selectable-title-directive.js @@ -44,6 +44,11 @@ angular.module('openproject.uiComponents') scope.filteredGroups = angular.copy(scope.groups); }); + angular.element('#title-filter').bind('click', function(event) { + event.preventDefault(); + event.stopPropagation(); + }); + scope.reload = function(modelId, newTitle) { scope.selectedTitle = newTitle; scope.reloadMethod(modelId); diff --git a/app/assets/javascripts/angular/directives/work_packages/options-dropdown-directive.js b/app/assets/javascripts/angular/directives/work_packages/options-dropdown-directive.js index a1692506d8..cca8dad4b7 100644 --- a/app/assets/javascripts/angular/directives/work_packages/options-dropdown-directive.js +++ b/app/assets/javascripts/angular/directives/work_packages/options-dropdown-directive.js @@ -35,12 +35,17 @@ angular.module('openproject.workPackages.directives') 'settingsModal', 'shareModal', 'sortingModal', - function(I18n, columnsModal, exportModal, saveModal, settingsModal, shareModal, sortingModal){ + 'QueryService', + '$window', + function(I18n, columnsModal, exportModal, saveModal, settingsModal, shareModal, sortingModal, QueryService, $window){ return { restrict: 'AE', scope: true, link: function(scope, element, attributes) { + angular.element($window).bind('click', function() { + scope.$emit('hideAllDropdowns'); + }); // Modals scope.showColumnsModal = columnsModal.activate; @@ -67,6 +72,7 @@ angular.module('openproject.workPackages.directives') }; scope.toggleDisplaySums = function(){ + scope.$emit('hideAllDropdowns'); scope.query.displaySums = !scope.query.displaySums; }; } diff --git a/app/assets/javascripts/angular/helpers/work-packages-table-helper.js b/app/assets/javascripts/angular/helpers/work-packages-table-helper.js index 9892c1509a..0f4180f3ed 100644 --- a/app/assets/javascripts/angular/helpers/work-packages-table-helper.js +++ b/app/assets/javascripts/angular/helpers/work-packages-table-helper.js @@ -31,7 +31,7 @@ angular.module('openproject.workPackages.helpers') .factory('WorkPackagesTableHelper', ['WorkPackagesHelper', function(WorkPackagesHelper) { var WorkPackagesTableHelper = { /* builds rows from work packages, see IssuesHelper */ - getRows: function(workPackages, groupBy) { + buildRows: function(workPackages, groupBy) { var rows = [], ancestors = []; var currentGroup, allGroups = [], groupIndex = -1; diff --git a/app/assets/javascripts/angular/models/query.js b/app/assets/javascripts/angular/models/query.js index 19a0f0b360..71e9c44388 100644 --- a/app/assets/javascripts/angular/models/query.js +++ b/app/assets/javascripts/angular/models/query.js @@ -58,7 +58,8 @@ angular.module('openproject.models') 'group_by': this.groupBy, 'sort': this.sortation.encode(), 'display_sums': this.displaySums, - 'name': this.name + 'name': this.name, + 'is_public': this.isPublic }].concat(this.getActiveConfiguredFilters().map(function(filter) { return filter.toParams(); })) @@ -73,7 +74,8 @@ angular.module('openproject.models') 'c[]': this.getParamColumns(), 'group_by': this.groupBy, 'sort': this.sortation.encode(), - 'display_sums': this.displaySums + 'display_sums': this.displaySums, + 'is_public': this.isPublic }].concat(this.getActiveConfiguredFilters().map(function(filter) { return filter.toParams(); })) diff --git a/app/assets/javascripts/angular/openproject-app.js b/app/assets/javascripts/angular/openproject-app.js index bcd4952217..73a06c6a76 100644 --- a/app/assets/javascripts/angular/openproject-app.js +++ b/app/assets/javascripts/angular/openproject-app.js @@ -73,7 +73,7 @@ openprojectApp config.url = window.appBasePath + config.url; return config || $q.when(config); } - } + }; }); }]) .run(['$http', function($http){ diff --git a/app/assets/javascripts/angular/services/query-service.js b/app/assets/javascripts/angular/services/query-service.js index 88a365e91b..f0d53422fe 100644 --- a/app/assets/javascripts/angular/services/query-service.js +++ b/app/assets/javascripts/angular/services/query-service.js @@ -67,7 +67,8 @@ angular.module('openproject.services') groupSums: queryData.group_sums, sums: queryData.sums, columns: selectedColumns, - groupBy: queryData.group_by + groupBy: queryData.group_by, + isPublic: queryData.is_public }); query.setSortation(new Sortation(queryData.sort_criteria)); @@ -99,6 +100,10 @@ angular.module('openproject.services') return totalEntries; }, + getAvailableUnusedColumns: function() { + return availableUnusedColumns; + }, + hideColumns: function(columnNames) { WorkPackagesTableHelper.moveColumns(columnNames, this.getSelectedColumns(), availableColumns); }, @@ -115,15 +120,19 @@ angular.module('openproject.services') return QueryService.doQuery(url); }, - getAvailableUnusedColumns: function(projectIdentifier) { - return QueryService.getAvailableColumns(projectIdentifier) + loadAvailableUnusedColumns: function(projectIdentifier) { + if(availableUnusedColumns.length) { + return $q.when(availableUnusedColumns); + } + + return QueryService.loadAvailableColumns(projectIdentifier) .then(function(available_columns) { availableUnusedColumns = WorkPackagesTableHelper.getColumnDifference(available_columns, QueryService.getSelectedColumns()); return availableUnusedColumns; }); }, - getAvailableColumns: function(projectIdentifier) { + loadAvailableColumns: function(projectIdentifier) { // TODO: Once we have a single page app we need to differentiate between different project columns if(availableColumns.length) { return $q.when(availableColumns); diff --git a/app/assets/javascripts/angular/services/work-packages-table-service.js b/app/assets/javascripts/angular/services/work-packages-table-service.js index 74380ae51e..dfb538ef12 100644 --- a/app/assets/javascripts/angular/services/work-packages-table-service.js +++ b/app/assets/javascripts/angular/services/work-packages-table-service.js @@ -31,7 +31,8 @@ angular.module('openproject.workPackages.services') .service('WorkPackagesTableService', [ '$filter', 'QueryService', - function($filter, QueryService) { + 'WorkPackagesTableHelper', + function($filter, QueryService, WorkPackagesTableHelper) { var workPackagesTableData = { allRowsChecked: false }; @@ -77,6 +78,10 @@ angular.module('openproject.workPackages.services') return workPackagesTableData.groupableColumns; }, + buildRows: function(workPackages, groupBy) { + this.setRows(WorkPackagesTableHelper.buildRows(workPackages, groupBy)); + }, + setRows: function(rows) { workPackagesTableData.rows = rows; }, diff --git a/app/assets/javascripts/application.js.erb b/app/assets/javascripts/application.js.erb index ce99000b25..01b09d0453 100644 --- a/app/assets/javascripts/application.js.erb +++ b/app/assets/javascripts/application.js.erb @@ -20,7 +20,7 @@ //= require momentjs/lang/de.js //= require jquery.atwho/dist/js/jquery.atwho.js -//= require Caret.js/src/jquery.caret +//= require Caret.js/src/jquery.caret.js //= require jquery_noconflict //= require prototype //= require effects diff --git a/app/assets/stylesheets/content/_context_menu.sass b/app/assets/stylesheets/content/_context_menu.sass index 12e44f3af2..dd4aabf581 100644 --- a/app/assets/stylesheets/content/_context_menu.sass +++ b/app/assets/stylesheets/content/_context_menu.sass @@ -34,106 +34,9 @@ padding: 0 border: 0 -.context-menu - position: absolute - font-size: 0.9em - left: -7px - top: -7px - padding: 6px - z-index: 21 - ul - @include context_menu_defaults - width: 140px - list-style: none +#work-package-context-menu, #column-context-menu + &.action-menu position: absolute - left: -7px - z-index: 20 - background: #f4f4f4 - border: 1px solid #afafaf - li - @include context_menu_defaults - position: relative - padding: 1px - padding: 6px - z-index: 39 - border: 1px solid white - background-position: 6px center - background-repeat: no-repeat - cursor: pointer - border-top: 1px solid #fff - border-bottom: 1px solid #ddd - > a - width:auto - &:hover - border: 1px solid gray - background-color: #eee - - &.folder - &:hover - z-index: 40 - div.submenu - background: url(image-path('arrow-right.png')) no-repeat right - position: absolute - height: 9px - width: 7px - top: 11px - right: 6px - ul - display: none - position: absolute - max-height: 400px - overflow-x: hidden - overflow-y: auto - left: 140px - top: -1px - width: auto - z-index: 19 - - a - @include context_menu_defaults - border: none - background-repeat: no-repeat - background-position: 1px 50% - padding: 1px 10px 1px 15px - width: 100% - - &.icon, &.icon-context - color: $content_icon_link_hover_color - font-weight: bold - padding-left: 0 - - &.disabled, &.disabled:hover - color: #ccc - - &:hover - color: #2A5685 - border: none - text-decoration: none - - &.reverse-y li.folder>ul - top: auto - bottom: 0 - &.reverse-x li.folder - ul - left: auto - right: 168px - >ul - right: 148px - -#context-menu ul ul, #context-menu li:hover ul ul - display: none - -#context-menu li:hover ul, #context-menu li:hover li:hover ul - display: block - -#context-menu li li - padding: 6px 12px - width: auto - display: block - white-space: nowrap - -#context-menu li:hover ul - display: block .hascontextmenu cursor: context-menu diff --git a/app/assets/stylesheets/context_menu_rtl.css b/app/assets/stylesheets/context_menu_rtl.css index 66c7b5888f..5258418270 100644 --- a/app/assets/stylesheets/context_menu_rtl.css +++ b/app/assets/stylesheets/context_menu_rtl.css @@ -27,6 +27,8 @@ See doc/COPYRIGHT.rdoc for more details. ++*/ +/* FIXME adapt modifications to the new action-menu component */ + #context-menu li.folder ul { left:auto; right:168px; } #context-menu li.folder>ul { left:auto; right:148px; } #context-menu li a.submenu { background:url("../images/bullet_arrow_left.png") left no-repeat; } diff --git a/app/assets/stylesheets/fonts/_openproject_icon_font.sass b/app/assets/stylesheets/fonts/_openproject_icon_font.sass index 1ed09ae63b..d5d500a0ea 100644 --- a/app/assets/stylesheets/fonts/_openproject_icon_font.sass +++ b/app/assets/stylesheets/fonts/_openproject_icon_font.sass @@ -65,11 +65,11 @@ @mixin icon6-rules padding: 0 7px 0 9px font-size: 12px - + @mixin icon-dropdown-rules padding: 0 0px 0 3px font-size: 13px - + @mixin icon-button-rules padding: 0 5px 0 0px font-size: 13px @@ -77,7 +77,7 @@ @mixin icon-context-rules padding: 0 4px 0 0 color: $content_icon_color - + @mixin icon-table-rules padding: 0 0 0 0 @@ -105,17 +105,17 @@ @include icon-common content: attr(data-icon5) @include icon5-rules - + [data-icon-dropwdown]:before @include icon-common content: attr(data-icon-dropdown) @include icon-dropdown-rules - + [data-icon-button]:before @include icon-common content: attr(data-icon-button) @include icon-button-rules - + [data-icon-table]:before @include icon-common content: attr(data-icon-table) @@ -147,15 +147,15 @@ // used for toggler icons in the project menu .icon6:before @include icon6-rules - + // used for arrow icons in buttons with dropdown .icon-dropdown:before @include icon-dropdown-rules - + // used for icons in buttons .icon-buttons:before @include icon-button-rules - + // used for icons in workpackage table .icon-table:before @include icon-table-rules @@ -166,7 +166,7 @@ float: left // used for icons in the content area, which appear in context (menus) -#context-menu .icon:before, +.action-menu .icon:before, .icon-context:before @include icon-context-rules diff --git a/app/controllers/api/v3/queries_controller.rb b/app/controllers/api/v3/queries_controller.rb index 1a34b76edd..ea3475bd73 100644 --- a/app/controllers/api/v3/queries_controller.rb +++ b/app/controllers/api/v3/queries_controller.rb @@ -122,6 +122,7 @@ module Api::V3 @query.column_names = params[:c] if params[:c] @query.column_names = nil if params[:default_columns] @query.name = params[:name] if params[:name] + @query.is_public = params[:is_public] if params[:is_public] end def visible_queries diff --git a/app/views/work_packages/index.html.erb b/app/views/work_packages/index.html.erb index cdf3a16e04..52c40b0300 100644 --- a/app/views/work_packages/index.html.erb +++ b/app/views/work_packages/index.html.erb @@ -86,7 +86,7 @@ end
  • Save
  • Save as
  • Export
  • -
  • Share
  • +
  • Share
  • Page settings
  • diff --git a/features/work_packages/moves/work_package_moves_new_copy.feature b/features/work_packages/moves/work_package_moves_new_copy.feature index cf92c9b23a..e04056f86e 100644 --- a/features/work_packages/moves/work_package_moves_new_copy.feature +++ b/features/work_packages/moves/work_package_moves_new_copy.feature @@ -128,7 +128,7 @@ Feature: Copying a work package And I open the context menu on the work packages: | issue1 | | issue2 | - And I follow "Copy" within "#work-pacakge-context-menu" + And I follow "Copy" within "#work-package-context-menu" Then I should see "Copy" within "#content" And I should not see "Move" within "#content" diff --git a/karma/tests/controllers/work-packages-controller-test.js b/karma/tests/controllers/work-packages-controller-test.js index e2e956ce2a..2d8df67e2f 100644 --- a/karma/tests/controllers/work-packages-controller-test.js +++ b/karma/tests/controllers/work-packages-controller-test.js @@ -72,7 +72,7 @@ describe('WorkPackagesController', function() { }, initQuery: function () { }, - getAvailableColumns: function () { + loadAvailableColumns: function () { return $timeout(function () { return columnData; }, 10); @@ -83,7 +83,7 @@ describe('WorkPackagesController', function() { }, 10); }, - getAvailableUnusedColumns: function() { + loadAvailableUnusedColumns: function() { return $timeout(function () { return columnData; }, 10); diff --git a/public/templates/work_packages/modals/share.html b/public/templates/work_packages/modals/share.html index dcfb9d18ee..ee3b919c71 100644 --- a/public/templates/work_packages/modals/share.html +++ b/public/templates/work_packages/modals/share.html @@ -4,5 +4,14 @@

    Share

    +
    + + +
    +
    + + +
    +
    From c961c82a33487f97447f141ad389f11bc133a0bb Mon Sep 17 00:00:00 2001 From: Richard Date: Thu, 22 May 2014 11:31:45 +0200 Subject: [PATCH 26/43] New task dropdown links now point to new work package view. Signed-off-by: Alex Coles --- public/templates/work_packages.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/public/templates/work_packages.html b/public/templates/work_packages.html index 124dff96fc..f79b57d769 100644 --- a/public/templates/work_packages.html +++ b/public/templates/work_packages.html @@ -28,7 +28,7 @@ From 2dd2982c97b7760d3aea59804a839c913ac8b419 Mon Sep 17 00:00:00 2001 From: Christoph Zierz - zzmedia Date: Thu, 22 May 2014 11:38:05 +0200 Subject: [PATCH 27/43] Fix menu-markup - cleaned up the action-menu markup - fixed some issues --- .../stylesheets/content/_action_menu_main.md | 80 +++++++++---------- .../content/_action_menu_main.sass | 45 +++++------ .../fonts/_openproject_icon_font.sass | 21 +++++ 3 files changed, 78 insertions(+), 68 deletions(-) diff --git a/app/assets/stylesheets/content/_action_menu_main.md b/app/assets/stylesheets/content/_action_menu_main.md index 6e7e392a0a..6742d6594e 100644 --- a/app/assets/stylesheets/content/_action_menu_main.md +++ b/app/assets/stylesheets/content/_action_menu_main.md @@ -2,50 +2,42 @@ ```
    - +
    - ``` diff --git a/app/assets/stylesheets/content/_action_menu_main.sass b/app/assets/stylesheets/content/_action_menu_main.sass index f51c50c5e2..098be13874 100644 --- a/app/assets/stylesheets/content/_action_menu_main.sass +++ b/app/assets/stylesheets/content/_action_menu_main.sass @@ -84,18 +84,18 @@ ul.action_menu_more @include contextual(-39px) .action-menu - float: left - width: 200px - border: 1px solid #dddddd - box-shadow: 1px 1px 4px #cccccc - -webkit-box-shadow: 1px 1px 4px #cccccc - padding: 3px 0 ul list-style-type: none - padding: 0 margin: 0 + + width: 200px + border: 1px solid #dddddd + box-shadow: 1px 1px 4px #cccccc + padding: 3px 0 + background: #ffffff + li - padding: 4px 10px + padding: 4px 13px 4px 10px &:hover background: #f0f0f0 &.hasnoicon @@ -105,25 +105,22 @@ ul.action_menu_more margin: 3px 0 padding: 0 font-size: 1px + &:hover ul + display: block + margin: -28px 0 0 190px + a color: $main_menu_font_color font-weight: normal - white-space: nowrap &:hover text-decoration: none + ul + display: none + position: absolute -i -.icon-actionmenu - padding: 0 10px 0 0 - font-size: 15px - line-height: 5px - vertical-align: -40% -.icon-submenu - padding: 0 0 0 0 - float: right - font-size: 15px - line-height: 5px - vertical-align: -40% - -#submenu - margin: 81px 0 0 0 \ No newline at end of file + +.icon-action-menu + @include icon-action-menu-rules +.icon-sub-menu + @include icon-sub-menu-rules + \ No newline at end of file diff --git a/app/assets/stylesheets/fonts/_openproject_icon_font.sass b/app/assets/stylesheets/fonts/_openproject_icon_font.sass index 1ed09ae63b..c45d9f2c3d 100644 --- a/app/assets/stylesheets/fonts/_openproject_icon_font.sass +++ b/app/assets/stylesheets/fonts/_openproject_icon_font.sass @@ -80,6 +80,19 @@ @mixin icon-table-rules padding: 0 0 0 0 + +@mixin icon-action-menu-rules + padding: 0 10px 0 0 + font-size: 15px + line-height: 5px + vertical-align: -40% + +@mixin icon-sub-menu-rules + padding: 0 0 0 0 + float: right + font-size: 15px + line-height: 5px + vertical-align: -40% [data-icon]:before @include icon-common @@ -120,6 +133,14 @@ @include icon-common content: attr(data-icon-table) @include icon-table-rules + +[data-icon-action-menu]:before + content: attr(data-icon-action-menu) + @include icon-action-menu-rules + +[data-icon-sub-menu]:before + content: attr(data-icon-sub-menu) + @include icon-sub-menu-rules [class^="icon-"]:before, [class*=" icon-"]:before From 5921fbd73a74a5599b58d9fb256393389fd130a1 Mon Sep 17 00:00:00 2001 From: Christoph Zierz - zzmedia Date: Thu, 22 May 2014 11:49:00 +0200 Subject: [PATCH 28/43] Remove former context menu-styles - removed former context menu-styles --- .../content/_action_menu_main.sass | 57 ------------------- 1 file changed, 57 deletions(-) diff --git a/app/assets/stylesheets/content/_action_menu_main.sass b/app/assets/stylesheets/content/_action_menu_main.sass index 098be13874..6a7ba19dfc 100644 --- a/app/assets/stylesheets/content/_action_menu_main.sass +++ b/app/assets/stylesheets/content/_action_menu_main.sass @@ -25,63 +25,6 @@ * * See doc/COPYRIGHT.rdoc for more details. ++ */ - -@mixin action_menu_defaults($margin-top: 7px) - float: right - margin-top: $margin-top - > li - float: left - position: relative - list-style: none - -@mixin contextual($margin-top: 8px) - float: right - white-space: nowrap - line-height: 1.4em - margin-top: $margin-top - padding-left: 10px - -ul.action_menu_main - @include action_menu_defaults - -ul.action_menu_specific, -.nosidebar ul.action_menu_specific - @include action_menu_defaults(-34px) - -p.subtitle + ul.action_menu_specific - @include action_menu_defaults(-57px) - -ul.action_menu_more - position: absolute - top: 23px - right: 0px - z-index: 100 - white-space: nowrap - padding: 10px - padding-top: 5px - - background: white - border: 1px solid #B7B7B7 - - box-shadow: 1px 1px 2px #aaa - > li - padding-top: 5px - - -#lower-title-bar ul.action_menu_specific - @include action_menu_defaults - padding-top: 10px - -#lower-title-bar ul.action_menu_more - bottom: 0 - right: 0 - margin-bottom: 25px - top: auto - > li.drop-down - position: relative - -.message-reply-menu - @include contextual(-39px) .action-menu ul From d8b5570db42d76ac6bf22701ee62d5b4d36b08be Mon Sep 17 00:00:00 2001 From: Alex Coles Date: Thu, 22 May 2014 11:54:35 +0200 Subject: [PATCH 29/43] Extract WorkPackageDetailsController (was inline) * Add skeleton Karma test. Signed-off-by: Alex Coles --- .../work-package-details-controller.js | 47 ++++++++++++++++ app/assets/javascripts/angular/routing.js | 15 +---- karma.conf.js | 1 + .../work-package-details-controller-test.js | 56 +++++++++++++++++++ 4 files changed, 105 insertions(+), 14 deletions(-) create mode 100644 app/assets/javascripts/angular/controllers/work-package-details-controller.js create mode 100644 karma/tests/controllers/work-package-details-controller-test.js diff --git a/app/assets/javascripts/angular/controllers/work-package-details-controller.js b/app/assets/javascripts/angular/controllers/work-package-details-controller.js new file mode 100644 index 0000000000..b4b86c0597 --- /dev/null +++ b/app/assets/javascripts/angular/controllers/work-package-details-controller.js @@ -0,0 +1,47 @@ +//-- copyright +// OpenProject is a project management system. +// Copyright (C) 2012-2014 the OpenProject Foundation (OPF) +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License version 3. +// +// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +// Copyright (C) 2006-2013 Jean-Philippe Lang +// Copyright (C) 2010-2013 the ChiliProject Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// See doc/COPYRIGHT.rdoc for more details. +//++ + +angular.module('openproject.workPackages.controllers') + +.controller('WorkPackageDetailsController', [ + '$scope', + '$stateParams', + function($scope, $stateParams) { + + $scope.workPackageId = $stateParams.workPackageId + + $scope.$watch('rows', function(rows) { + if (rows && rows.length > 0) { + var row = $scope.rows.find(function(row) { + return row.object.id == $scope.workPackageId; + }); + $scope.workPackage = row ? row.object : {}; + } + }); + } +]); diff --git a/app/assets/javascripts/angular/routing.js b/app/assets/javascripts/angular/routing.js index e8d210c99e..d9e7e88f08 100644 --- a/app/assets/javascripts/angular/routing.js +++ b/app/assets/javascripts/angular/routing.js @@ -48,19 +48,6 @@ openprojectApp.config(['$stateProvider', '$urlRouterProvider', .state('work-packages.list.details', { url: "/:workPackageId", templateUrl: "/templates/work_packages.list.details.html", - controller: ['$scope', '$stateParams', - function($scope, $stateParams) { - $scope.workPackageId = $stateParams.workPackageId - - $scope.$watch('rows', function(rows){ - if (rows && rows.length > 0) { - var row = $scope.rows.find(function(row) { - return row.object.id == $scope.workPackageId; - }); - $scope.workPackage = row ? row.object : {}; - } - }); - - }] + controller: 'WorkPackageDetailsController' }) }]); diff --git a/karma.conf.js b/karma.conf.js index b46315d193..1b95a8f2d6 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -90,6 +90,7 @@ module.exports = function(config) { "app/assets/javascripts/angular/controllers/timelines-controller.js", "app/assets/javascripts/angular/controllers/work-packages-controller.js", + "app/assets/javascripts/angular/controllers/work-package-details-controller.js", 'app/assets/javascripts/date-en-US.js', diff --git a/karma/tests/controllers/work-package-details-controller-test.js b/karma/tests/controllers/work-package-details-controller-test.js new file mode 100644 index 0000000000..c1f365802b --- /dev/null +++ b/karma/tests/controllers/work-package-details-controller-test.js @@ -0,0 +1,56 @@ +//-- copyright +// OpenProject is a project management system. +// Copyright (C) 2012-2014 the OpenProject Foundation (OPF) +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License version 3. +// +// OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +// Copyright (C) 2006-2013 Jean-Philippe Lang +// Copyright (C) 2010-2013 the ChiliProject Team +// +// This program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License +// as published by the Free Software Foundation; either version 2 +// of the License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +// +// See doc/COPYRIGHT.rdoc for more details. +//++ + +/*jshint expr: true*/ + +describe('WorkPackageDetailsController', function() { + var scope; + var buildController; + + beforeEach(module('openproject.workPackages.controllers')); + beforeEach(inject(function($rootScope, $controller, $timeout) { + scope = $rootScope.$new(); + + buildController = function() { + ctrl = $controller("WorkPackageDetailsController", { + $scope: scope, + $stateParams: { workPackageId: 99 } + }); + + // $timeout.flush(); + }; + + })); + + describe('initialisation', function() { + it('should initialise', function() { + buildController(); + }); + }); + +}); From fdae696804c18e8f27fe2c4bde62631e95a8d446 Mon Sep 17 00:00:00 2001 From: Alex Coles Date: Thu, 22 May 2014 11:56:06 +0200 Subject: [PATCH 30/43] Remove empty controller from router Signed-off-by: Alex Coles --- app/assets/javascripts/angular/routing.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/app/assets/javascripts/angular/routing.js b/app/assets/javascripts/angular/routing.js index d9e7e88f08..fec1ecab87 100644 --- a/app/assets/javascripts/angular/routing.js +++ b/app/assets/javascripts/angular/routing.js @@ -40,10 +40,7 @@ openprojectApp.config(['$stateProvider', '$urlRouterProvider', }) .state('work-packages.list', { url: "", - templateUrl: "/templates/work_packages.list.html", - controller: function($scope) { - // - } + templateUrl: "/templates/work_packages.list.html" }) .state('work-packages.list.details', { url: "/:workPackageId", From ee1849efe7cd5f8d78893d6673b0e946e0df47c1 Mon Sep 17 00:00:00 2001 From: Richard Date: Thu, 22 May 2014 13:00:14 +0200 Subject: [PATCH 31/43] Column headers now displaying first sort element up/down arrow. --- .../work_packages/options-dropdown-directive.js | 6 +++++- app/assets/javascripts/angular/models/query.js | 6 +----- app/assets/javascripts/angular/models/sortation.js | 8 ++++++++ 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/app/assets/javascripts/angular/directives/work_packages/options-dropdown-directive.js b/app/assets/javascripts/angular/directives/work_packages/options-dropdown-directive.js index a1692506d8..65fbf6f131 100644 --- a/app/assets/javascripts/angular/directives/work_packages/options-dropdown-directive.js +++ b/app/assets/javascripts/angular/directives/work_packages/options-dropdown-directive.js @@ -47,7 +47,6 @@ angular.module('openproject.workPackages.directives') scope.showExportModal = exportModal.activate; scope.showSettingsModal = settingsModal.activate; scope.showShareModal = shareModal.activate; - scope.showSortingModal = sortingModal.activate; scope.showSaveModal = function(saveAs){ scope.$emit('hideAllDropdowns'); @@ -66,6 +65,11 @@ angular.module('openproject.workPackages.directives') columnsModal.activate(); }; + scope.showSortingModal = function(){ + scope.$emit('hideAllDropdowns'); + sortingModal.activate(); + }; + scope.toggleDisplaySums = function(){ scope.query.displaySums = !scope.query.displaySums; }; diff --git a/app/assets/javascripts/angular/models/query.js b/app/assets/javascripts/angular/models/query.js index 19a0f0b360..25b532afb6 100644 --- a/app/assets/javascripts/angular/models/query.js +++ b/app/assets/javascripts/angular/models/query.js @@ -99,11 +99,7 @@ angular.module('openproject.models') }, updateSortElements: function(sortElements){ - this.sortation.sortElements.length = 0; - var self = this; - angular.forEach(sortElements, function(sortElement){ - self.sortation.addSortElement(sortElement); - }) + this.sortation.setSortElements(sortElements); }, setName: function(name) { diff --git a/app/assets/javascripts/angular/models/sortation.js b/app/assets/javascripts/angular/models/sortation.js index 93f7172ce3..ebe67541d0 100644 --- a/app/assets/javascripts/angular/models/sortation.js +++ b/app/assets/javascripts/angular/models/sortation.js @@ -83,6 +83,14 @@ angular.module('openproject.models') this.sortElements.unshift(sortElement); }; + Sortation.prototype.setSortElements = function(sortElements) { + var elements = this.sortElements; + elements.length = 0; + angular.forEach(sortElements, function(element){ + elements.push(element); + }); + }; + Sortation.prototype.getTargetSortationOfHeader = function(headerName) { var targetSortation = angular.copy(this); var targetSortDirection = this.getCurrentSortDirectionOfHeader(headerName) === 'asc' ? 'desc' : 'asc'; From aaeedb37685da9d5c5a0599a3453b16b266d240d Mon Sep 17 00:00:00 2001 From: Christoph Zierz - zzmedia Date: Thu, 22 May 2014 13:32:39 +0200 Subject: [PATCH 32/43] Add styles for modal popups - added styles for modal popups / lightboxes --- app/assets/stylesheets/content/_modal.md | 13 ++++++++++ app/assets/stylesheets/content/_modal.sass | 29 ++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/app/assets/stylesheets/content/_modal.md b/app/assets/stylesheets/content/_modal.md index d8b4b4cdf7..e536cba332 100644 --- a/app/assets/stylesheets/content/_modal.md +++ b/app/assets/stylesheets/content/_modal.md @@ -1 +1,14 @@ # Modal + +``` +
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Crasdapibus. Vivamus elementum semper
    + + +``` diff --git a/app/assets/stylesheets/content/_modal.sass b/app/assets/stylesheets/content/_modal.sass index 18202fd25e..37166f6115 100644 --- a/app/assets/stylesheets/content/_modal.sass +++ b/app/assets/stylesheets/content/_modal.sass @@ -100,3 +100,32 @@ $ng-modal-image-width: $ng-modal-image-height margin-top: 1em &:last-child padding: 0 2em + +#sample-content-behind-modal + position: absolute + z-index: 1 + padding: 10px + +#modal-dark-overlay + position: absolute + z-index: 2 + background: #000000 + opacity: 0.3 + width: 97% + height: 94% + +.modal-container + position: relative + z-index: 3 + margin: 20px auto + width: 60% + background: #ffffff + padding: 0 + .modal-header + padding: 0 + i + float: right + padding: 10px + .modal-content + padding: 20px 20px 20px 20px + \ No newline at end of file From b4bc2951cd75ed4b9e0c95e7bf48b6122816526a Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Thu, 22 May 2014 14:02:26 +0200 Subject: [PATCH 33/43] Apply new action menu styles to wp context menu --- public/templates/work_packages/work_package_context_menu.html | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/public/templates/work_packages/work_package_context_menu.html b/public/templates/work_packages/work_package_context_menu.html index b8c9704003..173dc1271b 100644 --- a/public/templates/work_packages/work_package_context_menu.html +++ b/public/templates/work_packages/work_package_context_menu.html @@ -12,7 +12,8 @@
  • TODO Priority -
      + +
  • From afc167a50fae41b7020abae3ffd5a10ce3d37d3d Mon Sep 17 00:00:00 2001 From: Till Breuer Date: Thu, 22 May 2014 15:38:48 +0200 Subject: [PATCH 35/43] Update close icons in modal dialogs --- app/assets/stylesheets/content/_modal.md | 17 +++--- app/assets/stylesheets/content/_modal.sass | 54 +++---------------- .../work_packages/modals/columns.html | 2 +- .../work_packages/modals/export.html | 2 +- .../templates/work_packages/modals/save.html | 2 +- .../work_packages/modals/settings.html | 2 +- .../templates/work_packages/modals/share.html | 2 +- .../work_packages/modals/sorting.html | 4 +- 8 files changed, 24 insertions(+), 61 deletions(-) diff --git a/app/assets/stylesheets/content/_modal.md b/app/assets/stylesheets/content/_modal.md index e536cba332..a1f6d21402 100644 --- a/app/assets/stylesheets/content/_modal.md +++ b/app/assets/stylesheets/content/_modal.md @@ -1,14 +1,17 @@ # Modal ``` -
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras +
    Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Cras Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. Nulla consequat massa quis enim. Donec pede justo, fringilla vel, aliquet nec, vulputate eget, arcu. In enim justo, rhoncus ut, imperdiet a, venenatis vitae, justo. Nullam dictum felis eu pede mollis pretium. Integer tincidunt. Crasdapibus. Vivamus elementum semper
    - -