Merge pull request #1493 from opf/feature/api-queries-star-share-modal

Feature/api queries star share modal
pull/1497/head
Till Breuer 11 years ago
commit 6c3d0effdf
  1. 27
      app/assets/javascripts/angular/controllers/dialogs/share.js
  2. 30
      app/assets/javascripts/angular/helpers/components/path-helper.js
  3. 8
      app/assets/javascripts/angular/models/query.js
  4. 37
      app/assets/javascripts/angular/services/query-service.js
  5. 1
      app/controllers/api/experimental/queries_controller.rb
  6. 2
      app/controllers/api/experimental/work_packages_controller.rb
  7. 5
      app/models/query.rb
  8. 1
      config/locales/js-de.yml
  9. 1
      config/locales/js-en.yml
  10. 19
      public/templates/work_packages/modals/share.html

@ -38,19 +38,40 @@ angular.module('openproject.workPackages.controllers')
.controller('ShareModalController', [
'$scope',
'I18n',
'shareModal',
'QueryService',
function($scope, shareModal, QueryService) {
function($scope, I18n, shareModal, QueryService) {
this.name = 'Share';
this.closeMe = shareModal.deactivate;
$scope.query = QueryService.getQuery();
$scope.shareSettings = {
starred: $scope.query.starred
};
closeAndReport = function(message) {
shareModal.deactivate();
$scope.$emit('flashMessage', message);
};
$scope.saveQuery = function() {
var messageObject;
QueryService.saveQuery()
.then(function(data){
shareModal.deactivate();
$scope.$emit('flashMessage', data.status);
messageObject = data.status;
})
.then(function(data){
if($scope.query.starred != $scope.shareSettings.starred){
QueryService.toggleQueryStarred()
.then(function(data){
messageObject.text = messageObject.text + " " + I18n.t('js.work_packages.message_please_refresh');
closeAndReport(messageObject);
});
} else {
closeAndReport(messageObject);
}
});
};
}]);

@ -32,7 +32,8 @@ angular.module('openproject.helpers')
.service('PathHelper', [function() {
PathHelper = {
apiPrefixV2: '/api/v2',
apiPrefixV3: '/api/experimental',
apiPrefixExperimental: '/api/experimental',
apiPrefixV3: '/api/v3',
activityPath: function(projectIdentifier, from) {
var link = '/activity';
@ -118,13 +119,16 @@ angular.module('openproject.helpers')
return PathHelper.apiPrefixV2 + PathHelper.projectPath(projectIdentifier);
},
apiV3ProjectsPath: function(){
return PathHelper.apiPrefixV3 + PathHelper.projectsPath();
return PathHelper.apiPrefixExperimental + PathHelper.projectsPath();
},
apiV3ProjectPath: function(projectIdentifier) {
return PathHelper.apiPrefixV3 + PathHelper.projectPath(projectIdentifier);
return PathHelper.apiPrefixExperimental + PathHelper.projectPath(projectIdentifier);
},
apiV3QueryPath: function(queryId) {
return PathHelper.apiPrefixV3 + PathHelper.queryPath(queryId);
},
apiWorkPackagesPath: function() {
return PathHelper.apiPrefixV3 + '/work_packages';
return PathHelper.apiPrefixExperimental + '/work_packages';
},
apiProjectWorkPackagesPath: function(projectIdentifier) {
return PathHelper.apiV3ProjectPath(projectIdentifier) + PathHelper.workPackagesPath();
@ -139,13 +143,13 @@ angular.module('openproject.helpers')
return PathHelper.apiV3ProjectPath(projectIdentifier) + PathHelper.queryPath(queryIdentifier);
},
apiGroupedQueriesPath: function() {
return PathHelper.apiPrefixV3 + '/queries/grouped';
return PathHelper.apiPrefixExperimental + '/queries/grouped';
},
apiAvailableColumnsPath: function() {
return PathHelper.apiPrefixV3 + '/queries/available_columns';
return PathHelper.apiPrefixExperimental + '/queries/available_columns';
},
apiCustomFieldsPath: function() {
return PathHelper.apiPrefixV3 + '/queries/custom_field_filters';
return PathHelper.apiPrefixExperimental + '/queries/custom_field_filters';
},
apiProjectCustomFieldsPath: function(projectIdentifier) {
return PathHelper.apiV3ProjectPath(projectIdentifier) + '/queries/custom_field_filters';
@ -156,6 +160,12 @@ angular.module('openproject.helpers')
apiProjectGroupedQueriesPath: function(projectIdentifier) {
return PathHelper.apiV3ProjectPath(projectIdentifier) + '/queries/grouped';
},
apiQueryStarPath: function(queryId) {
return PathHelper.apiV3QueryPath(queryId) + '/star';
},
apiQueryUnstarPath: function(queryId) {
return PathHelper.apiV3QueryPath(queryId) + '/unstar';
},
apiWorkPackagesColumnDataPath: function() {
return PathHelper.apiWorkPackagesPath() + '/column_data';
},
@ -169,10 +179,10 @@ angular.module('openproject.helpers')
return PathHelper.apiV2ProjectPath(projectIdentifier) + '/statuses';
},
apiGroupsPath: function() {
return PathHelper.apiPrefixV3 + '/groups';
return PathHelper.apiPrefixExperimental + '/groups';
},
apiRolesPath: function() {
return PathHelper.apiPrefixV3 + '/roles';
return PathHelper.apiPrefixExperimental + '/roles';
},
apiWorkPackageTypesPath: function() {
return PathHelper.apiPrefixV2 + '/planning_element_types';
@ -181,7 +191,7 @@ angular.module('openproject.helpers')
return PathHelper.apiV2ProjectPath(projectIdentifier) + '/planning_element_types';
},
apiUsersPath: function() {
return PathHelper.apiPrefixV3 + PathHelper.usersPath();
return PathHelper.apiPrefixExperimental + PathHelper.usersPath();
},
apiProjectVersionsPath: function(projectIdentifier) {
return PathHelper.apiV3ProjectPath(projectIdentifier) + PathHelper.versionsPath();

@ -89,6 +89,14 @@ angular.module('openproject.models')
return this;
},
star: function() {
this.starred = true;
},
unstar: function() {
this.starred = false;
},
getQueryString: function(){
return UrlParamsHelper.buildQueryString(this.toParams());
},

@ -70,7 +70,8 @@ angular.module('openproject.services')
columns: selectedColumns,
groupBy: queryData.group_by,
isPublic: queryData.is_public,
exportFormats: exportFormats
exportFormats: exportFormats,
starred: queryData.starred
});
query.setSortation(new Sortation(queryData.sort_criteria));
@ -325,17 +326,49 @@ angular.module('openproject.services')
});
},
toggleQueryStarred: function() {
if(query.starred) {
return QueryService.unstarQuery();
} else {
return QueryService.starQuery();
}
},
starQuery: function() {
var url = PathHelper.apiQueryStarPath(query.id);
var theQuery = query;
return QueryService.doPatch(url, function(response){
theQuery.star();
return response.data;
});
},
unstarQuery: function() {
var url = PathHelper.apiQueryUnstarPath(query.id);
var theQuery = query;
return QueryService.doPatch(url, function(response){
theQuery.unstar();
return response.data;
});
},
doGet: function(url, success, failure) {
return QueryService.doQuery(url, null, 'GET', success, failure);
},
doPatch: function(url, success, failure) {
return QueryService.doQuery(url, null, 'PATCH', success, failure);
},
doQuery: function(url, params, method, success, failure) {
method = method || 'GET';
success = success || function(response){
return response.data;
};
failure = failure || function(response){
return angular.extend(response.data, { status: { text: I18n.t('js.notice_bad_request'), isError: true }} );
return angular.extend(response, { status: { text: I18n.t('js.notice_bad_request'), isError: true }} );
};
return $http({

@ -125,7 +125,6 @@ module Api::Experimental
view_context.add_filter_from_params if params[:fields] || params[:f]
@query.group_by = params[:group_by] if params[:group_by].present?
@query.sort_criteria = prepare_sort_criteria if params[:sort]
@query.project = nil if params[:query_is_for_all]
@query.display_sums = params[:display_sums] if params[:display_sums].present?
@query.column_names = params[:c] if params[:c]
@query.column_names = nil if params[:default_columns]

@ -165,7 +165,7 @@ module Api
def set_work_packages_meta_data(query, results, work_packages)
@display_meta = true
@work_packages_meta_data = {
query: query.as_json(except: :filters, include: :filters),
query: query.as_json(except: :filters, include: :filters, methods: [:starred]),
columns: get_columns_for_json(query.columns),
groupable_columns: get_columns_for_json(query.groupable_columns),
work_package_count_by_group: results.work_package_count_by_group,

@ -440,6 +440,11 @@ class Query < ActiveRecord::Base
raise ::Query::StatementInvalid.new(e.message)
end
# Note: Convenience method to allow the angular front end to deal with query menu items in a non implementation-specific way
def starred
!!query_menu_item
end
private
def custom_field_id(filter)

@ -211,6 +211,7 @@ de:
label_options: "Optionen"
message_error_during_bulk_delete: Fehler beim Löschen der Arbeitspakete.
message_successful_bulk_delete: Arbeitspakete erfolgreich gelöscht.
message_please_refresh: "Bitte laden Sie die Seite neu, um Änderungen am Menü sichtbar zu machen."
description_filter: "Filter"
description_enter_text: "Text eingeben"
description_options_hide: "Optionen ausblenden"

@ -214,6 +214,7 @@ en:
label_options: "Options"
message_error_during_bulk_delete: An error occurred while trying to delete work packages.
message_successful_bulk_delete: Successfully deleted work packages.
message_please_refresh: Please refresh page to see changes to menu.
description_filter: "Filter"
description_enter_text: "Enter text"
description_options_hide: "Hide options"

@ -4,11 +4,20 @@
<h3>Share</h3>
<label class="checkbox-label">
<input type="checkbox" name="is_public" ng-model="query.isPublic"></input>
<div class="styled-checkbox"></div>
Page visible for others
</label>
<div>
<label class="checkbox-label">
<input type="checkbox" name="is_public" ng-model="query.isPublic"></input>
<div class="styled-checkbox"></div>
Page visible for others
</label>
</div>
<div>
<label class="checkbox-label">
<input type="checkbox" name="show_in_menu" ng-model="shareSettings.starred"></input>
<div class="styled-checkbox"></div>
Show page in menu
</label>
</div>
<div>
<button class="button_highlight" ng-click="saveQuery()">Save</button>
<button class="button" ng-click="modal.closeMe()">Cancel</button>

Loading…
Cancel
Save