Merge branch 'dev-angular' into feature/work-packages-detail-pane

pull/1327/head
Alex Coles 11 years ago
commit 6d106df01e
  1. 52
      app/assets/javascripts/angular/controllers/dialogs/sorting.js
  2. 6
      app/assets/javascripts/angular/directives/work_packages/options-dropdown-directive.js
  3. 8
      app/assets/javascripts/angular/models/query.js
  4. 8
      app/assets/javascripts/angular/models/sortation.js
  5. 5
      app/assets/javascripts/angular/openproject-app.js
  6. 4
      app/assets/javascripts/angular/routing.js
  7. 8
      app/assets/javascripts/angular/services/query-service.js
  8. 80
      app/assets/stylesheets/content/_action_menu_main.md
  9. 103
      app/assets/stylesheets/content/_action_menu_main.sass
  10. 12
      app/assets/stylesheets/content/_headings.md
  11. 12
      app/assets/stylesheets/content/_headings.sass
  12. 16
      app/assets/stylesheets/content/_modal.md
  13. 74
      app/assets/stylesheets/content/_modal.sass
  14. 38
      app/assets/stylesheets/fonts/_openproject_icon_font.sass
  15. 34
      app/assets/stylesheets/global/_mixins.sass
  16. 9
      app/assets/stylesheets/global/_variables.sass
  17. 21
      app/assets/stylesheets/layout/_drop_down.sass
  18. 4
      bower.json
  19. 6
      features/issues/query.feature
  20. 1
      public/templates/work_packages.html
  21. 13
      public/templates/work_packages/column_context_menu.html
  22. 8
      public/templates/work_packages/modals/columns.html
  23. 4
      public/templates/work_packages/modals/export.html
  24. 10
      public/templates/work_packages/modals/save.html
  25. 4
      public/templates/work_packages/modals/settings.html
  26. 6
      public/templates/work_packages/modals/share.html
  27. 22
      public/templates/work_packages/modals/sorting.html
  28. 3
      public/templates/work_packages/work_package_context_menu.html
  29. 4
      spec/features/accessibility/custom_fields_spec.rb
  30. 14
      spec/features/accessibility/work_packages/work_package_query_spec.rb

@ -36,7 +36,57 @@ angular.module('openproject.workPackages.controllers')
}); });
}]) }])
.controller('SortingModalController', ['sortingModal', function(sortingModal) { .controller('SortingModalController', ['sortingModal',
'$scope',
'QueryService',
function(sortingModal, $scope, QueryService) {
this.name = 'Sorting'; this.name = 'Sorting';
this.closeMe = sortingModal.deactivate; this.closeMe = sortingModal.deactivate;
$scope.sortByOptions = {};
$scope.initSortation = function(){
var currentSortation = QueryService.getSortation();
$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]]
});
while($scope.sortElements.length < 3) {
$scope.sortElements.push([]);
}
}
$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(){
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();
}
QueryService.loadAvailableColumns()
.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();
});
$scope.availableDirectionsData = [{ id: 'desc', label: 'Descending'}, { id: 'asc', label: 'Ascending'}];
}]); }]);

@ -52,7 +52,6 @@ angular.module('openproject.workPackages.directives')
scope.showExportModal = exportModal.activate; scope.showExportModal = exportModal.activate;
scope.showSettingsModal = settingsModal.activate; scope.showSettingsModal = settingsModal.activate;
scope.showShareModal = shareModal.activate; scope.showShareModal = shareModal.activate;
scope.showSortingModal = sortingModal.activate;
scope.showSaveModal = function(saveAs){ scope.showSaveModal = function(saveAs){
scope.$emit('hideAllDropdowns'); scope.$emit('hideAllDropdowns');
@ -71,6 +70,11 @@ angular.module('openproject.workPackages.directives')
columnsModal.activate(); columnsModal.activate();
}; };
scope.showSortingModal = function(){
scope.$emit('hideAllDropdowns');
sortingModal.activate();
};
scope.toggleDisplaySums = function(){ scope.toggleDisplaySums = function(){
scope.$emit('hideAllDropdowns'); scope.$emit('hideAllDropdowns');
scope.query.displaySums = !scope.query.displaySums; scope.query.displaySums = !scope.query.displaySums;

@ -92,10 +92,18 @@ angular.module('openproject.models')
return UrlParamsHelper.buildQueryString(this.toParams()); return UrlParamsHelper.buildQueryString(this.toParams());
}, },
getSortation: function(){
return this.sortation;
},
setSortation: function(sortation){ setSortation: function(sortation){
this.sortation = sortation; this.sortation = sortation;
}, },
updateSortElements: function(sortElements){
this.sortation.setSortElements(sortElements);
},
setName: function(name) { setName: function(name) {
this.name = name; this.name = name;
}, },

@ -83,6 +83,14 @@ angular.module('openproject.models')
this.sortElements.unshift(sortElement); 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) { Sortation.prototype.getTargetSortationOfHeader = function(headerName) {
var targetSortation = angular.copy(this); var targetSortation = angular.copy(this);
var targetSortDirection = this.getCurrentSortDirectionOfHeader(headerName) === 'asc' ? 'desc' : 'asc'; var targetSortDirection = this.getCurrentSortDirectionOfHeader(headerName) === 'asc' ? 'desc' : 'asc';

@ -118,9 +118,6 @@ var openprojectApp = angular.module('openproject', [
window.appBasePath = jQuery('meta[name=app_base_path]').attr('content') || ''; window.appBasePath = jQuery('meta[name=app_base_path]').attr('content') || '';
// FIXME: replace with actual data
window.gon = { project_types: [] };
openprojectApp openprojectApp
.config(['$locationProvider', '$httpProvider', function($locationProvider, $httpProvider) { .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. // Note: Not using this because we want to use $location to get the url params and html5Mode prevents all the links from working normally.
@ -133,7 +130,7 @@ openprojectApp
config.url = window.appBasePath + config.url; config.url = window.appBasePath + config.url;
return config || $q.when(config); return config || $q.when(config);
} }
} };
}); });
}]) }])
.run(['$http', function($http){ .run(['$http', function($http){

@ -26,7 +26,9 @@
// See doc/COPYRIGHT.rdoc for more details. // See doc/COPYRIGHT.rdoc for more details.
//++ //++
openprojectApp.config(['$stateProvider', '$urlRouterProvider', openprojectApp.config([
'$stateProvider',
'$urlRouterProvider',
function($stateProvider, $urlRouterProvider) { function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/wp"); $urlRouterProvider.otherwise("/wp");

@ -157,6 +157,14 @@ angular.module('openproject.services')
this.showColumns(selectedColumnNames); this.showColumns(selectedColumnNames);
}, },
updateSortElements: function(sortation) {
return query.updateSortElements(sortation);
},
getSortation: function() {
return query.getSortation();
},
getAvailableFilters: function(projectIdentifier){ 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 // 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'; var identifier = 'global';

@ -2,50 +2,42 @@
``` ```
<div class="action-menu"> <div class="action-menu">
<ul class="menu"> <ul class="menu">
<li> <li>
<a href="#"><i class="icon-edit icon-actionmenu"></i>menu item for modal...</a> <a href="#"><i class="icon-edit icon-action-menu"></i>menu item for modal...</a>
</li> </li>
<li>
<li> <a href="#"><i class="icon-yes icon-action-menu"></i>menu item</a>
<a href="#"><i class="icon-yes icon-actionmenu"></i>menu item</a> </li>
</li> <li>
<a href="#"><i class="icon-copy icon-action-menu"></i>menu item</a>
<li> </li>
<a href="#"><i class="icon-copy icon-actionmenu"></i>menu item</a> <li>
</li> <a href="#"><i class="icon-priority icon-action-menu"></i>menu item with sub</a>
<i class="icon-pulldown-arrow4 icon-sub-menu"></i>
<li class="submenu-item"> <ul class="sub-menu">
<a href="#"><i class="icon-priority icon-actionmenu"></i>menu item with sub</a><i class="icon-pulldown-arrow4 icon-submenu"></i> <li>
</li> <a href="#"><i class="icon-edit icon-action-menu"></i>menu item</a>
<li> </li>
<a href="#"><i class="icon-delete icon-actionmenu"></i>menu item</a> <li>
</li> <a href="#"><i class="icon-yes icon-action-menu"></i>menu item</a>
</li>
<li class="hasnoicon"> <li>
<a href="#">menu item no icon</a> <a href="#"><i class="icon-copy icon-action-menu"></i>menu item</a>
</li> </li>
</ul>
<li class="dropdown-divider"></li> </li>
<li>
<li> <a href="#"><i class="icon-delete icon-action-menu"></i>menu item</a>
<a href="#"><i class="icon-time icon-actionmenu"></i>menu item</a> </li>
</li> <li class="has-no-icon">
<a href="#">menu item no icon</a>
</ul> </li>
<li class="dropdown-divider"></li>
<li>
<a href="#"><i class="icon-time icon-action-menu"></i>menu item</a>
</li>
</ul>
</div> </div>
<div id="submenu" class="action-menu">
<ul class="menu">
<li>
<a href="#"><i class="icon-edit icon-actionmenu"></i>menu item for modal...</a>
</li>
<li>
<a href="#"><i class="icon-yes icon-actionmenu"></i>menu item</a>
</li>
<li>
<a href="#"><i class="icon-copy icon-actionmenu"></i>menu item</a>
</li>
</ul>
</div>
``` ```

@ -26,105 +26,44 @@
* See doc/COPYRIGHT.rdoc for more details. ++ * 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 .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
background: $action_menu_bg_color
ul ul
list-style-type: none list-style-type: none
padding: 0
margin: 0 margin: 0
width: 200px
border: 1px solid #dddddd
box-shadow: 1px 1px 4px #cccccc
padding: 3px 0
background: #ffffff
li li
padding: 4px 10px padding: 4px 13px 4px 10px
&:hover &:hover
background: #f0f0f0 background: #f0f0f0
&.hasnoicon &.has-no-icon
padding: 4px 10px 4px 35px padding: 4px 10px 4px 35px
&.dropdown-divider &.dropdown-divider
border-top: 1px solid #eeeeee border-top: 1px solid #eeeeee
margin: 3px 0 margin: 3px 0
padding: 0 padding: 0
font-size: 1px font-size: 1px
&:hover ul
display: block
margin: -28px 0 0 190px
a a
color: $main_menu_font_color color: $main_menu_font_color
font-weight: normal font-weight: normal
white-space: nowrap
&:hover &:hover
text-decoration: none text-decoration: none
ul
display: none
position: absolute
i .icon-action-menu
.icon-actionmenu @include icon-action-menu-rules
padding: 0 10px 0 0 .icon-sub-menu
font-size: 15px @include icon-sub-menu-rules
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

@ -1 +1,13 @@
# Headings # Headings
```
<h1>Headline H1</h1>
<span class="sample-text">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.<br /><br /></span>
<h2>Headline H2</h2>
<span class="sample-text">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.<br /><br /></span>
<h3>Headline H3</h3>
<span class="sample-text">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.<br /><br /></span>
<h4>Headline H4</h4>
<span class="sample-text">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.<br /><br /></span>
```

@ -29,3 +29,15 @@
#content #content
h2 h2
padding-right: 340px padding-right: 340px
h1
@include default-headline-h1
h2
@include default-headline-h2
h3
@include default-headline-h3
h4
@include default-headline-h4

@ -1 +1,17 @@
# Modal # Modal
```
<div id="content-behind-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</div>
<div id="modal-dark-overlay">
</div>
<div class="modal-container">
<div class="modal-header"><i class="icon-close"></i></div>
<div class="modal-content">
<h3>Modal 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. 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 dapibus. Vivamus elementum semper
</div>
</div>
```

@ -12,7 +12,7 @@ $ng-modal-image-width: $ng-modal-image-height
.ng-modal-window .ng-modal-window
// overlay // overlay
+position(fixed, 0px 0px 0px 0px) +position(fixed, 0px 0px 0px 0px)
background: rgba(0, 0, 0, 0.2) background: rgba(0, 0, 0, 0.5)
text-align: left text-align: left
z-index: 10000 z-index: 10000
@ -32,30 +32,8 @@ $ng-modal-image-width: $ng-modal-image-height
.ng-modal-inner .ng-modal-inner
top: 0 top: 0
.ng-modal-close
+position(absolute, $ng-modal-padding / 2 $ng-modal-padding / 2 0 0)
+size(1.5em)
cursor: pointer
background: $ng-modal-background
&:after,
&:before
+position(absolute, 3px 3px 0 50%)
+transform(rotate(45deg))
+size(0.15em 1.5em)
background: $ng-modal-close-color
content: ''
display: block
margin: -3px 0 0 -1px
&:hover:after,
&:hover:before
background: darken($ng-modal-close-color, 10)
&:before
+transform(rotate(-45deg))
.ng-modal-inner .ng-modal-inner
+transition(opacity 0.25s ease) +transition(opacity 0.25s ease)
border-radius: $base-border-radius
box-shadow: 0 5px 10px rgba(0, 0, 0, .2)
background: $ng-modal-background background: $ng-modal-background
margin: auto margin: auto
max-height: 95% max-height: 95%
@ -66,37 +44,33 @@ $ng-modal-image-width: $ng-modal-image-height
margin-top: .6em margin-top: .6em
//+media($medium-screen) //+media($medium-screen)
//padding: $ng-modal-padding //padding: $ng-modal-padding
//width: 60% //width: 50%
//max-height: 60% //max-height: 50%
//margin-top: 10em //margin-top: 10em
//+media($large-screen) //+media($large-screen)
width: 50% width: 40%
margin-top: 10em margin-top: 10em
h1 .modal-header
color: $base-font-color
margin-bottom: .6em
text-align: left
text-transform: capitalize
p
font-size: $base-font-size
max-width: 100% !important
padding: 0 padding: 0
text-align: left i
&.intro float: right
color: $blue cursor: pointer
line-height: 1.6em
&.body
color: $base-font-color
line-height: 1.45em
//+media($medium-screen)
+columns(2 8em)
a.cta label
color: white padding: 0 50px 0 0
display: inline-block input
margin-right: .5em width: 230px
margin-top: 1em height: 30px
&:last-child line-height: 30px
padding: 0 2em padding: 0 5px
background: #ffffff
border: 1px solid #cacaca
font-size: 13px
color: #222222
border-radius: 2px
button
margin: 30px 7px 0 0
.select2-container
margin: 0 0 10px 0

@ -67,13 +67,17 @@
font-size: 12px font-size: 12px
@mixin icon-dropdown-rules @mixin icon-dropdown-rules
padding: 0 0px 0 3px padding: 0 0 0 3px
font-size: 13px font-size: 13px
@mixin icon-button-rules @mixin icon-button-rules
padding: 0 5px 0 0px padding: 0 5px 0 0
font-size: 13px font-size: 13px
@mixin icon-dropdown-menu-rules
padding: 0 8px 0 0
font-size: 14px
@mixin icon-context-rules @mixin icon-context-rules
padding: 0 4px 0 0 padding: 0 4px 0 0
color: $content_icon_color color: $content_icon_color
@ -81,6 +85,19 @@
@mixin icon-table-rules @mixin icon-table-rules
padding: 0 0 0 0 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 [data-icon]:before
@include icon-common @include icon-common
content: attr(data-icon) content: attr(data-icon)
@ -111,6 +128,11 @@
content: attr(data-icon-dropdown) content: attr(data-icon-dropdown)
@include icon-dropdown-rules @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 [data-icon-button]:before
@include icon-common @include icon-common
content: attr(data-icon-button) content: attr(data-icon-button)
@ -121,6 +143,14 @@
content: attr(data-icon-table) content: attr(data-icon-table)
@include icon-table-rules @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,
[class*=" icon-"]:before [class*=" icon-"]:before
@include icon-common @include icon-common
@ -152,6 +182,10 @@
.icon-dropdown:before .icon-dropdown:before
@include icon-dropdown-rules @include icon-dropdown-rules
// used for icons dropdown-menus
.icon-dropdown-menu:before
@include icon-dropdown-menu-rules
// used for icons in buttons // used for icons in buttons
.icon-buttons:before .icon-buttons:before
@include icon-button-rules @include icon-button-rules

@ -37,6 +37,40 @@ $button_gray_font_color: #222222
@each $vendor in $vendors @each $vendor in $vendors
#{$vendor}transition: all 200ms ease-in-out 0s #{$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) @mixin default-font-normal($color, $font-size: 13px)
color: $color color: $color
font-size: $font-size font-size: $font-size

@ -30,6 +30,15 @@ $global_font_color: #555555 !default
$global_font_size: 13px !default $global_font_size: 13px !default
$global_line_height: 1.5 !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_height: 55px !default
$header_bg_color: #3493B3 !default $header_bg_color: #3493B3 !default
$header_border_bottom_color: #3493B3 !default $header_border_bottom_color: #3493B3 !default

@ -32,6 +32,10 @@
// https://github.com/plapier/jquery-dropdown // https://github.com/plapier/jquery-dropdown
// (dual MIT/GPL-Licensed) // (dual MIT/GPL-Licensed)
#settingsDropdown
margin: 10px 0 0 0
.dropdown .dropdown
position: absolute position: absolute
z-index: 9999999 z-index: 9999999
@ -45,7 +49,7 @@
background: #FFF background: #FFF
border: solid 1px #DDD border: solid 1px #DDD
border: solid 1px rgba(0, 0, 0, .2) border: solid 1px rgba(0, 0, 0, .2)
border-radius: 6px border-radius: 0px
box-shadow: 0 5px 10px rgba(0, 0, 0, .2) box-shadow: 0 5px 10px rgba(0, 0, 0, .2)
overflow: visible overflow: visible
padding: 4px 0 padding: 4px 0
@ -103,21 +107,28 @@
color: #555 color: #555
text-decoration: none text-decoration: none
line-height: 18px line-height: 18px
padding: 3px 15px padding: 3px 32px
white-space: nowrap white-space: nowrap
.dropdown .dropdown-menu LI > A:hover, .dropdown .dropdown-menu LI > A:hover,
.dropdown .dropdown-menu LABEL:hover .dropdown .dropdown-menu LABEL:hover
background-color: #08C background-color: #F0F0F0
color: #FFF
cursor: pointer 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 .dropdown .dropdown-menu .dropdown-divider
font-size: 1px font-size: 1px
border-top: solid 1px #E5E5E5 border-top: solid 1px #E5E5E5
padding: 0 padding: 0
margin: 5px 0 margin: 4px 0
/* Icon Examples - icons courtesy of http://p.yusukekamiyamane.com/ */ /* Icon Examples - icons courtesy of http://p.yusukekamiyamane.com/ */
.dropdown.has-icons LI > A .dropdown.has-icons LI > A

@ -13,6 +13,7 @@
"angular-ui-select2": "latest", "angular-ui-select2": "latest",
"angular-ui-select2-sortable": "latest", "angular-ui-select2-sortable": "latest",
"angular-ui-date": "latest", "angular-ui-date": "latest",
"angular-ui-router": "~0.2.10",
"angular-i18n": "~1.3.0", "angular-i18n": "~1.3.0",
"angular-modal": "~0.3.0", "angular-modal": "~0.3.0",
"angular-sanitize": "~1.2.14", "angular-sanitize": "~1.2.14",
@ -24,8 +25,7 @@
"mocha": "~1.14.0", "mocha": "~1.14.0",
"angular-mocks": "~1.2.14", "angular-mocks": "~1.2.14",
"angular-scenario": "~1.2.14", "angular-scenario": "~1.2.14",
"chai": "~1.9.0", "chai": "~1.9.0"
"angular-ui-router": "~0.2.10"
}, },
"resolutions": { "resolutions": {
"select2": "3.3.2" "select2": "3.3.2"

@ -38,7 +38,7 @@ Feature: Work Package Query
| name | position | | name | position |
| Bug | 1 | | Bug | 1 |
@javascript @javascript @wip
Scenario: Create a query and give it a name Scenario: Create a query and give it a name
When I am already admin When I am already admin
And I go to the work packages index page for the project "project" And I go to the work packages index page for the project "project"
@ -49,7 +49,7 @@ Feature: Work Package Query
Then I should see "Query" within "#content" Then I should see "Query" within "#content"
And I should see "Successful creation." And I should see "Successful creation."
@javascript @javascript @wip
Scenario: Group on empty Value (Assignee) Scenario: Group on empty Value (Assignee)
Given the project "project" has 1 issue with the following: Given the project "project" has 1 issue with the following:
| subject | issue1 | | subject | issue1 |
@ -65,6 +65,7 @@ Feature: Work Package Query
And I should see "Successful creation." And I should see "Successful creation."
And I should see "None" within "#content" And I should see "None" within "#content"
@wip
Scenario: Save Button should be visible for users with the proper rights Scenario: Save Button should be visible for users with the proper rights
Given there is 1 user with the following: Given there is 1 user with the following:
| login | bob | | login | bob |
@ -79,6 +80,7 @@ Feature: Work Package Query
And I go to the work packages index page for the project "project" And I go to the work packages index page for the project "project"
Then I should see "Save" within "#query_form" Then I should see "Save" within "#query_form"
@wip
Scenario: Save Button should be invisible for users without the proper rights Scenario: Save Button should be invisible for users without the proper rights
Given there is 1 user with the following: Given there is 1 user with the following:
| login | alice | | login | alice |

@ -67,7 +67,6 @@
<li><a href ng-click="showSaveModal(true)">Save as</a></li> <li><a href ng-click="showSaveModal(true)">Save as</a></li>
<li><a href ng-click="showExportModal()">Export</a></li> <li><a href ng-click="showExportModal()">Export</a></li>
<li ng-show="!query.isNew()"><a href ng-click="showShareModal()">Share</a></li> <li ng-show="!query.isNew()"><a href ng-click="showShareModal()">Share</a></li>
<li><a href ng-click="showSettingsModal()">Page settings</a></li>
</ul> </ul>
</div> </div>

@ -1,26 +1,33 @@
<div id="column-context-menu" class="action-menu" ng-show="opened"> <div id="column-context-menu" class="action-menu" ng-show="opened">
<ul class="menu"> <ul class="menu">
<li ng-click="groupBy(column.name)"> <li ng-click="groupBy(column.name)" class="has-no-icon">
<a href="#"><span ng-bind="I18n.t('js.work_packages.query.group_by')"/> {{column.title}}</a> <a href="#"><span ng-bind="I18n.t('js.work_packages.query.group_by')"/> <span ng-bind="column.title"/></a>
</li> </li>
<li ng-click="sortAscending(column.name)"> <li ng-click="sortAscending(column.name)">
<a href="#"><span ng-bind="I18n.t('js.label_sort_by')"/> <span ng-bind="column.title"/> <span ng-bind="I18n.t('js.label_ascending')"/></a> <a href="#">
<i class="icon-action-menu icon-pulldown-arrow3"></i>
<span ng-bind="I18n.t('js.label_sort_by')"/> <span ng-bind="column.title"/> <span ng-bind="I18n.t('js.label_ascending')"/>
</a>
</li> </li>
<li ng-click="sortDescending(column.name)"> <li ng-click="sortDescending(column.name)">
<i class="icon-action-menu icon-pulldown-arrow1"></i>
<a href="#"><span ng-bind="I18n.t('js.label_sort_by')"/> <span ng-bind="column.title"/> <span ng-bind="I18n.t('js.label_descending')"/></a> <a href="#"><span ng-bind="I18n.t('js.label_sort_by')"/> <span ng-bind="column.title"/> <span ng-bind="I18n.t('js.label_descending')"/></a>
</li> </li>
<li ng-click="moveLeft(column.name)"> <li ng-click="moveLeft(column.name)">
<i class="icon-action-menu icon-paragraph-left"></i>
<a href="#"><span ng-bind="I18n.t('js.label_move_column_left')"/></a> <a href="#"><span ng-bind="I18n.t('js.label_move_column_left')"/></a>
</li> </li>
<li ng-click="moveRight(column.name)"> <li ng-click="moveRight(column.name)">
<i class="icon-action-menu icon-paragraph-right"></i>
<a href="#"><span ng-bind="I18n.t('js.label_move_column_right')"/></a> <a href="#"><span ng-bind="I18n.t('js.label_move_column_right')"/></a>
</li> </li>
<li ng-click="hideColumn(column.name)"> <li ng-click="hideColumn(column.name)">
<i class="icon-action-menu icon-delete2"></i>
<a href="#"><span ng-bind="I18n.t('js.label_hide_column')"/></a> <a href="#"><span ng-bind="I18n.t('js.label_hide_column')"/></a>
</li> </li>

@ -1,8 +1,8 @@
<div class="ng-modal-window"> <div class="ng-modal-window">
<div class="ng-modal-inner"> <div class="ng-modal-inner">
<a href class="ng-modal-close" ng-click="modal.closeMe()">&nbsp;</a> <div class="modal-header"><i class="icon-close" ng-click="modal.closeMe()"></i></div>
<h1>Columns</h1> <h3>Columns</h3>
<div> <div>
<label for="selected_columns">Selected Columns</label> <label for="selected_columns">Selected Columns</label>
@ -16,8 +16,8 @@
</div> </div>
<div> <div>
<button ng-click="updateSelectedColumns()">Apply</button> <button class="button_highlight" ng-click="updateSelectedColumns()">Apply</button>
<button ng-click="modal.closeMe()">Cancel</button> <button class="button" ng-click="modal.closeMe()">Cancel</button>
</div> </div>
</div> </div>

@ -1,8 +1,8 @@
<div class="ng-modal-window"> <div class="ng-modal-window">
<div class="ng-modal-inner"> <div class="ng-modal-inner">
<a href class="ng-modal-close" ng-click="modal.closeMe()">&nbsp;</a> <div class="modal-header"><i class="icon-close" ng-click="modal.closeMe()"></i></div>
<h1>{{modal.name}}</h1> <h3>{{modal.name}}</h3>
<div class="grid-items-lines"> <div class="grid-items-lines">
<a ng-repeat="(key, value) in modal.formats" ng-href="{{value}}" class="grid-item"> <a ng-repeat="(key, value) in modal.formats" ng-href="{{value}}" class="grid-item">
<img src="" alt=""> <img src="" alt="">

@ -1,16 +1,16 @@
<div class="ng-modal-window"> <div class="ng-modal-window">
<div class="ng-modal-inner"> <div class="ng-modal-inner">
<a href class="ng-modal-close" ng-click="modal.closeMe()">&nbsp;</a> <div class="modal-header"><i class="icon-close" ng-click="modal.closeMe()"></i></div>
<h1>Save</h1> <h3>Save</h3>
<div> <div>
<label for="name">Name</label> <label for="name">Name</label>
<input type="text" name="query_name" ng-model="queryName"></input> <input class="short" type="text" name="query_name" ng-model="queryName"></input>
</div> </div>
<div> <div>
<button ng-click="modal.closeMe()">Cancel</button> <button class="button_highlight" ng-click="saveQueryAs(queryName)">Save</button>
<button ng-click="saveQueryAs(queryName)">Save</button> <button class="button" ng-click="modal.closeMe()">Cancel</button>
</div> </div>
</div> </div>

@ -1,8 +1,8 @@
<div class="ng-modal-window"> <div class="ng-modal-window">
<div class="ng-modal-inner"> <div class="ng-modal-inner">
<a href class="ng-modal-close" ng-click="modal.closeMe()">&nbsp;</a> <div class="modal-header"><i class="icon-close" ng-click="modal.closeMe()"></i></div>
<h1>Settings</h1> <h3>Settings</h3>
</div> </div>
</div> </div>

@ -1,16 +1,16 @@
<div class="ng-modal-window"> <div class="ng-modal-window">
<div class="ng-modal-inner"> <div class="ng-modal-inner">
<a href class="ng-modal-close" ng-click="modal.closeMe()">&nbsp;</a> <div class="modal-header"><i class="icon-close" ng-click="modal.closeMe()"></i></div>
<h1>Share</h1> <h3>Share</h3>
<div> <div>
<label for="name">Page visible for others</label> <label for="name">Page visible for others</label>
<input type="checkbox" name="is_public" ng-model="query.isPublic"></input> <input type="checkbox" name="is_public" ng-model="query.isPublic"></input>
</div> </div>
<div> <div>
<button ng-click="modal.closeMe()">Cancel</button>
<button ng-click="saveQuery()">Save</button> <button ng-click="saveQuery()">Save</button>
<button ng-click="modal.closeMe()">Cancel</button>
</div> </div>
</div> </div>

@ -1,8 +1,24 @@
<div class="ng-modal-window"> <div class="ng-modal-window">
<div class="ng-modal-inner"> <div class="ng-modal-inner modal-content">
<a href class="ng-modal-close" ng-click="modal.closeMe()">&nbsp;</a> <div class="modal-header"><i class="icon-close" ng-click="modal.closeMe()"></i></div>
<h1>Sorting</h1> <h3>Sorting</h3>
<div ng-repeat="element in sortElements">
<input type="hidden"
ui-select2-sortable="sortByOptions"
simple-query="getAvailableColumnsData"
ng-model="element[0]"></input>
<input type="hidden"
ui-select2-sortable="sortDirectionOptions"
simple-query="getDirectionsData"
ng-model="element[1]"></input>
</div>
<div>
<button class="button_highlight" ng-click="updateSortation()">Apply</button>
<button class="button" ng-click="modal.closeMe()">Cancel</button>
</div>
</div> </div>
</div> </div>

@ -12,7 +12,8 @@
<li class="folder priority"> <li class="folder priority">
<a href="#" class="context_item">TODO Priority</a> <a href="#" class="context_item">TODO Priority</a>
<ul> <i class="icon-pulldown-arrow4 icon-submenu"></i>
<ul class="sub-menu">
<li><a href="#" class=" disabled">Immediate</a></li> <li><a href="#" class=" disabled">Immediate</a></li>
<li><a href="#" class=" disabled">Urgent</a></li> <li><a href="#" class=" disabled">Urgent</a></li>
<li><a href="#" class=" disabled">High</a></li> <li><a href="#" class=" disabled">High</a></li>

@ -212,7 +212,7 @@ describe 'Custom field accessibility' do
include_context "index page with query" include_context "index page with query"
it_behaves_like "localized table header" pending # it_behaves_like "localized table header"
end end
context "de" do context "de" do
@ -220,7 +220,7 @@ describe 'Custom field accessibility' do
include_context "index page with query" include_context "index page with query"
it_behaves_like "localized table header" pending # it_behaves_like "localized table header"
end end
end end

@ -44,7 +44,7 @@ describe 'Work package index accessibility' do
describe 'Select all link' do describe 'Select all link' do
def select_all_link def select_all_link
find('table.list.issues th.checkbox a') find('table.workpackages-table th.checkbox a')
end end
def description_for_blind def description_for_blind
@ -142,7 +142,7 @@ describe 'Work package index accessibility' do
describe 'id column' do describe 'id column' do
let(:link_caption) { '#' } let(:link_caption) { '#' }
let(:sort_header_selector) { 'table.list.issues th.checkbox + th' } let(:sort_header_selector) { 'table.workpackages-table th.checkbox + th + th' }
let(:sort_link_selector) { sort_header_selector + ' a' } let(:sort_link_selector) { sort_header_selector + ' a' }
it_behaves_like 'sortable column' it_behaves_like 'sortable column'
@ -152,7 +152,7 @@ describe 'Work package index accessibility' do
describe 'type column' do describe 'type column' do
let(:link_caption) { 'Type' } let(:link_caption) { 'Type' }
let(:sort_header_selector) { 'table.list.issues th.checkbox + th + th' } let(:sort_header_selector) { 'table.workpackages-table th.checkbox + th + th + th' }
let(:sort_link_selector) { sort_header_selector + ' a' } let(:sort_link_selector) { sort_header_selector + ' a' }
it_behaves_like 'sortable column' it_behaves_like 'sortable column'
@ -162,7 +162,7 @@ describe 'Work package index accessibility' do
describe 'status column' do describe 'status column' do
let(:link_caption) { 'Status' } let(:link_caption) { 'Status' }
let(:sort_header_selector) { 'table.list.issues th.checkbox + th + th + th' } let(:sort_header_selector) { 'table.workpackages-table th.checkbox + th + th + th + th' }
let(:sort_link_selector) { sort_header_selector + ' a' } let(:sort_link_selector) { sort_header_selector + ' a' }
it_behaves_like 'sortable column' it_behaves_like 'sortable column'
@ -172,7 +172,7 @@ describe 'Work package index accessibility' do
describe 'priority column' do describe 'priority column' do
let(:link_caption) { 'Priority' } let(:link_caption) { 'Priority' }
let(:sort_header_selector) { 'table.list.issues th.checkbox + th + th + th + th' } let(:sort_header_selector) { 'table.workpackages-table th.checkbox + th + th + th + th + th' }
let(:sort_link_selector) { sort_header_selector + ' a' } let(:sort_link_selector) { sort_header_selector + ' a' }
it_behaves_like 'sortable column' it_behaves_like 'sortable column'
@ -182,7 +182,7 @@ describe 'Work package index accessibility' do
describe 'subject column' do describe 'subject column' do
let(:link_caption) { 'Subject' } let(:link_caption) { 'Subject' }
let(:sort_header_selector) { 'table.list.issues th.checkbox + th + th + th + th + th' } let(:sort_header_selector) { 'table.workpackages-table th.checkbox + th + th + th + th + th + th' }
let(:sort_link_selector) { sort_header_selector + ' a' } let(:sort_link_selector) { sort_header_selector + ' a' }
it_behaves_like 'sortable column' it_behaves_like 'sortable column'
@ -192,7 +192,7 @@ describe 'Work package index accessibility' do
describe 'assigned to column' do describe 'assigned to column' do
let(:link_caption) { 'Assignee' } let(:link_caption) { 'Assignee' }
let(:sort_header_selector) { 'table.list.issues th.checkbox + th + th + th + th + th + th' } let(:sort_header_selector) { 'table.workpackages-table th.checkbox + th + th + th + th + th + th + th' }
let(:sort_link_selector) { sort_header_selector + ' a' } let(:sort_link_selector) { sort_header_selector + ' a' }
it_behaves_like 'sortable column' it_behaves_like 'sortable column'

Loading…
Cancel
Save