diff --git a/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-edit-element/case-edit-element.component.html b/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-edit-element/case-edit-element.component.html index 530730cf6a..6f8c4382fe 100644 --- a/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-edit-element/case-edit-element.component.html +++ b/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-edit-element/case-edit-element.component.html @@ -19,6 +19,7 @@

{{ element.label }} @@ -34,6 +35,7 @@

{{ 'Extra picture' | translate }}

@@ -44,7 +46,9 @@

{{ 'Extra recording' | translate }}

diff --git a/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-edit-element/case-edit-element.component.ts b/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-edit-element/case-edit-element.component.ts index bc7795207d..4a29bf4839 100644 --- a/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-edit-element/case-edit-element.component.ts +++ b/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-edit-element/case-edit-element.component.ts @@ -22,6 +22,13 @@ export class CaseEditElementComponent implements OnInit { * keeps the heading it has today. */ @Input() showSectionTitle = true; + /** + * Id of the case being edited. Routed case pages may omit it — the picture + * element still falls back to the route params. Dialog hosts must supply it, + * because the ActivatedRoute they inject is the route the dialog was opened + * from and carries no case id at all. + */ + @Input() caseId?: number; @Output() needUpdate: EventEmitter = new EventEmitter(); requestModel: CaseEditRequest = new CaseEditRequest(); requestModels: Array = []; diff --git a/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-edit-switch/case-edit-switch.component.html b/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-edit-switch/case-edit-switch.component.html index 75df719de6..ac96de863b 100644 --- a/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-edit-switch/case-edit-switch.component.html +++ b/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-edit-switch/case-edit-switch.component.html @@ -18,7 +18,7 @@

{{dataItem.la - + @@ -59,7 +59,9 @@

{{dataItem.la + [dataItemLabel]="dataItem.label" + [caseId]="caseId" + (needUpdate)="emitNeedUpdate()"> diff --git a/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-edit-switch/case-edit-switch.component.spec.ts b/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-edit-switch/case-edit-switch.component.spec.ts index de455d4a81..e1d866d431 100644 --- a/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-edit-switch/case-edit-switch.component.spec.ts +++ b/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-edit-switch/case-edit-switch.component.spec.ts @@ -17,6 +17,7 @@ import {DataItemDto} from 'src/app/common/models'; class StubPictureComponent { @Input() fieldValues: any; @Input() fieldId: any; + @Input() caseId: any; } function makeDataItem(overrides: Partial = {}): DataItemDto { diff --git a/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-edit-switch/case-edit-switch.component.ts b/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-edit-switch/case-edit-switch.component.ts index 6e19d5a90a..c887cae300 100644 --- a/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-edit-switch/case-edit-switch.component.ts +++ b/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-edit-switch/case-edit-switch.component.ts @@ -8,6 +8,12 @@ import {DataItemDto} from 'src/app/common/models'; }) export class CaseEditSwitchComponent implements OnInit { @Input() dataItemList: Array = []; + /** + * Id of the case being edited, threaded down to the picture element. Optional + * — it is only needed where the ActivatedRoute cannot supply it, i.e. when + * the case editor is rendered inside a dialog rather than on a case route. + */ + @Input() caseId?: number; @Output() needUpdate: EventEmitter = new EventEmitter(); constructor() { } diff --git a/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-elements/element-container/element-container.component.html b/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-elements/element-container/element-container.component.html index 53465c468a..0defda93cf 100644 --- a/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-elements/element-container/element-container.component.html +++ b/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-elements/element-container/element-container.component.html @@ -5,6 +5,6 @@
{{dataItemLabel}}
{{isCollapsed ? 'chevron_right' : 'expand_more'}} - + diff --git a/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-elements/element-container/element-container.component.ts b/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-elements/element-container/element-container.component.ts index 38ff6b5c71..6f409a36ba 100644 --- a/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-elements/element-container/element-container.component.ts +++ b/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-elements/element-container/element-container.component.ts @@ -1,4 +1,4 @@ -import { Component, Input} from '@angular/core'; +import { Component, EventEmitter, Input, Output} from '@angular/core'; import { DataItemDto } from 'src/app/common/models'; @Component({ @@ -12,6 +12,12 @@ export class ElementContainerComponent { dataItemList: Array = []; isCollapsed = true; @Input() dataItemLabel: string; + /** + * Id of the case being edited, threaded on down to the nested switch so a + * Picture field grouped inside this container still resolves a case id when + * the editor is rendered inside a dialog rather than on a case route. + */ + @Input() caseId?: number; @Input() get fieldValue() { return this.dataItemList; @@ -19,6 +25,11 @@ export class ElementContainerComponent { set fieldValue(val) { this.dataItemList = val; } + @Output() needUpdate: EventEmitter = new EventEmitter(); constructor() {} + + emitNeedUpdate() { + this.needUpdate.emit(); + } } diff --git a/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-elements/element-picture/element-picture.component.ts b/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-elements/element-picture/element-picture.component.ts index a4e5176736..eac5818954 100644 --- a/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-elements/element-picture/element-picture.component.ts +++ b/eform-client/src/app/common/modules/eform-cases/components/case-edit/case-elements/element-picture/element-picture.component.ts @@ -29,12 +29,20 @@ export class ElementPictureComponent implements OnChanges, OnDestroy { @Input() fieldValues: Array = []; @Input() fieldId: number; + /** + * Case id supplied by the host component. It takes precedence over the route + * params below: inside a MatDialog the injected ActivatedRoute is the route + * the dialog was opened from, which carries neither ':id' nor ':sdkCaseId', + * so the fallback would resolve to NaN and the upload would fail with + * CaseNotFound. Routed case pages may keep omitting it. + */ + @Input() caseId?: number; @Output() pictureUpdated: EventEmitter = new EventEmitter(); buttonsLocked = false; geoObjects = []; images = []; galleryImages: GalleryItem[] = []; - caseId: number; + private routeCaseId: number; imageSub$: Subscription; rotateImageSub$: Subscription; @@ -48,12 +56,14 @@ export class ElementPictureComponent implements OnChanges, OnDestroy { ngOnChanges(changes: SimpleChanges): void { if (changes && changes.fieldValues) { this.images = []; - this.activatedRouteSub$ = this.activateRoute.params.subscribe((params) => { - this.caseId = +params['id']; - if (isNaN(this.caseId)) { - this.caseId = +params['sdkCaseId']; - } - }); + if (!this.hasCaseIdInput) { + this.activatedRouteSub$ = this.activateRoute.params.subscribe((params) => { + this.routeCaseId = +params['id']; + if (isNaN(this.routeCaseId)) { + this.routeCaseId = +params['sdkCaseId']; + } + }); + } this.fieldValues.forEach(value => { if (value.uploadedDataObj) { this.geoObjects.push({ @@ -83,6 +93,21 @@ export class ElementPictureComponent implements OnChanges, OnDestroy { } } + /** + * True when the host explicitly bound a usable case id. + */ + private get hasCaseIdInput(): boolean { + return Number.isFinite(this.caseId) && this.caseId > 0; + } + + /** + * The bound input always wins; the route params are only a fallback for the + * routed case pages that do not pass the id down. + */ + private get resolvedCaseId(): number { + return this.hasCaseIdInput ? this.caseId : this.routeCaseId; + } + updateGallery() { this.galleryImages = []; this.images = this.images.sort((a, b) => a.fileName.localeCompare(b.fileName)); @@ -146,7 +171,7 @@ export class ElementPictureComponent implements OnChanges, OnDestroy { addPicture(newImage: File, modalId: string) { const fieldId = this.fieldId; this.addImageSub$ = this.imageService - .addNewImage(fieldId, this.caseId, newImage) + .addNewImage(fieldId, this.resolvedCaseId, newImage) .subscribe(data => { if (data && data.success) { this.dialog.getDialogById(modalId).close();