diff --git a/app/assets/javascripts/angular/hal/api-resource.js b/app/assets/javascripts/angular/hal/api-resource.js new file mode 100644 index 0000000000..1a36552084 --- /dev/null +++ b/app/assets/javascripts/angular/hal/api-resource.js @@ -0,0 +1,46 @@ + +angular.module('openproject.hal') + +.factory('HALAPIResource', function HALAPIResource() { + 'use strict'; + + var HALAPIResource = { + parseApiaryResponse: function(json) { + // Apiary mock response isn't valid json so i'm mocking the mock:/ TODO: Get this from a file + var mockWorkPackageResponse = "{ \"_type\": \"WorkPackage\", \"_links\": { \"self\": { \"href\": \"https://openproject.org/api/v3/work_packages/1\", \"title\": \"quis numquam qui voluptatum quia praesentium blanditiis nisi\" } }, \"_embedded\": { \"activities\": [ { \"_type\": \"Activity\", \"_links\": { \"self\": { \"href\": \"https://openproject.org/api/v3/activity/1\", \"title\": \"Priority changed from High to Low\" }, \"workPackage\": { \"href\": \"https://openproject.org/api/v3/work_packages/1\", \"title\": \"quis numquam qui voluptatum quia praesentium blanditiis nisi\" }, \"user\": { \"href\": \"https://openproject.org/api/v3/users/1\", \"title\": \"John Sheppard - admin\" } }, \"id\": 1, \"userId\": 1, \"userName\": \"OpenProject Admin\", \"userLogin\": \"admin\", \"userMail\": \"admin@example.net\", \"notes\": \"Lorem ipsum dolor sit amet\", \"details\": [ \"Priority changed from High to Low\" ], \"createdAt\": \"2014-05-21T08: 51: 20Z\", \"version\": 31 } ], \"watchers\": [ { \"_type\": \"User\", \"_links\": { \"self\": { \"href\": \"https: //openproject.org/api/v3/users/1\", \"title\": \"JohnSheppard-admin\" }, \"workPackage\": { \"href\": \"https: //openproject.org/api/v3/work_packages/1\", \"title\": \"quisnumquamquivoluptatumquiapraesentiumblanditiisnisi\" } }, \"id\": 1, \"login\": \"admin\", \"firstname\": \"John\", \"lastname\": \"Sheppard\", \"mail\": \"admin@example.net\", \"type\": \"User\", \"createdAt\": \"2014-05-21T08: 51: 20Z\", \"updatedAt\": \"2014-05-22T09: 41: 29Z\" } ], \"relations\": [ { \"_type\": \"Relationship\", \"_links\": { \"self\": { \"href\": \"https: //openproject.org/api/v3/relationships/1\", \"title\": \"WorkpackageAduplicatedbyWorkpackageB\" }, \"workPackage\": { \"href\": \"https: //openproject.org/api/v3/work_packages/1\", \"title\": \"quisnumquamquivoluptatumquiapraesentiumblanditiisnisi\" }, \"relatedWorkPackage\": { \"href\": \"https: //openproject.org/api/v3/work_packages/2\", \"title\": \"Loremipsum\" } }, \"id\": 1, \"type\": \"duplicates\", \"relatedWorkPackageId\": 2, \"relatedWorkPackageSubject\": \"Loremipsum\", \"relatedWorkPackageType\": \"Bug\", \"relatedWorkPackageStartDate\": \"2014-05-29\", \"relatedWorkPackageDueDate\": \"2014-08-29\" } ], \"attachments\": [ { \"_type\": \"Attachment\", \"_links\": { \"self\": { \"href\": \"https: //openproject.org/api/v3/attachments/1\", \"title\": \"Attachmentfilename\" }, \"workPackage\": { \"href\": \"https: //openproject.org/api/v3/work_packages/1\", \"title\": \"quisnumquamquivoluptatumquiapraesentiumblanditiisnisi\" }, \"author\": { \"href\": \"https: //openproject.org/api/v3/users/1\", \"title\": \"Userslogin\" } }, \"id\": 1, \"filename\": \"Attachmentfilename\", \"filesize\": 30, \"contentType\": \"txt\", \"description\": \"Loremipsumdolorsitamet.\", \"authorName\": \"JohnSheppard\", \"authorLogin\": \"admin\", \"authorMail\": \"admin@example.net\", \"createdAt\": \"2014-05-21T08: 51: 20Z\" } ] }, \"id\": 1, \"subject\": \"quisnumquamquivoluptatumquiapraesentiumblanditiisnisi\", \"type\": \"Support\", \"description\": \"Cruxveleosdoloresadmoveosummaveritatisacerbitas.Deleovenustascubocurtusbalbussumoambitusvalens.Tenercotidieangelusillo.Citovertocomburo.Tergeovinculumsuccedoullussuppono.\", \"status\": \"New\", \"priority\": \"Normal\", \"startDate\": \"2014-05-29\", \"dueDate\": \"2014-08-29\", \"estimatedTime\": { \"units\": \"hours\", \"value\": 10 }, \"percentageDone\": 0, \"targetVersionId\": 1, \"targetVersionName\": \"sprint-01\", \"projectId\": 1, \"projectName\": \"SeededProject\", \"responsibleId\": 1, \"responsibleName\": \"OpenProjectAdmin\", \"responsibleLogin\": \"admin\", \"responsibleMail\": \"admin@example.net\", \"assigneeId\": 22, \"assigneeName\": \"VivienneWindler\", \"assigneeLogin\": \"Yoshiko8884\", \"assigneeMail\": \"gabriel.osinski@glover.name\", \"authorName\": \"DeliaSchneider\", \"authorLogin\": \"Layla3137\", \"authorMail\": \"charlene.terry@stromanko.org\", \"createdAt\": \"2014-05-21T08: 51: 20Z\", \"updatedAt\": \"2014-05-22T09: 41: 29Z\", \"customProperties\": [ { \"name\": \"Mycustomfield1\", \"format\": \"text\", \"value\": \"Loremipsum\" } ]}"; + return mockWorkPackageResponse; + }, + + configure: function() { + // Configure Hyperagent to prefix every URL with the unicorn proxy. + Hyperagent.configure('ajax', function ajax(options) { + options.url = 'https://unicorn-cors-proxy.herokuapp.com/' + options.url; + options.converters = { + // Convert anything to text + "* text": window.String, + // Text to html (true = no transformation) + "text html": true, + // Evaluate text as a json expression + "text json": HALAPIResource.parseApiaryResponse, + // Parse text as xml + "text xml": jQuery.parseXML + } + options.dataType = "json"; + + return jQuery.ajax(options); + }); + }, + + setup: function(uri) { + HALAPIResource.configure(); + return new Hyperagent.Resource({ + url: 'http://opapi.apiary-mock.com/' + uri, + headers: { + 'X-Requested-With': 'Hyperagent' + } + }); + } + } + + return HALAPIResource; +}); \ No newline at end of file diff --git a/app/assets/javascripts/angular/openproject-app.js b/app/assets/javascripts/angular/openproject-app.js index b07cd30647..dd5239d4ee 100644 --- a/app/assets/javascripts/angular/openproject-app.js +++ b/app/assets/javascripts/angular/openproject-app.js @@ -104,6 +104,8 @@ angular.module('openproject.timeEntries.controllers', []); angular.module('openproject.layout', []); +angular.module('openproject.hal', []); + // main app var openprojectApp = angular.module('openproject', [ 'ui.select2', @@ -121,7 +123,8 @@ var openprojectApp = angular.module('openproject', [ 'truncate', 'feature-flags', 'openproject.layout', - 'cgBusy' + 'cgBusy', + 'openproject.hal' ]); window.appBasePath = jQuery('meta[name=app_base_path]').attr('content') || ''; diff --git a/app/assets/javascripts/angular/services/work-package-service.js b/app/assets/javascripts/angular/services/work-package-service.js index 22a7db7440..2d3ac40d9e 100644 --- a/app/assets/javascripts/angular/services/work-package-service.js +++ b/app/assets/javascripts/angular/services/work-package-service.js @@ -34,10 +34,22 @@ angular.module('openproject.services') '$http', 'PathHelper', 'WorkPackagesHelper', + 'HALAPIResource', 'DEFAULT_FILTER_PARAMS', - function($http, PathHelper, WorkPackagesHelper, DEFAULT_FILTER_PARAMS) { + function($http, PathHelper, WorkPackagesHelper, HALAPIResource, DEFAULT_FILTER_PARAMS) { + var workPackage; var WorkPackageService = { + getWorkPackage: function(id) { + var resource = HALAPIResource.setup("work_packages/" + id); + return resource.fetch().then(function (wp) { + workPackage = wp; + return workPackage; + }).fail(function(error){ + // Do something sensible + }); + }, + getWorkPackagesByQueryId: function(projectIdentifier, queryId) { var url = projectIdentifier ? PathHelper.apiProjectWorkPackagesPath(projectIdentifier) : PathHelper.apiWorkPackagesPath(); diff --git a/app/assets/javascripts/angular/work_packages/controllers/work-package-details-controller.js b/app/assets/javascripts/angular/work_packages/controllers/work-package-details-controller.js index 438c73b793..ea8a228fa8 100644 --- a/app/assets/javascripts/angular/work_packages/controllers/work-package-details-controller.js +++ b/app/assets/javascripts/angular/work_packages/controllers/work-package-details-controller.js @@ -31,17 +31,12 @@ angular.module('openproject.workPackages.controllers') .controller('WorkPackageDetailsController', [ '$scope', '$stateParams', - function($scope, $stateParams) { + 'WorkPackageService', + function($scope, $stateParams, WorkPackageService) { $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 : {}; - } + WorkPackageService.getWorkPackage($scope.workPackageId).then(function(workPackage) { + $scope.workPackage = workPackage; }); } ]); diff --git a/app/assets/javascripts/angular/work_packages/controllers/work-packages-list-controller.js b/app/assets/javascripts/angular/work_packages/controllers/work-packages-list-controller.js index ecfd4cbf45..150b5b21b8 100644 --- a/app/assets/javascripts/angular/work_packages/controllers/work-packages-list-controller.js +++ b/app/assets/javascripts/angular/work_packages/controllers/work-packages-list-controller.js @@ -42,17 +42,17 @@ angular.module('openproject.workPackages.controllers') 'PaginationService', 'AuthorisationService', 'WorkPackageLoadingHelper', + 'HALAPIResource', 'INITIALLY_SELECTED_COLUMNS', 'OPERATORS_AND_LABELS_BY_FILTER_TYPE', function($scope, $rootScope, $q, $location, $stateParams, I18n, WorkPackagesTableService, WorkPackageService, ProjectService, QueryService, PaginationService, - AuthorisationService, WorkPackageLoadingHelper, INITIALLY_SELECTED_COLUMNS, + AuthorisationService, WorkPackageLoadingHelper, HALAPIResource, INITIALLY_SELECTED_COLUMNS, OPERATORS_AND_LABELS_BY_FILTER_TYPE) { // Setup - function initialSetup() { $scope.operatorsAndLabelsByFilterType = OPERATORS_AND_LABELS_BY_FILTER_TYPE; $scope.disableFilters = false; diff --git a/app/assets/javascripts/application.js.erb b/app/assets/javascripts/application.js.erb index daa5a7f92c..7c8312603a 100644 --- a/app/assets/javascripts/application.js.erb +++ b/app/assets/javascripts/application.js.erb @@ -53,6 +53,10 @@ //= require warn_leaving_unsaved //= require openproject_plugins //= require versions +//= require q/q +//= require uri.js/src/URI +//= require uri.js/src/URITemplate +//= require hyperagent/dist/hyperagent //= require_tree ./specific //= require angular diff --git a/bower.json b/bower.json index 916d826b80..d05892ab79 100644 --- a/bower.json +++ b/bower.json @@ -24,7 +24,8 @@ "momentjs": "~2.6.0", "moment-timezone": "~0.0.6", "angular-context-menu": "0.1.2", - "angular-busy": "~4.0.4" + "angular-busy": "~4.0.4", + "hyperagent": "latest" }, "devDependencies": { "mocha": "~1.14.0", diff --git a/public/templates/work_packages.list.details.html b/public/templates/work_packages.list.details.html index b587360d56..a3be869884 100644 --- a/public/templates/work_packages.list.details.html +++ b/public/templates/work_packages.list.details.html @@ -1,26 +1,26 @@ -
+

- {{ workPackage.type.name }} - {{ workPackage.subject }} + {{ workPackage.props.type }} + {{ workPackage.props.subject }}

- #{{ workPackage.id }} + #{{ workPackage.props.id }}

Description

-

TODO: Add description

+

{{ workPackage.props.description }}

Status
-
{{ workPackage.status.name }}
+
{{ workPackage.props.status }}
Priority
-
{{ workPackage.priority.name }}
+
{{ workPackage.props.priority }}
Date
Responsible
-
{{ workPackage.assigned_to }}
+
{{ workPackage.props.responsibleName }}
Assignee
-
+
{{ workPackage.props.assigneeName }}
% Done
-
+
{{ percentageDone }}
@@ -37,6 +37,6 @@
-
+

Select a work package for more information.