parent
d1acccd464
commit
9d2ebdf22a
@ -0,0 +1,25 @@ |
||||
import {ResourceChangeset} from "core-app/modules/fields/changeset/resource-changeset"; |
||||
import { TimeEntryResource } from 'core-app/modules/hal/resources/time-entry-resource'; |
||||
|
||||
export class TimeEntryChangeset extends ResourceChangeset<TimeEntryResource> { |
||||
|
||||
public setValue(key:string, val:any) { |
||||
super.setValue(key, val); |
||||
|
||||
// Update the form for fields that may alter the form itself
|
||||
// when the time entry is new. Otherwise, the save request afterwards
|
||||
// will update the form automatically.
|
||||
if (this.pristineResource.isNew && (key === 'workPackage')) { |
||||
this.updateForm().then(() => this.push()); |
||||
} |
||||
} |
||||
|
||||
protected buildPayloadFromChanges() { |
||||
let payload = super.buildPayloadFromChanges(); |
||||
|
||||
// we ignore the project and instead rely completely on the work package.
|
||||
delete payload['_links']['project']; |
||||
|
||||
return payload; |
||||
} |
||||
} |
@ -0,0 +1,83 @@ |
||||
<div class="op-modal--portal ngdialog-theme-openproject"> |
||||
<div class="op-modal--modal-container confirm-dialog--modal loading-indicator--location" |
||||
data-indicator-name="modal" |
||||
tabindex="0"> |
||||
<div class="op-modal--modal-header"> |
||||
<a class="op-modal--modal-close-button"> |
||||
<i |
||||
class="icon-close" |
||||
(click)="closeMe($event)" |
||||
[attr.title]="text.close"> |
||||
</i> |
||||
</a> |
||||
<h3 class="icon-context icon-attention" [textContent]="text.title"></h3> |
||||
</div> |
||||
|
||||
<div class="ngdialog-body op-modal--modal-body"> |
||||
<edit-form |
||||
#editForm |
||||
[resource]="entry" |
||||
[inEditMode]="true" |
||||
(onSaved)="setModifiedEntry($event)"> |
||||
<div class="attributes-map"> |
||||
|
||||
<div class="attributes-map--key" [textContent]="text.attributes.spentOn"></div> |
||||
<div class="attributes-map--value"> |
||||
<editable-attribute-field [resource]="entry" |
||||
[fieldName]="'spentOn'"> |
||||
</editable-attribute-field> |
||||
</div> |
||||
|
||||
<div class="attributes-map--key" [textContent]="text.attributes.hours"></div> |
||||
<div class="attributes-map--value"> |
||||
<editable-attribute-field [resource]="entry" |
||||
[fieldName]="'hours'"> |
||||
</editable-attribute-field> |
||||
</div> |
||||
|
||||
<div class="attributes-map--key" [textContent]="text.attributes.workPackage"></div> |
||||
<div class="attributes-map--value"> |
||||
<editable-attribute-field [resource]="entry" |
||||
[fieldName]="'workPackage'"> |
||||
</editable-attribute-field> |
||||
</div> |
||||
|
||||
<div class="attributes-map--key" [textContent]="text.attributes.activity"></div> |
||||
<div class="attributes-map--value"> |
||||
<editable-attribute-field *ngIf="workPackageSelected" |
||||
[resource]="entry" |
||||
[fieldName]="'activity'"> |
||||
</editable-attribute-field> |
||||
<i *ngIf="!workPackageSelected" |
||||
[textContent]="text.wpRequired"> |
||||
</i> |
||||
</div> |
||||
|
||||
<div class="attributes-map--key" [textContent]="text.attributes.comment"></div> |
||||
<div class="attributes-map--value"> |
||||
<editable-attribute-field [resource]="entry" |
||||
[fieldName]="'comment'"> |
||||
</editable-attribute-field> |
||||
</div> |
||||
|
||||
<ng-container *ngFor="let cf of customFields"> |
||||
<div class="attributes-map--key" [textContent]="cf.label"></div> |
||||
<div class="attributes-map--value"> |
||||
<editable-attribute-field [resource]="entry" |
||||
[fieldName]="cf.key"> |
||||
</editable-attribute-field> |
||||
</div> |
||||
</ng-container> |
||||
</div> |
||||
</edit-form> |
||||
</div> |
||||
|
||||
<div class="op-modal--modal-footer"> |
||||
<button class="button -highlight" |
||||
(click)="createEntry()" |
||||
[textContent]="text.create" |
||||
[attr.title]="text.create"> |
||||
</button> |
||||
</div> |
||||
</div> |
||||
</div> |
@ -0,0 +1,92 @@ |
||||
import {Component, ElementRef, Inject, ChangeDetectorRef, ViewChild} from "@angular/core"; |
||||
import {OpModalComponent} from "app/components/op-modals/op-modal.component"; |
||||
import {OpModalLocalsToken} from "app/components/op-modals/op-modal.service"; |
||||
import {OpModalLocalsMap} from "app/components/op-modals/op-modal.types"; |
||||
import {I18nService} from "core-app/modules/common/i18n/i18n.service"; |
||||
import {HalResourceEditingService} from "core-app/modules/fields/edit/services/hal-resource-editing.service"; |
||||
import {TimeEntryResource} from "core-app/modules/hal/resources/time-entry-resource"; |
||||
import {HalResource} from "core-app/modules/hal/resources/hal-resource"; |
||||
import {SchemaResource} from "core-app/modules/hal/resources/schema-resource"; |
||||
import {EditFormComponent} from "core-app/modules/fields/edit/edit-form/edit-form.component"; |
||||
import { untilComponentDestroyed } from 'ng2-rx-componentdestroyed'; |
||||
|
||||
@Component({ |
||||
templateUrl: './create.modal.html', |
||||
styleUrls: ['../edit/edit.modal.sass'], |
||||
providers: [ |
||||
HalResourceEditingService |
||||
] |
||||
}) |
||||
export class TimeEntryCreateModal extends OpModalComponent { |
||||
|
||||
@ViewChild('editForm', { static: true }) editForm:EditFormComponent; |
||||
|
||||
text = { |
||||
title: this.i18n.t('js.time_entry.edit'), |
||||
attributes: { |
||||
comment: this.i18n.t('js.time_entry.comment'), |
||||
hours: this.i18n.t('js.time_entry.hours'), |
||||
activity: this.i18n.t('js.time_entry.activity'), |
||||
workPackage: this.i18n.t('js.time_entry.work_package'), |
||||
spentOn: this.i18n.t('js.time_entry.spent_on'), |
||||
}, |
||||
wpRequired: this.i18n.t('js.time_entry.work_package_required'), |
||||
create: this.i18n.t('js.label_create'), |
||||
close: this.i18n.t('js.button_close') |
||||
}; |
||||
|
||||
public closeOnEscape = false; |
||||
public closeOnOutsideClick = false; |
||||
public customFields:{key:string, label:string}[] = []; |
||||
public workPackageSelected:boolean = false; |
||||
|
||||
public createdEntry:TimeEntryResource; |
||||
|
||||
constructor(readonly elementRef:ElementRef, |
||||
@Inject(OpModalLocalsToken) readonly locals:OpModalLocalsMap, |
||||
readonly cdRef:ChangeDetectorRef, |
||||
readonly i18n:I18nService, |
||||
readonly halEditing:HalResourceEditingService) { |
||||
super(locals, cdRef, elementRef); |
||||
|
||||
halEditing |
||||
.temporaryEditResource(this.entry) |
||||
.values$() |
||||
.pipe( |
||||
untilComponentDestroyed(this) |
||||
) |
||||
.subscribe(changeset => { |
||||
if (changeset && changeset.workPackage) { |
||||
this.workPackageSelected = true; |
||||
} |
||||
}); |
||||
} |
||||
|
||||
public get entry() { |
||||
return this.locals.entry; |
||||
} |
||||
|
||||
public createEntry() { |
||||
this.editForm.save() |
||||
.then(() => { |
||||
this.service.close(); |
||||
}); |
||||
} |
||||
|
||||
public setModifiedEntry($event:{savedResource:HalResource, isInital:boolean}) { |
||||
this.createdEntry = $event.savedResource as TimeEntryResource; |
||||
} |
||||
|
||||
ngOnInit() { |
||||
super.ngOnInit(); |
||||
this.setCustomFields(this.entry.schema); |
||||
} |
||||
|
||||
private setCustomFields(schema:SchemaResource) { |
||||
Object.entries(schema).forEach(([key, keySchema]) => { |
||||
if (key.match(/customField\d+/)) { |
||||
this.customFields.push({key: key, label: keySchema.name }); |
||||
} |
||||
}); |
||||
} |
||||
} |
Loading…
Reference in new issue