more camelcase for the experimental api

pull/4159/head
Jens Ulferts 9 years ago
parent 7ad12c0cad
commit 9bf8993908
  1. 15
      app/controllers/api/experimental/concerns/v3_naming.rb
  2. 17
      frontend/app/components/api/api-work-packages/api-work-packages.service.ts
  3. 12
      frontend/app/components/query/query-service.service.test.js
  4. 46
      frontend/app/components/query/query-service.service.ts
  5. 22
      frontend/app/components/query/query.service.js
  6. 19
      frontend/app/components/work-packages/work-package.service.js
  7. 4
      frontend/app/helpers/url-params-helper.js
  8. 14
      frontend/app/typings/open-project.typings.ts
  9. 474
      frontend/tests/integration/mocks/work-packages.json

@ -57,18 +57,27 @@ module Api::Experimental::Concerns::V3Naming
"#{v3_to_internal_name(criteria.first, append_id: false)}:#{criteria.last}"
}.join(',')
end if params[:sort]
params[:group_by] = params.delete(:groupBy)
params[:project_id] = params.delete(:projectId)
params[:display_sums] = params.delete(:displaySums)
params[:is_public] = params.delete(:isPublic)
params[:user_id] = params.delete(:userId)
end
def json_query_as_v3(json_query)
json_query['column_names'] = (json_query['column_names'] || []).map { |column|
json_query['columnNames'] = (json_query.delete('column_names') || [] ).map { |column|
internal_to_v3_name(column)
}
json_query['sort_criteria'] = (json_query['sort_criteria'] || []).map { |criteria|
json_query['sortCriteria'] = (json_query.delete('sort_criteria') || [] ).map { |criteria|
[internal_to_v3_name(criteria.first), criteria.last]
}
json_query['group_by'] = internal_to_v3_name(json_query['group_by'])
json_query['groupBy'] = internal_to_v3_name(json_query.delete('group_by'))
json_query['projectId'] = json_query.delete('project_id')
json_query['displaySums'] = json_query.delete('display_sums')
json_query['isPublic'] = json_query.delete('is_public')
json_query['userId'] = json_query.delete('user_id')
json_query['filters'].each do |filter|
filter[:name] = internal_to_v3_name(filter[:name])

@ -36,8 +36,8 @@ export class ApiWorkPackagesService {
public list(offset:number, pageSize:number, query:api.ex.Query) {
var workPackages;
if (query.project_id) {
workPackages = this.apiV3.service('work_packages', this.apiV3.one('projects', query.project_id));
if (query.projectId) {
workPackages = this.apiV3.service('work_packages', this.apiV3.one('projects', query.projectId));
}
else {
workPackages = this.apiV3.service('work_packages');
@ -60,25 +60,16 @@ export class ApiWorkPackagesService {
filters: [v3Filters]
};
if (query.group_by) {
params.groupBy = query.group_by;
}
if (query.groupBy) {
params.groupBy = query.groupBy;
}
// TODO: why is it display_sums sometimes and displaySums at other times
if (query.display_sums) {
params.showSums = query.display_sums;
}
if (query.displaySums) {
params.showSums = query.displaySums;
}
if (query.sort_criteria) {
params.sortBy = [query.sort_criteria];
if (query.sortCriteria) {
params.sortBy = [query.sortCriteria];
}
return params;

@ -57,10 +57,10 @@ describe('QueryService', function() {
beforeEach(function() {
queryData = {
group_by: 'type',
display_sums: 1,
groupBy: 'type',
displaySums: 1,
filters: {
type_id: {
type: {
operator: '~',
values: ['Bug', 'Feature']
}
@ -71,11 +71,11 @@ describe('QueryService', function() {
});
it('should set query.groupBy', function() {
expect(query.groupBy).to.equal(queryData.group_by);
expect(query.groupBy).to.equal(queryData.groupBy);
});
it('should set query.displaySums', function() {
expect(query.displaySums).to.equal(queryData.display_sums);
expect(query.displaySums).to.equal(queryData.displaySums);
});
describe('filters', function() {
@ -92,7 +92,7 @@ describe('QueryService', function() {
var spy;
beforeEach(function() {
spy = sinon.spy($rootScope, '$broadcast');
queryData = { name: '_', 'project_id': 1 };
queryData = { name: '_', 'projectId': 1 };
QueryService.initQuery(1, queryData);
var path = PathHelper.apiProjectQueryPath(1, 1);
$httpBackend.when('DELETE', new RegExp(path + '*')).respond(200, []);

@ -61,20 +61,20 @@ function QueryService(Query,
query = new Query({
id: queryId,
name: queryData.name,
project_id: queryData.project_id,
displaySums: queryData.display_sums,
groupSums: queryData.group_sums,
projectId: queryData.projectId,
displaySums: queryData.displaySums,
groupSums: queryData.groupSums,
sums: queryData.sums,
columns: selectedColumns,
groupBy: queryData.group_by,
isPublic: queryData.is_public,
groupBy: queryData.groupBy,
isPublic: queryData.isPublic,
exportFormats: exportFormats,
starred: queryData.starred,
links: queryData._links
});
query.setSortation(queryData.sort_criteria);
query.setSortation(queryData.sortCriteria);
QueryService.getAvailableFilters(query.project_id)
QueryService.getAvailableFilters(query.projectId)
.then(function(availableFilters) {
query.setAvailableWorkPackageFilters(availableFilters);
if (query.isDefault()) {
@ -94,21 +94,21 @@ function QueryService(Query,
updateQuery: function(values, afterUpdate) {
var queryData = {
};
if(!!values.display_sums) {
queryData.displaySums = values.display_sums;
if(!!values.displaySums) {
queryData.displaySums = values.displaySums;
}
if(!!values.columns) {
queryData.columns = values.columns;
}
if(!!values.group_by) {
queryData.groupBy = values.group_by;
if(!!values.groupBy) {
queryData.groupBy = values.groupBy;
}
if(!!values.sort_criteria) {
queryData.sortCriteria = values.sort_criteria;
if(!!values.sortCriteria) {
queryData.sortCriteria = values.sortCriteria;
}
query.update(queryData);
QueryService.getAvailableFilters(query.project_id)
QueryService.getAvailableFilters(query.projectId)
.then(function(availableFilters) {
query.setAvailableWorkPackageFilters(availableFilters);
if(queryData.filters && queryData.filters.length) {
@ -335,11 +335,11 @@ function QueryService(Query,
// synchronization
saveQuery: function() {
var url = query.project_id ? PathHelper.apiProjectQueryPath(query.project_id, query.id) : PathHelper.apiQueryPath(query.id);
var url = query.projectId ? PathHelper.apiProjectQueryPath(query.projectId, query.id) : PathHelper.apiQueryPath(query.id);
return QueryService.doQuery(url, query.toUpdateParams(), 'PUT', function(response) {
query.dirty = false;
QueryService.fetchAvailableGroupedQueries(query.project_id);
QueryService.fetchAvailableGroupedQueries(query.projectId);
return angular.extend(response.data, { status: { text: I18n.t('js.notice_successful_update') }} );
});
@ -347,11 +347,11 @@ function QueryService(Query,
saveQueryAs: function(name) {
query.setName(name);
var url = query.project_id ? PathHelper.apiProjectQueriesPath(query.project_id) : PathHelper.apiQueriesPath();
var url = query.projectId ? PathHelper.apiProjectQueriesPath(query.projectId) : PathHelper.apiQueriesPath();
return QueryService.doQuery(url, query.toParams(), 'POST', function(response){
query.save(response.data.query);
QueryService.fetchAvailableGroupedQueries(query.project_id);
QueryService.fetchAvailableGroupedQueries(query.projectId);
// The starred-state does not get saved via the API. So we manually
// set it, if the old query was starred.
@ -365,13 +365,13 @@ function QueryService(Query,
deleteQuery: function() {
var url;
if(_.isNull(query.project_id)) {
if(_.isNull(query.projectId)) {
url = PathHelper.apiQueryPath(query.id);
} else {
url = PathHelper.apiProjectQueryPath(query.project_id, query.id);
url = PathHelper.apiProjectQueryPath(query.projectId, query.id);
}
return QueryService.doQuery(url, query.toUpdateParams(), 'DELETE', function(response){
QueryService.fetchAvailableGroupedQueries(query.project_id);
QueryService.fetchAvailableGroupedQueries(query.projectId);
$rootScope.$broadcast('openproject.layout.removeMenuItem', {
itemType: QUERY_MENU_ITEM_TYPE,
@ -382,8 +382,8 @@ function QueryService(Query,
},
getQueryPath: function(query) {
if (query.project_id) {
return PathHelper.projectWorkPackagesPath(query.project_id) + '?query_id=' + query.id;
if (query.projectId) {
return PathHelper.projectWorkPackagesPath(query.projectId) + '?query_id=' + query.id;
} else {
return PathHelper.workPackagesPath() + '?query_id=' + query.id;
}

@ -62,11 +62,11 @@ function QueryConstructorService(Filter, Sortation, UrlParamsHelper, INITIALLY_S
{
'f[]': this.getFilterNames(this.getActiveConfiguredFilters()),
'c[]': this.getParamColumns(),
'group_by': this.groupBy,
'groupBy': this.groupBy,
'sort': this.getEncodedSortation(),
'display_sums': this.displaySums,
'displaySums': this.displaySums,
'name': this.name,
'is_public': this.isPublic,
'isPublic': this.isPublic,
'accept_empty_query_fields': this.isDirty(),
}].concat(this.getActiveConfiguredFilters().map(function(filter) {
return filter.toParams();
@ -78,14 +78,14 @@ function QueryConstructorService(Filter, Sortation, UrlParamsHelper, INITIALLY_S
return angular.extend.apply(this, [
{
'id': this.id,
'query_id': this.id,
'queryId': this.id,
'f[]': this.getFilterNames(this.getActiveConfiguredFilters()),
'c[]': this.getParamColumns(),
'group_by': this.groupBy,
'groupBy': this.groupBy,
'sort': this.getEncodedSortation(),
'display_sums': this.displaySums,
'displaySums': this.displaySums,
'name': this.name,
'is_public': this.isPublic,
'isPublic': this.isPublic,
'accept_empty_query_fields': this.isDirty()
}].concat(this.getActiveConfiguredFilters().map(function(filter) {
return filter.toParams();
@ -158,10 +158,10 @@ function QueryConstructorService(Filter, Sortation, UrlParamsHelper, INITIALLY_S
setAvailableWorkPackageFilters: function(availableFilters) {
this.availableWorkPackageFilters = availableFilters;
if (this.project_id){
delete this.availableWorkPackageFilters["project_id"];
if (this.projectId){
delete this.availableWorkPackageFilters['project'];
} else {
delete this.availableWorkPackageFilters["subproject_id"];
delete this.availableWorkPackageFilters['subprojectId'];
}
// TODO RS: Need to assertain if there are any sub-projects and remove filter if not.
// The project will have to be fetched prior to this.
@ -224,7 +224,7 @@ function QueryConstructorService(Filter, Sortation, UrlParamsHelper, INITIALLY_S
* @returns {boolean} default
*/
isGlobal: function() {
return !this.project_id;
return !this.projectId;
},
/**

@ -184,25 +184,6 @@ function WorkPackageService($http, PathHelper, UrlParamsHelper, WorkPackagesHelp
return WorkPackageService.doQuery(url, params);
},
// Note: Should this be on a project-service?
getWorkPackagesSums: function(projectIdentifier, query, columns){
var columnNames = columns.map(function(column){
return column.name;
});
if (projectIdentifier){
var url = PathHelper.apiProjectWorkPackagesSumsPath(projectIdentifier);
} else {
var url = PathHelper.apiWorkPackagesSumsPath();
}
var params = angular.extend(query.toParams(), {
'column_names[]': columnNames
});
return WorkPackageService.doQuery(url, params);
},
loadWorkPackageForm: function(workPackage) {
if (this.authorizedFor(workPackage, 'update')) {
var options = { ajax: {

@ -148,8 +148,8 @@ module.exports = function(I18n, PaginationService, PathHelper) {
buildQueryExportOptions: function(query){
var relativeUrl;
if (query.project_id) {
relativeUrl = PathHelper.projectWorkPackagesPath(query.project_id);
if (query.projectId) {
relativeUrl = PathHelper.projectWorkPackagesPath(query.projectId);
} else {
relativeUrl = PathHelper.workPackagesPath();
}

@ -113,16 +113,16 @@ declare namespace api {
interface Query {
_links:any;
id:number;
column_names;
display_sums:boolean;
columnNames;
displaySums:boolean;
filters;
group_by:string;
is_public:boolean;
groupBy:string;
isPublic:boolean;
name:string;
project_id;
sort_criteria;
projectId:number;
sortCriteria;
starred:boolean;
user_id:number;
userId:number;
}
interface Meta {

@ -320,8 +320,8 @@
"_links": {
"create": "/api/experimental/queries"
},
"column_names": null,
"display_sums": null,
"columnNames": null,
"displaySums": null,
"filters": [
{
"name": "status_id",
@ -331,472 +331,14 @@
]
}
],
"group_by": null,
"groupBy": null,
"id": null,
"is_public": false,
"isPublic": false,
"name": "_",
"project_id": 14,
"sort_criteria": [],
"projectId": 14,
"sortCriteria": [],
"starred": false,
"user_id": 0
},
"sums": [
null,
null,
null,
null
],
"total_entries": 10,
"work_package_count_by_group": null
},
"work_packages": [
{
"_actions": [
"edit",
"move",
"copy",
"duplicate",
"delete"
],
"_links": {
"copy": "/work_packages/move/new?copy=true&ids%5B%5D=16923",
"delete": "/work_packages/bulk?ids%5B%5D=16923&method=delete",
"duplicate": "/projects/openproject/work_packages/new?copy_from=16923",
"edit": "/work_packages/16923/edit",
"move": "/work_packages/move/new?ids%5B%5D=16923"
},
"assigned_to": {
"firstname": "Karol",
"id": 9248,
"name": "Karol Skolar"
},
"created_at": "2014-10-22T13:25:56Z",
"custom_values": [],
"id": 16923,
"parent_id": null,
"status": {
"id": 1,
"name": "new"
},
"subject": "INSTALAR DIMMER OMAR",
"type": {
"color_id": 8,
"created_at": "11/13/2013/ 13:11 PM",
"id": 4,
"in_aggregation": true,
"is_default": false,
"is_in_roadmap": false,
"is_milestone": false,
"is_standard": false,
"name": "Task",
"position": 2,
"updated_at": "05/13/2014/ 12:10 PM"
},
"updated_at": "2014-10-22T13:25:56Z"
},
{
"_actions": [
"edit",
"move",
"copy",
"duplicate",
"delete"
],
"_links": {
"copy": "/work_packages/move/new?copy=true&ids%5B%5D=16923",
"delete": "/work_packages/bulk?ids%5B%5D=16923&method=delete",
"duplicate": "/projects/openproject/work_packages/new?copy_from=16923",
"edit": "/work_packages/16923/edit",
"move": "/work_packages/move/new?ids%5B%5D=16923"
},
"assigned_to": {
"firstname": "Karol",
"id": 9248,
"name": "Karol Skolar"
},
"created_at": "2014-10-22T13:25:56Z",
"custom_values": [],
"id": 820,
"parent_id": null,
"status": {
"id": 1,
"name": "new"
},
"subject": "The other work package (820.json)",
"type": {
"color_id": 8,
"created_at": "11/13/2013/ 13:11 PM",
"id": 4,
"in_aggregation": true,
"is_default": false,
"is_in_roadmap": false,
"is_milestone": false,
"is_standard": false,
"name": "Task",
"position": 2,
"updated_at": "05/13/2014/ 12:10 PM"
},
"updated_at": "2014-10-22T13:25:56Z"
},
{
"_actions": [
"edit",
"move",
"copy",
"duplicate",
"delete"
],
"_links": {
"copy": "/work_packages/move/new?copy=true&ids%5B%5D=16914",
"delete": "/work_packages/bulk?ids%5B%5D=16914&method=delete",
"duplicate": "/projects/openproject/work_packages/new?copy_from=16914",
"edit": "/work_packages/16914/edit",
"move": "/work_packages/move/new?ids%5B%5D=16914"
},
"assigned_to": null,
"created_at": "2014-10-22T09:50:40Z",
"custom_values": [],
"id": 16914,
"parent_id": null,
"status": {
"id": 1,
"name": "new"
},
"subject": "ReffoTest",
"type": {
"color_id": 22,
"created_at": "02/19/2014/ 11:43 AM",
"id": 21,
"in_aggregation": true,
"is_default": false,
"is_in_roadmap": true,
"is_milestone": false,
"is_standard": false,
"name": "Idea",
"position": 7,
"updated_at": "04/22/2014/ 06:56 AM"
},
"updated_at": "2014-10-22T10:08:35Z"
},
{
"_actions": [
"edit",
"move",
"copy",
"duplicate",
"delete"
],
"_links": {
"copy": "/work_packages/move/new?copy=true&ids%5B%5D=16912",
"delete": "/work_packages/bulk?ids%5B%5D=16912&method=delete",
"duplicate": "/projects/openproject/work_packages/new?copy_from=16912",
"edit": "/work_packages/16912/edit",
"move": "/work_packages/move/new?ids%5B%5D=16912"
},
"assigned_to": null,
"created_at": "2014-10-22T09:29:12Z",
"custom_values": [],
"id": 16912,
"parent_id": null,
"status": {
"id": 1,
"name": "new"
},
"subject": "Tab order on 'New Work Package' page could be optimized",
"type": {
"color_id": 14,
"created_at": "11/13/2013/ 13:11 PM",
"id": 6,
"in_aggregation": true,
"is_default": false,
"is_in_roadmap": true,
"is_milestone": false,
"is_standard": false,
"name": "User Story",
"position": 5,
"updated_at": "05/13/2014/ 12:11 PM"
},
"updated_at": "2014-10-22T09:29:12Z"
},
{
"_actions": [
"edit",
"move",
"copy",
"duplicate",
"delete"
],
"_links": {
"copy": "/work_packages/move/new?copy=true&ids%5B%5D=16905",
"delete": "/work_packages/bulk?ids%5B%5D=16905&method=delete",
"duplicate": "/projects/openproject/work_packages/new?copy_from=16905",
"edit": "/work_packages/16905/edit",
"move": "/work_packages/move/new?ids%5B%5D=16905"
},
"assigned_to": null,
"created_at": "2014-10-22T05:09:18Z",
"custom_values": [],
"id": 16905,
"parent_id": null,
"status": {
"id": 1,
"name": "new"
},
"subject": "Rubber recycling in South Africa",
"type": {
"color_id": 22,
"created_at": "02/19/2014/ 11:43 AM",
"id": 21,
"in_aggregation": true,
"is_default": false,
"is_in_roadmap": true,
"is_milestone": false,
"is_standard": false,
"name": "Idea",
"position": 7,
"updated_at": "04/22/2014/ 06:56 AM"
},
"updated_at": "2014-10-22T05:09:19Z"
},
{
"_actions": [
"edit",
"move",
"copy",
"duplicate",
"delete"
],
"_links": {
"copy": "/work_packages/move/new?copy=true&ids%5B%5D=16904",
"delete": "/work_packages/bulk?ids%5B%5D=16904&method=delete",
"duplicate": "/projects/openproject/work_packages/new?copy_from=16904",
"edit": "/work_packages/16904/edit",
"move": "/work_packages/move/new?ids%5B%5D=16904"
},
"assigned_to": null,
"created_at": "2014-10-21T20:55:10Z",
"custom_values": [],
"id": 16904,
"parent_id": null,
"status": {
"id": 1,
"name": "new"
},
"subject": "Traject Sylvia van der Stam - Leliveld",
"type": {
"color_id": 8,
"created_at": "11/13/2013/ 13:11 PM",
"id": 4,
"in_aggregation": true,
"is_default": false,
"is_in_roadmap": false,
"is_milestone": false,
"is_standard": false,
"name": "Task",
"position": 2,
"updated_at": "05/13/2014/ 12:10 PM"
},
"updated_at": "2014-10-21T20:55:11Z"
},
{
"_actions": [
"edit",
"move",
"copy",
"duplicate",
"delete"
],
"_links": {
"copy": "/work_packages/move/new?copy=true&ids%5B%5D=16902",
"delete": "/work_packages/bulk?ids%5B%5D=16902&method=delete",
"duplicate": "/projects/openproject/work_packages/new?copy_from=16902",
"edit": "/work_packages/16902/edit",
"move": "/work_packages/move/new?ids%5B%5D=16902"
},
"assigned_to": null,
"created_at": "2014-10-21T18:06:54Z",
"custom_values": [],
"id": 16902,
"parent_id": null,
"status": {
"id": 1,
"name": "new"
},
"subject": "Parque T\u00e9cnol\u00f3gico",
"type": {
"color_id": 8,
"created_at": "11/13/2013/ 13:11 PM",
"id": 4,
"in_aggregation": true,
"is_default": false,
"is_in_roadmap": false,
"is_milestone": false,
"is_standard": false,
"name": "Task",
"position": 2,
"updated_at": "05/13/2014/ 12:10 PM"
},
"updated_at": "2014-10-21T18:14:21Z"
},
{
"_actions": [
"edit",
"move",
"copy",
"duplicate",
"delete"
],
"_links": {
"copy": "/work_packages/move/new?copy=true&ids%5B%5D=16899",
"delete": "/work_packages/bulk?ids%5B%5D=16899&method=delete",
"duplicate": "/projects/openproject/work_packages/new?copy_from=16899",
"edit": "/work_packages/16899/edit",
"move": "/work_packages/move/new?ids%5B%5D=16899"
},
"assigned_to": null,
"created_at": "2014-10-21T15:30:28Z",
"custom_values": [],
"id": 16899,
"parent_id": null,
"status": {
"id": 1,
"name": "new"
},
"subject": "PDF export fails if there is U+FFFD in issue data or journals",
"type": {
"color_id": 17,
"created_at": "11/13/2013/ 13:11 PM",
"id": 1,
"in_aggregation": true,
"is_default": false,
"is_in_roadmap": true,
"is_milestone": false,
"is_standard": false,
"name": "Bug",
"position": 4,
"updated_at": "05/13/2014/ 12:10 PM"
},
"updated_at": "2014-10-21T15:31:25Z"
},
{
"_actions": [
"edit",
"move",
"copy",
"duplicate",
"delete"
],
"_links": {
"copy": "/work_packages/move/new?copy=true&ids%5B%5D=16893",
"delete": "/work_packages/bulk?ids%5B%5D=16893&method=delete",
"duplicate": "/projects/openproject/work_packages/new?copy_from=16893",
"edit": "/work_packages/16893/edit",
"move": "/work_packages/move/new?ids%5B%5D=16893"
},
"assigned_to": null,
"created_at": "2014-10-21T13:49:42Z",
"custom_values": [],
"id": 16893,
"parent_id": null,
"status": {
"id": 1,
"name": "new"
},
"subject": "A thaliana",
"type": {
"color_id": 8,
"created_at": "11/13/2013/ 13:11 PM",
"id": 4,
"in_aggregation": true,
"is_default": false,
"is_in_roadmap": false,
"is_milestone": false,
"is_standard": false,
"name": "Task",
"position": 2,
"updated_at": "05/13/2014/ 12:10 PM"
},
"updated_at": "2014-10-21T13:49:42Z"
},
{
"_actions": [
"edit",
"move",
"copy",
"duplicate",
"delete"
],
"_links": {
"copy": "/work_packages/move/new?copy=true&ids%5B%5D=16879",
"delete": "/work_packages/bulk?ids%5B%5D=16879&method=delete",
"duplicate": "/projects/openproject/work_packages/new?copy_from=16879",
"edit": "/work_packages/16879/edit",
"move": "/work_packages/move/new?ids%5B%5D=16879"
},
"assigned_to": null,
"created_at": "2014-10-20T15:03:40Z",
"custom_values": [],
"id": 16879,
"parent_id": null,
"status": {
"id": 1,
"name": "new"
},
"subject": "500 on Workpackage update",
"type": {
"color_id": 17,
"created_at": "11/13/2013/ 13:11 PM",
"id": 1,
"in_aggregation": true,
"is_default": false,
"is_in_roadmap": true,
"is_milestone": false,
"is_standard": false,
"name": "Bug",
"position": 4,
"updated_at": "05/13/2014/ 12:10 PM"
},
"updated_at": "2014-10-20T15:29:06Z"
},
{
"_actions": [
"edit",
"move",
"copy",
"duplicate",
"delete"
],
"_links": {
"copy": "/work_packages/move/new?copy=true&ids%5B%5D=16877",
"delete": "/work_packages/bulk?ids%5B%5D=16877&method=delete",
"duplicate": "/projects/openproject/work_packages/new?copy_from=16877",
"edit": "/work_packages/16877/edit",
"move": "/work_packages/move/new?ids%5B%5D=16877"
},
"assigned_to": null,
"created_at": "2014-10-20T14:33:15Z",
"custom_values": [],
"id": 16877,
"parent_id": null,
"status": {
"id": 7,
"name": "confirmed"
},
"subject": "[Emails] In work package create / update, closed work packages are not striked through",
"type": {
"color_id": 17,
"created_at": "11/13/2013/ 13:11 PM",
"id": 1,
"in_aggregation": true,
"is_default": false,
"is_in_roadmap": true,
"is_milestone": false,
"is_standard": false,
"name": "Bug",
"position": 4,
"updated_at": "05/13/2014/ 12:10 PM"
},
"updated_at": "2014-10-20T14:33:16Z"
"userId": 0
}
]
}
}

Loading…
Cancel
Save