diff --git a/app/assets/javascripts/angular/controllers/dialogs/share.js b/app/assets/javascripts/angular/controllers/dialogs/share.js index 66a130d220..2813376580 100644 --- a/app/assets/javascripts/angular/controllers/dialogs/share.js +++ b/app/assets/javascripts/angular/controllers/dialogs/share.js @@ -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); + } }); }; }]); diff --git a/app/assets/javascripts/angular/helpers/components/path-helper.js b/app/assets/javascripts/angular/helpers/components/path-helper.js index 5dbbe6ef87..a8793b437c 100644 --- a/app/assets/javascripts/angular/helpers/components/path-helper.js +++ b/app/assets/javascripts/angular/helpers/components/path-helper.js @@ -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(); diff --git a/app/assets/javascripts/angular/models/query.js b/app/assets/javascripts/angular/models/query.js index aa1792d89c..2f0eaa6670 100644 --- a/app/assets/javascripts/angular/models/query.js +++ b/app/assets/javascripts/angular/models/query.js @@ -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()); }, diff --git a/app/assets/javascripts/angular/services/query-service.js b/app/assets/javascripts/angular/services/query-service.js index 452d574e78..9529e72cad 100644 --- a/app/assets/javascripts/angular/services/query-service.js +++ b/app/assets/javascripts/angular/services/query-service.js @@ -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({ diff --git a/app/controllers/api/experimental/queries_controller.rb b/app/controllers/api/experimental/queries_controller.rb index a8a5ec6f9f..20891c46f9 100644 --- a/app/controllers/api/experimental/queries_controller.rb +++ b/app/controllers/api/experimental/queries_controller.rb @@ -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] diff --git a/app/controllers/api/experimental/work_packages_controller.rb b/app/controllers/api/experimental/work_packages_controller.rb index 1f4a07ad4d..080ea56b75 100644 --- a/app/controllers/api/experimental/work_packages_controller.rb +++ b/app/controllers/api/experimental/work_packages_controller.rb @@ -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, diff --git a/app/models/query.rb b/app/models/query.rb index 71d242e2fa..44c836f963 100644 --- a/app/models/query.rb +++ b/app/models/query.rb @@ -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) diff --git a/config/locales/js-de.yml b/config/locales/js-de.yml index b9c1883014..4ceffda945 100644 --- a/config/locales/js-de.yml +++ b/config/locales/js-de.yml @@ -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" diff --git a/config/locales/js-en.yml b/config/locales/js-en.yml index 7b9ff71a34..eeb576b89f 100644 --- a/config/locales/js-en.yml +++ b/config/locales/js-en.yml @@ -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" diff --git a/public/templates/work_packages/modals/share.html b/public/templates/work_packages/modals/share.html index 6a9b2b856d..d6b86dac5c 100644 --- a/public/templates/work_packages/modals/share.html +++ b/public/templates/work_packages/modals/share.html @@ -4,11 +4,20 @@