|
|
|
@ -36,6 +36,9 @@ import {UploadFile} from '../../op-file-upload/op-file-upload.service'; |
|
|
|
|
import IQService = angular.IQService; |
|
|
|
|
import IPromise = angular.IPromise; |
|
|
|
|
import ITimeoutService = angular.ITimeoutService; |
|
|
|
|
import {States} from '../../../states.service'; |
|
|
|
|
import {State} from './../../../../helpers/reactive-fassade'; |
|
|
|
|
import {SchemaResource} from './schema-resource.service'; |
|
|
|
|
|
|
|
|
|
interface WorkPackageResourceEmbedded { |
|
|
|
|
activities: CollectionResourceInterface; |
|
|
|
@ -50,7 +53,7 @@ interface WorkPackageResourceEmbedded { |
|
|
|
|
project: HalResource|any; |
|
|
|
|
relations: CollectionResourceInterface; |
|
|
|
|
responsible: HalResource|any; |
|
|
|
|
schema: HalResource|any; |
|
|
|
|
schema: SchemaResource; |
|
|
|
|
status: HalResource|any; |
|
|
|
|
timeEntries: HalResource[]|any[]; |
|
|
|
|
type: HalResource|any; |
|
|
|
@ -80,6 +83,7 @@ var $q: IQService; |
|
|
|
|
var $stateParams: any; |
|
|
|
|
var $timeout: ITimeoutService; |
|
|
|
|
var I18n: op.I18n; |
|
|
|
|
var states: States; |
|
|
|
|
var apiWorkPackages: ApiWorkPackagesService; |
|
|
|
|
var wpCacheService: WorkPackageCacheService; |
|
|
|
|
var NotificationsService: any; |
|
|
|
@ -113,7 +117,7 @@ export class WorkPackageResource extends HalResource { |
|
|
|
|
public $embedded: WorkPackageResourceEmbedded; |
|
|
|
|
public $links: WorkPackageResourceLinks; |
|
|
|
|
public id: number|string; |
|
|
|
|
public schema; |
|
|
|
|
public schema: SchemaResource; |
|
|
|
|
public $pristine: { [attribute: string]: any } = {}; |
|
|
|
|
public parentId: number; |
|
|
|
|
public subject: string; |
|
|
|
@ -146,6 +150,9 @@ export class WorkPackageResource extends HalResource { |
|
|
|
|
return this.modifiedFields.length > 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Returns all modified fields by comparing open $pristine fields. |
|
|
|
|
*/ |
|
|
|
|
public get modifiedFields(): string[] { |
|
|
|
|
var modified = []; |
|
|
|
|
|
|
|
|
@ -190,12 +197,8 @@ export class WorkPackageResource extends HalResource { |
|
|
|
|
* be done automatically, but the backend does not provide typed collections yet. |
|
|
|
|
*/ |
|
|
|
|
protected $initialize(source) { |
|
|
|
|
const oldSchema = this.schema; |
|
|
|
|
super.$initialize(source); |
|
|
|
|
|
|
|
|
|
// Take over previously loaded schema resource
|
|
|
|
|
this.setExistingSchema(oldSchema); |
|
|
|
|
|
|
|
|
|
var attachments = this.attachments || {$source: void 0, $loaded: void 0}; |
|
|
|
|
this.attachments = new AttachmentCollectionResource( |
|
|
|
|
attachments.$source, |
|
|
|
@ -259,18 +262,6 @@ export class WorkPackageResource extends HalResource { |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public requiredValueFor(fieldName): boolean { |
|
|
|
|
var fieldSchema = this.schema[fieldName]; |
|
|
|
|
|
|
|
|
|
// The field schema may be undefined if a custom field
|
|
|
|
|
// is used as a column, but not available for this type.
|
|
|
|
|
if (angular.isUndefined(fieldSchema)) { |
|
|
|
|
return false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return !this[fieldName] && fieldSchema.writable && fieldSchema.required; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public allowedValuesFor(field): ng.IPromise<HalResource[]> { |
|
|
|
|
var deferred = $q.defer(); |
|
|
|
|
|
|
|
|
@ -337,11 +328,11 @@ export class WorkPackageResource extends HalResource { |
|
|
|
|
return deferred.promise; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public getSchema() { |
|
|
|
|
public loadFormSchema() { |
|
|
|
|
return this.getForm().then(form => { |
|
|
|
|
const schema = form.$embedded.schema; |
|
|
|
|
this.schema = form.$embedded.schema; |
|
|
|
|
|
|
|
|
|
angular.forEach(schema, (field, name) => { |
|
|
|
|
angular.forEach(this.schema, (field, name) => { |
|
|
|
|
// Assign only links from schema when an href is set
|
|
|
|
|
// and field is writable.
|
|
|
|
|
// (exclude plain properties and null values)
|
|
|
|
@ -352,11 +343,11 @@ export class WorkPackageResource extends HalResource { |
|
|
|
|
const hasAllowedValues = Array.isArray(field.allowedValues) && field.allowedValues.length > 0; |
|
|
|
|
|
|
|
|
|
if (isHalField && hasAllowedValues) { |
|
|
|
|
this[name] = _.find(field.allowedValues, {href: this[name].href}); |
|
|
|
|
this[name] = _.find(field.allowedValues, {href: this[name].href}) || this[name]; |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
return schema; |
|
|
|
|
return this.schema; |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -369,27 +360,31 @@ export class WorkPackageResource extends HalResource { |
|
|
|
|
const payload = this.mergeWithForm(form); |
|
|
|
|
const sentValues = Object.keys(this.$pristine); |
|
|
|
|
|
|
|
|
|
this.saveResource(payload) |
|
|
|
|
.then(workPackage => { |
|
|
|
|
// Initialize any potentially new HAL values
|
|
|
|
|
this.$initialize(workPackage); |
|
|
|
|
this.updateActivities(); |
|
|
|
|
this.$links.updateImmediately(payload) |
|
|
|
|
.then((workPackage:WorkPackageResource) => { |
|
|
|
|
// Remove the current form, otherwise old form data
|
|
|
|
|
// might still be used for the next edit field to be edited
|
|
|
|
|
this.form = null; |
|
|
|
|
|
|
|
|
|
if (wasNew) { |
|
|
|
|
this.uploadPendingAttachments(); |
|
|
|
|
wpCacheService.newWorkPackageCreated(this); |
|
|
|
|
} |
|
|
|
|
// Ensure the schema is loaded before updating
|
|
|
|
|
workPackage.schema.$load().then((schema) => { |
|
|
|
|
// Initialize any potentially new HAL values
|
|
|
|
|
this.$initialize(workPackage); |
|
|
|
|
this.schema = schema; |
|
|
|
|
this.updateActivities(); |
|
|
|
|
|
|
|
|
|
// Remove only those pristine values that were submitted
|
|
|
|
|
angular.forEach(sentValues, (key) => { |
|
|
|
|
delete this.$pristine[key]; |
|
|
|
|
}); |
|
|
|
|
if (wasNew) { |
|
|
|
|
this.uploadPendingAttachments(); |
|
|
|
|
wpCacheService.newWorkPackageCreated(this); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Remove the current form, otherwise old form data
|
|
|
|
|
// might still be used for the next edit field in #getSchema()
|
|
|
|
|
this.form = null; |
|
|
|
|
// Remove only those pristine values that were submitted
|
|
|
|
|
angular.forEach(sentValues, (key) => { |
|
|
|
|
delete this.$pristine[key]; |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
deferred.resolve(this); |
|
|
|
|
deferred.resolve(this); |
|
|
|
|
}); |
|
|
|
|
}) |
|
|
|
|
.catch(error => { |
|
|
|
|
deferred.reject(error); |
|
|
|
@ -425,13 +420,6 @@ export class WorkPackageResource extends HalResource { |
|
|
|
|
return otherWorkPackage.parent.$links.self.$link.href === this.$links.self.$link.href; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
protected saveResource(payload): ng.IPromise<any> { |
|
|
|
|
if (this.isNew) { |
|
|
|
|
return apiWorkPackages.createWorkPackage(payload); |
|
|
|
|
} |
|
|
|
|
return this.$links.updateImmediately(payload); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private mergeWithForm(form) { |
|
|
|
|
var plainPayload = form.payload.$plain(); |
|
|
|
|
var schema = form.$embedded.schema; |
|
|
|
@ -464,25 +452,6 @@ export class WorkPackageResource extends HalResource { |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private setExistingSchema(previous) { |
|
|
|
|
// Only when existing schema was loaded
|
|
|
|
|
if (!(previous && previous.$loaded)) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// If old schema was a regular schema and both href match
|
|
|
|
|
// assume they are matching
|
|
|
|
|
if (previous.href === this.schema.href) { |
|
|
|
|
this.schema = previous; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// If old schema was embedded into the WP form, decide
|
|
|
|
|
// based on its baseSchema href.
|
|
|
|
|
if (previous.baseSchema && previous.baseSchema.href === this.schema.href) { |
|
|
|
|
this.schema = previous; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Invalidate a set of linked resources of this work package. |
|
|
|
|
* And inform the cache service about the work package update. |
|
|
|
@ -543,6 +512,10 @@ export class WorkPackageResource extends HalResource { |
|
|
|
|
|
|
|
|
|
// Set update link to form
|
|
|
|
|
this['update'] = this.$links.update = form.$links.self; |
|
|
|
|
// Use POST /work_packages for saving link
|
|
|
|
|
this['updateImmediately'] = this.$links.updateImmediately = (payload) => { |
|
|
|
|
return apiWorkPackages.createWorkPackage(payload); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
this.parentId = this.parentId || $stateParams.parent_id; |
|
|
|
|
} |
|
|
|
@ -557,6 +530,7 @@ function wpResource(...args) { |
|
|
|
|
$stateParams, |
|
|
|
|
$timeout, |
|
|
|
|
I18n, |
|
|
|
|
states, |
|
|
|
|
apiWorkPackages, |
|
|
|
|
wpCacheService, |
|
|
|
|
NotificationsService, |
|
|
|
@ -570,6 +544,7 @@ wpResource.$inject = [ |
|
|
|
|
'$stateParams', |
|
|
|
|
'$timeout', |
|
|
|
|
'I18n', |
|
|
|
|
'states', |
|
|
|
|
'apiWorkPackages', |
|
|
|
|
'wpCacheService', |
|
|
|
|
'NotificationsService', |
|
|
|
|