diff --git a/projects/netgrif-components-core/src/lib/actions/front-action.module.ts b/projects/netgrif-components-core/src/lib/actions/front-action.module.ts
index 926acea17..c45918912 100644
--- a/projects/netgrif-components-core/src/lib/actions/front-action.module.ts
+++ b/projects/netgrif-components-core/src/lib/actions/front-action.module.ts
@@ -1,7 +1,7 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import {FrontActionRegistryService} from "../registry/front-action-registry.service";
-import {redirectAction} from "./model/router-action-definitions";
+import {redirectAction, snackBarAction} from "./model/router-action-definitions";
import {reloadTaskAction, validateTaskAction} from "./model/task-action-definitions";
@NgModule({
@@ -16,5 +16,6 @@ export class FrontActionModule {
frontActionsRegistry.register('redirect', redirectAction);
frontActionsRegistry.register('validate', validateTaskAction);
frontActionsRegistry.register('reloadTask', reloadTaskAction);
+ frontActionsRegistry.register('snackBar', snackBarAction);
}
}
diff --git a/projects/netgrif-components-core/src/lib/actions/services/front-action.service.ts b/projects/netgrif-components-core/src/lib/actions/services/front-action.service.ts
index e245d1dd8..8a4c0bbc7 100644
--- a/projects/netgrif-components-core/src/lib/actions/services/front-action.service.ts
+++ b/projects/netgrif-components-core/src/lib/actions/services/front-action.service.ts
@@ -16,6 +16,7 @@ export class FrontActionService {
const fn = this._frontActionRegistry.get(frontAction.id)
if (!fn) {
this._log.error("Frontend action is not defined for ID [" + frontAction.id +"]")
+ return;
}
fn.call(this._injector, frontAction)
}
diff --git a/projects/netgrif-components-core/src/lib/data-fields/file-field/file-default-field/abstract-file-default-field.component.spec.ts b/projects/netgrif-components-core/src/lib/data-fields/file-field/file-default-field/abstract-file-default-field.component.spec.ts
index e66f177b5..741562069 100644
--- a/projects/netgrif-components-core/src/lib/data-fields/file-field/file-default-field/abstract-file-default-field.component.spec.ts
+++ b/projects/netgrif-components-core/src/lib/data-fields/file-field/file-default-field/abstract-file-default-field.component.spec.ts
@@ -16,9 +16,6 @@ import {MockUserResourceService} from "../../../utility/tests/mocks/mock-user-re
import {ConfigurationService} from "../../../configuration/configuration.service";
import {TestConfigurationService} from "../../../utility/tests/test-config";
import {Component, CUSTOM_ELEMENTS_SCHEMA, Inject, Optional} from "@angular/core";
-import {BrowserDynamicTestingModule} from "@angular/platform-browser-dynamic/testing";
-import {ErrorSnackBarComponent} from "../../../snack-bar/components/error-snack-bar/error-snack-bar.component";
-import {SuccessSnackBarComponent} from "../../../snack-bar/components/success-snack-bar/success-snack-bar.component";
import {TaskResourceService} from "../../../resources/engine-endpoint/task-resource.service";
import {LoggerService} from "../../../logger/services/logger.service";
import {SnackBarService} from "../../../snack-bar/services/snack-bar.service";
@@ -29,6 +26,8 @@ import {AbstractFileDefaultFieldComponent} from "./abstract-file-default-field.c
import {DATA_FIELD_PORTAL_DATA, DataFieldPortalData} from "../../models/data-field-portal-data-injection-token";
import {FormControl} from "@angular/forms";
import {WrappedBoolean} from "../../data-field-template/models/wrapped-boolean";
+import {FrontActionService} from "../../../actions/services/front-action.service";
+import {MockTaskResourceService} from "../../../utility/tests/mocks/mock-task-resource.service";
describe('AbstractFileDefaultFieldComponent', () => {
let component: TestFileComponent;
@@ -48,10 +47,12 @@ describe('AbstractFileDefaultFieldComponent', () => {
providers: [
SideMenuService,
EventService,
+ FrontActionService,
{provide: AuthenticationMethodService, useClass: MockAuthenticationMethodService},
{provide: AuthenticationService, useClass: MockAuthenticationService},
{provide: UserResourceService, useClass: MockUserResourceService},
{provide: ConfigurationService, useClass: TestConfigurationService},
+ {provide: TaskResourceService, useClass: MockTaskResourceService},
{provide: DATA_FIELD_PORTAL_DATA, useValue: {
dataField: new FileField('', '', {
required: true,
@@ -81,6 +82,49 @@ describe('AbstractFileDefaultFieldComponent', () => {
expect(component).toBeTruthy();
});
+
+ it('should simulate file download', () => {
+ // Spy on the 'download' method
+ spyOn(component, 'download').and.callFake(() => {
+ // Simulate the download process
+ const anchor = document.createElement('a');
+ anchor.href = 'data:text/plain;charset=utf-8,' + encodeURIComponent('mockContent');
+ anchor.download = 'mockFile.txt';
+ document.body.appendChild(anchor);
+ anchor.click();
+ document.body.removeChild(anchor);
+ });
+
+ // Call the 'download' method
+ component.download();
+
+ // Assert that the 'download' method was called
+ expect(component.download).toHaveBeenCalled();
+ });
+
+ it('should simulate file upload', () => {
+ // Create a mock file
+ const mockFile = new File(['mockContent'], 'mockFile.txt', {type: 'text/plain'});
+
+ // Get the file input element's reference
+ const fileInput = component.fileUploadEl.nativeElement;
+
+ // Create a DataTransfer object to simulate file selection
+ const dataTransfer = new DataTransfer();
+ dataTransfer.items.add(mockFile);
+ fileInput.files = dataTransfer.files;
+ component.dataField.value = {file: mockFile, name: "mockFile.txt"}
+ // Trigger the file upload method
+ spyOn(component, 'upload').and.callThrough();
+ const uploadButtonEvent = new Event('change');
+ fileInput.dispatchEvent(uploadButtonEvent);
+ component.upload();
+
+ // Assertions
+ expect(component.upload).toHaveBeenCalled();
+ expect(component.dataField.value).toBeTruthy(); // Ensure value is processed
+ });
+
afterEach(() => {
TestBed.resetTestingModule();
});
@@ -88,7 +132,7 @@ describe('AbstractFileDefaultFieldComponent', () => {
@Component({
selector: 'ncc-test-file',
- template: ''
+ template: ''
})
class TestFileComponent extends AbstractFileDefaultFieldComponent {
constructor(taskResourceService: TaskResourceService,
@@ -97,8 +141,9 @@ class TestFileComponent extends AbstractFileDefaultFieldComponent {
translate: TranslateService,
sanitizer: DomSanitizer,
eventService: EventService,
+ frontActionService: FrontActionService,
@Optional() @Inject(DATA_FIELD_PORTAL_DATA) dataFieldPortalData: DataFieldPortalData) {
- super(taskResourceService, log, snackbar, translate, eventService, sanitizer, dataFieldPortalData);
+ super(taskResourceService, log, snackbar, translate, eventService, sanitizer, frontActionService, dataFieldPortalData);
}
}
diff --git a/projects/netgrif-components-core/src/lib/data-fields/file-field/file-default-field/abstract-file-default-field.component.ts b/projects/netgrif-components-core/src/lib/data-fields/file-field/file-default-field/abstract-file-default-field.component.ts
index 690a84ab7..20a551442 100644
--- a/projects/netgrif-components-core/src/lib/data-fields/file-field/file-default-field/abstract-file-default-field.component.ts
+++ b/projects/netgrif-components-core/src/lib/data-fields/file-field/file-default-field/abstract-file-default-field.component.ts
@@ -26,6 +26,8 @@ import {DATA_FIELD_PORTAL_DATA, DataFieldPortalData} from "../../models/data-fie
import {FILE_FIELD_HEIGHT, FILE_FIELD_PADDING, PREVIEW, PREVIEW_BUTTON} from '../models/file-field-constants';
import {FileFieldRequest} from "../../../resources/interface/file-field-request-body";
import {AbstractFileFieldDefaultComponent} from '../../models/abstract-file-field-default-component';
+import {FrontAction} from "../../models/changed-fields";
+import {FrontActionService} from "../../../actions/services/front-action.service";
export interface FileState {
progress: number;
@@ -114,6 +116,7 @@ export abstract class AbstractFileDefaultFieldComponent extends AbstractFileFiel
protected _translate: TranslateService,
protected _eventService: EventService,
protected _sanitizer: DomSanitizer,
+ protected _frontActionService: FrontActionService,
@Optional() @Inject(DATA_FIELD_PORTAL_DATA) dataFieldPortalData: DataFieldPortalData) {
super(_log, _snackbar, _translate, dataFieldPortalData);
this.state = this.defaultState;
@@ -217,60 +220,65 @@ export abstract class AbstractFileDefaultFieldComponent extends AbstractFileFiel
fileFormData.append('file', fileToUpload);
fileFormData.append('data', new Blob([JSON.stringify(this.createRequestBody())], {type: 'application/json'}));
this._taskResourceService.uploadFile(this.taskId, fileFormData, false)
- .subscribe((response: EventOutcomeMessageResource) => {
- if ((response as ProviderProgress).type && (response as ProviderProgress).type === ProgressType.UPLOAD) {
- this.state.progress = (response as ProviderProgress).progress;
- } else {
- this.state.completed = true;
- this.state.uploading = false;
- this.state.progress = 0;
+ .subscribe({
+ next: (response: EventOutcomeMessageResource) => {
+ if ((response as ProviderProgress).type && (response as ProviderProgress).type === ProgressType.UPLOAD) {
+ this.state.progress = (response as ProviderProgress).progress;
+ } else {
+ this.state.completed = true;
+ this.state.uploading = false;
+ this.state.progress = 0;
- if (response.error) {
- this.state.error = true;
- this._log.error(
- `File [${this.dataField.stringId}] ${this.fileUploadEl.nativeElement.files.item(0)} uploading has failed!`, response.error
- );
if (response.error) {
+ this.state.error = true;
+ this._log.error(
+ `File [${this.dataField.stringId}] ${this.fileUploadEl.nativeElement.files.item(0)?.name} uploading has failed!`, response.error
+ );
this._snackbar.openErrorSnackBar(this._translate.instant(response.error));
+
} else {
- this._snackbar.openErrorSnackBar(this._translate.instant('dataField.snackBar.fileUploadFailed'));
+ this._log.debug(
+ `File [${this.dataField.stringId}] ${this.fileUploadEl.nativeElement.files.item(0)?.name} was successfully uploaded`
+ );
+ const changedFieldsMap: ChangedFieldsMap = this._eventService.parseChangedFieldsFromOutcomeTree(response.outcome);
+ this.dataField.emitChangedFields(changedFieldsMap);
+ this.state.error = false;
+ this.dataField.downloaded = false;
+ this.dataField.value.name = fileToUpload.name;
+ if (this.isFilePreview) {
+ this.initializePreviewIfDisplayable();
+ }
+ this.fullSource.next(undefined);
+ this.fileForDownload = undefined;
+ this.formControlRef.setValue(this.dataField.value.name);
+ this._snackbar.openSuccessSnackBar(!!response.outcome.message ? response.outcome.message : this._translate.instant('tasks.snackbar.dataSaved'));
+ const frontActions: Array = this._eventService.parseFrontActionsFromOutcomeTree(response.outcome);
+ if (frontActions?.length > 0) {
+ this._frontActionService.runAll(frontActions);
+ }
}
+ this.dataField.touch = true;
+ this.dataField.update();
+ this.fileUploadEl.nativeElement.value = '';
+ }
+ },
+ error: (error) => {
+ this.state.completed = true;
+ this.state.error = true;
+ this.state.uploading = false;
+ this.state.progress = 0;
+ this._log.error(
+ `File [${this.dataField.stringId}] ${this.fileUploadEl.nativeElement.files.item(0)?.name} uploading has failed!`, error
+ );
+ if (error?.error?.message) {
+ this._snackbar.openErrorSnackBar(this._translate.instant(error.error.message));
} else {
- const changedFieldsMap: ChangedFieldsMap = this._eventService.parseChangedFieldsFromOutcomeTree(response.outcome);
- this.dataField.emitChangedFields(changedFieldsMap);
- this._log.debug(
- `File [${this.dataField.stringId}] ${this.fileUploadEl.nativeElement.files.item(0).name} was successfully uploaded`
- );
- this.state.error = false;
- this.dataField.downloaded = false;
- this.dataField.value.name = fileToUpload.name;
- if (this.isFilePreview) {
- this.initializePreviewIfDisplayable();
- }
- this.fullSource.next(undefined);
- this.fileForDownload = undefined;
- this.formControlRef.setValue(this.dataField.value.name);
+ this._snackbar.openErrorSnackBar(this._translate.instant('dataField.snackBar.fileUploadFailed'));
}
this.dataField.touch = true;
this.dataField.update();
this.fileUploadEl.nativeElement.value = '';
}
- }, error => {
- this.state.completed = true;
- this.state.error = true;
- this.state.uploading = false;
- this.state.progress = 0;
- this._log.error(
- `File [${this.dataField.stringId}] ${this.fileUploadEl.nativeElement.files.item(0)} uploading has failed!`, error
- );
- if (error?.error?.message) {
- this._snackbar.openErrorSnackBar(this._translate.instant(error.error.message));
- } else {
- this._snackbar.openErrorSnackBar(this._translate.instant('dataField.snackBar.fileUploadFailed'));
- }
- this.dataField.touch = true;
- this.dataField.update();
- this.fileUploadEl.nativeElement.value = '';
});
}
@@ -410,7 +418,8 @@ export abstract class AbstractFileDefaultFieldComponent extends AbstractFileFiel
this.state.downloading = true;
let params = new HttpParams()
params = params.set("fieldId", this.dataField.stringId);
- this._taskResourceService.downloadFilePreview(this.resolveParentTaskId(), params).subscribe(response => { if (response instanceof Blob) {
+ this._taskResourceService.downloadFilePreview(this.resolveParentTaskId(), params).subscribe(response => {
+ if (response instanceof Blob) {
this._log.debug(`Preview of file [${this.dataField.stringId}] ${this.dataField.value.name} was successfully downloaded`);
this.fileForPreview = new Blob([response], {type: 'application/octet-stream'});
this.previewSource = this._sanitizer.bypassSecurityTrustUrl(URL.createObjectURL(this.fileForPreview));
@@ -445,7 +454,8 @@ export abstract class AbstractFileDefaultFieldComponent extends AbstractFileFiel
}
let params = new HttpParams();
params = params.set("fieldId", this.dataField.stringId);
- this._taskResourceService.downloadFile(this.resolveParentTaskId(), params).subscribe(response => { if (!(response as ProviderProgress).type || (response as ProviderProgress).type !== ProgressType.DOWNLOAD) {
+ this._taskResourceService.downloadFile(this.resolveParentTaskId(), params).subscribe(response => {
+ if (!(response as ProviderProgress).type || (response as ProviderProgress).type !== ProgressType.DOWNLOAD) {
this._log.debug(`File [${this.dataField.stringId}] ${this.dataField.value.name} was successfully downloaded`);
this.initDownloadFile(response);
}
diff --git a/projects/netgrif-components-core/src/lib/data-fields/file-list-field/file-list-default-field/abstract-file-list-default-field.component.spec.ts b/projects/netgrif-components-core/src/lib/data-fields/file-list-field/file-list-default-field/abstract-file-list-default-field.component.spec.ts
index e03a36ea6..782c14187 100644
--- a/projects/netgrif-components-core/src/lib/data-fields/file-list-field/file-list-default-field/abstract-file-list-default-field.component.spec.ts
+++ b/projects/netgrif-components-core/src/lib/data-fields/file-list-field/file-list-default-field/abstract-file-list-default-field.component.spec.ts
@@ -16,9 +16,6 @@ import {MockUserResourceService} from "../../../utility/tests/mocks/mock-user-re
import {ConfigurationService} from "../../../configuration/configuration.service";
import {TestConfigurationService} from "../../../utility/tests/test-config";
import {Component, CUSTOM_ELEMENTS_SCHEMA, Inject, Optional} from "@angular/core";
-import {BrowserDynamicTestingModule} from "@angular/platform-browser-dynamic/testing";
-import {ErrorSnackBarComponent} from "../../../snack-bar/components/error-snack-bar/error-snack-bar.component";
-import {SuccessSnackBarComponent} from "../../../snack-bar/components/success-snack-bar/success-snack-bar.component";
import {TaskResourceService} from "../../../resources/engine-endpoint/task-resource.service";
import {LoggerService} from "../../../logger/services/logger.service";
import {SnackBarService} from "../../../snack-bar/services/snack-bar.service";
@@ -28,6 +25,8 @@ import {DATA_FIELD_PORTAL_DATA, DataFieldPortalData} from "../../models/data-fie
import {AbstractFileListDefaultFieldComponent} from "./abstract-file-list-default-field.component";
import {FormControl} from "@angular/forms";
import {WrappedBoolean} from "../../data-field-template/models/wrapped-boolean";
+import {FrontActionService} from "../../../actions/services/front-action.service";
+import {MockTaskResourceService} from "../../../utility/tests/mocks/mock-task-resource.service";
describe('AbstractFileListDefaultFieldComponent', () => {
let component: TestFileListComponent;
@@ -46,10 +45,12 @@ describe('AbstractFileListDefaultFieldComponent', () => {
providers: [
SideMenuService,
EventService,
+ FrontActionService,
{provide: AuthenticationMethodService, useClass: MockAuthenticationMethodService},
{provide: AuthenticationService, useClass: MockAuthenticationService},
{provide: UserResourceService, useClass: MockUserResourceService},
{provide: ConfigurationService, useClass: TestConfigurationService},
+ {provide: TaskResourceService, useClass: MockTaskResourceService},
{provide: DATA_FIELD_PORTAL_DATA, useValue: {
dataField: new FileListField('', '', {
required: true,
@@ -57,7 +58,7 @@ describe('AbstractFileListDefaultFieldComponent', () => {
visible: true,
editable: true,
hidden: true
- }),
+ }, {}),
formControlRef: new FormControl(),
showLargeLayout: new WrappedBoolean(),
additionalFieldProperties: {taskId: '0'}
@@ -79,6 +80,48 @@ describe('AbstractFileListDefaultFieldComponent', () => {
expect(component).toBeTruthy();
});
+ it('should simulate file download', () => {
+ // Spy on the 'download' method
+ spyOn(component, 'download').and.callFake(() => {
+ // Simulate the download process
+ const anchor = document.createElement('a');
+ anchor.href = 'data:text/plain;charset=utf-8,' + encodeURIComponent('mockContent');
+ anchor.download = 'mockFile.txt';
+ document.body.appendChild(anchor);
+ anchor.click();
+ document.body.removeChild(anchor);
+ });
+
+ // Call the 'download' method
+ component.download("mockFile.txt");
+
+ // Assert that the 'download' method was called
+ expect(component.download).toHaveBeenCalled();
+ });
+
+ it('should simulate file upload', () => {
+ // Create a mock file
+ const mockFile = new File(['mockContent'], 'mockFile.txt', {type: 'text/plain'});
+
+ // Get the file input element's reference
+ const fileInput = component.fileUploadEl.nativeElement;
+
+ // Create a DataTransfer object to simulate file selection
+ const dataTransfer = new DataTransfer();
+ dataTransfer.items.add(mockFile);
+ fileInput.files = dataTransfer.files;
+ component.dataField.value = {namesPaths: [{file: mockFile, name: "mockFile.txt"}]}
+ // Trigger the file upload method
+ spyOn(component, 'upload').and.callThrough();
+ const uploadButtonEvent = new Event('change');
+ fileInput.dispatchEvent(uploadButtonEvent);
+ component.upload();
+
+ // Assertions
+ expect(component.upload).toHaveBeenCalled();
+ expect(component.dataField.value).toBeTruthy(); // Ensure value is processed
+ });
+
afterEach(() => {
TestBed.resetTestingModule();
});
@@ -86,7 +129,7 @@ describe('AbstractFileListDefaultFieldComponent', () => {
@Component({
selector: 'ncc-test-filelist',
- template: ''
+ template: ''
})
class TestFileListComponent extends AbstractFileListDefaultFieldComponent {
constructor(taskResourceService: TaskResourceService,
@@ -94,8 +137,9 @@ class TestFileListComponent extends AbstractFileListDefaultFieldComponent {
snackbar: SnackBarService,
translate: TranslateService,
eventService: EventService,
+ frontActionService: FrontActionService,
@Optional() @Inject(DATA_FIELD_PORTAL_DATA) dataFieldPortalData: DataFieldPortalData) {
- super(taskResourceService, log, snackbar, translate, eventService, dataFieldPortalData);
+ super(taskResourceService, log, snackbar, translate, eventService, frontActionService, dataFieldPortalData);
}
}
diff --git a/projects/netgrif-components-core/src/lib/data-fields/file-list-field/file-list-default-field/abstract-file-list-default-field.component.ts b/projects/netgrif-components-core/src/lib/data-fields/file-list-field/file-list-default-field/abstract-file-list-default-field.component.ts
index 9fb99c8ee..56fec2aec 100644
--- a/projects/netgrif-components-core/src/lib/data-fields/file-list-field/file-list-default-field/abstract-file-list-default-field.component.ts
+++ b/projects/netgrif-components-core/src/lib/data-fields/file-list-field/file-list-default-field/abstract-file-list-default-field.component.ts
@@ -1,13 +1,10 @@
import {
AfterViewInit,
Component,
- ElementRef,
Inject,
- Input,
OnDestroy,
OnInit,
Optional,
- ViewChild
} from "@angular/core";
import {DATA_FIELD_PORTAL_DATA, DataFieldPortalData} from "../../models/data-field-portal-data-injection-token";
import {FileListField, FileListFieldValidation} from "../models/file-list-field";
@@ -17,16 +14,16 @@ import {LoggerService} from "../../../logger/services/logger.service";
import {SnackBarService} from "../../../snack-bar/services/snack-bar.service";
import {TranslateService} from "@ngx-translate/core";
import {EventService} from "../../../event/services/event.service";
-import {FileFieldIdBody} from "../../models/file-field-id-body";
import {EventOutcomeMessageResource} from "../../../resources/interface/message-resource";
import {ProgressType, ProviderProgress} from "../../../resources/resource-provider.service";
import {ChangedFieldsMap} from "../../../event/services/interfaces/changed-fields-map";
import {HttpParams} from "@angular/common/http";
import {take} from "rxjs/operators";
import {FileFieldValue} from "../../file-field/models/file-field-value";
-import {AbstractBaseDataFieldComponent} from "../../base-component/abstract-base-data-field.component";
import {FileFieldRequest} from "../../../resources/interface/file-field-request-body";
import {AbstractFileFieldDefaultComponent} from '../../models/abstract-file-field-default-component';
+import {FrontAction} from "../../models/changed-fields";
+import {FrontActionService} from "../../../actions/services/front-action.service";
export interface FilesState {
progress: number;
@@ -60,6 +57,7 @@ export abstract class AbstractFileListDefaultFieldComponent extends AbstractFile
protected _snackbar: SnackBarService,
protected _translate: TranslateService,
protected _eventService: EventService,
+ protected _frontActionService: FrontActionService,
@Optional() @Inject(DATA_FIELD_PORTAL_DATA) dataFieldPortalData: DataFieldPortalData) {
super(_log, _snackbar, _translate, dataFieldPortalData);
this.state = this.defaultState;
@@ -171,58 +169,62 @@ export abstract class AbstractFileListDefaultFieldComponent extends AbstractFile
fieldId: this.dataField.stringId,
}
fileFormData.append('data', new Blob([JSON.stringify(requestBody)], {type: 'application/json'}));
- this._taskResourceService.uploadFile(this.taskId, fileFormData, true).subscribe((response: EventOutcomeMessageResource) => {
- if ((response as ProviderProgress).type && (response as ProviderProgress).type === ProgressType.UPLOAD) {
- this.state.progress = (response as ProviderProgress).progress;
- } else {
- this.state.completed = true;
- this.state.uploading = false;
- this.state.progress = 0;
- this._log.debug(
- `Files [${this.dataField.stringId}] were successfully uploaded`
- );
- if (response.error) {
- this.state.error = true;
- this._log.error(
- `File [${this.dataField.stringId}] ${this.fileUploadEl.nativeElement.files.item(0)} uploading has failed!`, response.error
- );
+ this._taskResourceService.uploadFile(this.taskId, fileFormData, true)
+ .subscribe({
+ next: (response: EventOutcomeMessageResource) => {
+ if ((response as ProviderProgress).type && (response as ProviderProgress).type === ProgressType.UPLOAD) {
+ this.state.progress = (response as ProviderProgress).progress;
+ } else {
+ this.state.completed = true;
+ this.state.uploading = false;
+ this.state.progress = 0;
if (response.error) {
+ this.state.error = true;
+ this._log.error(
+ `File [${this.dataField.stringId}] ${this.fileUploadEl.nativeElement.files.item(0)?.name} uploading has failed!`, response.error
+ );
this._snackbar.openErrorSnackBar(this._translate.instant(response.error));
} else {
- this._snackbar.openErrorSnackBar(this._translate.instant('dataField.snackBar.fileUploadFailed'));
+ this._log.debug(
+ `Files [${this.dataField.stringId}] were successfully uploaded`
+ );
+ const changedFieldsMap: ChangedFieldsMap = this._eventService.parseChangedFieldsFromOutcomeTree(response.outcome);
+ this.dataField.emitChangedFields(changedFieldsMap);
+ this.state.error = false;
+ filesToUpload.forEach(fileToUpload => {
+ this.uploadedFiles.push(fileToUpload.name);
+ this.dataField.value.namesPaths.push({name: fileToUpload.name});
+ this.formControlRef.setValue(this.dataField.value.namesPaths.map(namePath => {
+ return namePath['name'];
+ }).join('/'));
+ });
+ this._snackbar.openSuccessSnackBar(!!response.outcome.message ? response.outcome.message : this._translate.instant('tasks.snackbar.dataSaved'));
+ const frontActions: Array = this._eventService.parseFrontActionsFromOutcomeTree(response.outcome);
+ if (frontActions?.length > 0) {
+ this._frontActionService.runAll(frontActions);
+ }
}
+ this.dataField.touch = true;
+ this.dataField.update();
+ this.fileUploadEl.nativeElement.value = '';
+ }
+ }, error: (error) => {
+ this.state.completed = true;
+ this.state.error = true;
+ this.state.uploading = false;
+ this.state.progress = 0;
+ if (error?.error?.message) {
+ this._snackbar.openErrorSnackBar(this._translate.instant(error.error.message));
} else {
- const changedFieldsMap: ChangedFieldsMap = this._eventService.parseChangedFieldsFromOutcomeTree(response.outcome);
- this.dataField.emitChangedFields(changedFieldsMap);
- this.state.error = false;
- filesToUpload.forEach(fileToUpload => {
- this.uploadedFiles.push(fileToUpload.name);
- this.dataField.value.namesPaths.push({name: fileToUpload.name});
- this.formControlRef.setValue(this.dataField.value.namesPaths.map(namePath => {
- return namePath['name'];
- }).join('/'));
- });
+ this._snackbar.openErrorSnackBar(this._translate.instant('dataField.snackBar.fileUploadFailed'));
}
+ this._log.error(
+ `File [${this.dataField.stringId}] ${this.fileUploadEl.nativeElement.files.item(0)?.name} uploading has failed!`, error
+ );
this.dataField.touch = true;
this.dataField.update();
this.fileUploadEl.nativeElement.value = '';
}
- }, error => {
- this.state.completed = true;
- this.state.error = true;
- this.state.uploading = false;
- this.state.progress = 0;
- if (error?.error?.message) {
- this._snackbar.openErrorSnackBar(this._translate.instant(error.error.message));
- } else {
- this._snackbar.openErrorSnackBar(this._translate.instant('dataField.snackBar.fileUploadFailed'));
- }
- this._log.error(
- `File [${this.dataField.stringId}] ${this.fileUploadEl.nativeElement.files.item(0)} uploading has failed!`, error
- );
- this.dataField.touch = true;
- this.dataField.update();
- this.fileUploadEl.nativeElement.value = '';
});
}
diff --git a/projects/netgrif-components-core/src/lib/event/services/event.service.ts b/projects/netgrif-components-core/src/lib/event/services/event.service.ts
index b8805bbfd..cec572d1f 100644
--- a/projects/netgrif-components-core/src/lib/event/services/event.service.ts
+++ b/projects/netgrif-components-core/src/lib/event/services/event.service.ts
@@ -57,6 +57,9 @@ export class EventService {
public parseFrontActionsFromOutcomeTree(outcome: EventOutcome): Array {
const frontActions: Array = [];
+ if (!!outcome.frontActions) {
+ frontActions.push(...outcome.frontActions);
+ }
if (!!outcome.outcomes && outcome.outcomes.length > 0) {
return this.parseFrontActionsFromOutcomeTreeRecursive(outcome.outcomes, frontActions);
} else return frontActions;
diff --git a/projects/netgrif-components-core/src/lib/utility/tests/mocks/mock-task-resource.service.ts b/projects/netgrif-components-core/src/lib/utility/tests/mocks/mock-task-resource.service.ts
index c42dabdc7..e02c570a0 100644
--- a/projects/netgrif-components-core/src/lib/utility/tests/mocks/mock-task-resource.service.ts
+++ b/projects/netgrif-components-core/src/lib/utility/tests/mocks/mock-task-resource.service.ts
@@ -2,9 +2,14 @@ import {Injectable} from "@angular/core";
import {Observable, of} from "rxjs";
import {Page} from "../../../resources/interface/page";
import {Task} from "../../../resources/interface/task";
+import {TaskResourceService} from "../../../resources/engine-endpoint/task-resource.service";
+import {ProviderProgress} from "../../../resources/resource-provider.service";
+import {EventOutcomeMessageResource} from "../../../resources/interface/message-resource";
+import {SetDataEventOutcome} from "../../../event/model/event-outcomes/data-outcomes/set-data-event-outcome";
+import {Change} from "../../../data-fields/models/changed-fields";
@Injectable()
-export class MockTaskResourceService {
+export class MockTaskResourceService extends TaskResourceService {
searchTask(): Observable> {
return of();
@@ -13,4 +18,22 @@ export class MockTaskResourceService {
getTasks(): Observable> {
return of();
}
+
+
+ uploadFile(taskId: string, body: object, multipleFiles: boolean): Observable {
+ return of({
+ outcome: {
+ net: undefined,
+ aCase: undefined,
+ task: undefined,
+ changedFields: {
+ changedFields: {
+ text: {
+ value: ""
+ } as Change
+ }
+ }
+ } as SetDataEventOutcome
+ });
+ }
}
diff --git a/projects/netgrif-components/src/lib/data-fields/file-field/file-default-field/file-default-field.component.spec.ts b/projects/netgrif-components/src/lib/data-fields/file-field/file-default-field/file-default-field.component.spec.ts
index 4c4365875..1a8b3abc7 100644
--- a/projects/netgrif-components/src/lib/data-fields/file-field/file-default-field/file-default-field.component.spec.ts
+++ b/projects/netgrif-components/src/lib/data-fields/file-field/file-default-field/file-default-field.component.spec.ts
@@ -6,7 +6,7 @@ import {
AuthenticationService,
ConfigurationService,
DATA_FIELD_PORTAL_DATA, DataFieldPortalData,
- ErrorSnackBarComponent, FileField,
+ ErrorSnackBarComponent, FileField, FrontActionService,
MaterialModule,
MockAuthenticationMethodService,
MockAuthenticationService,
@@ -39,6 +39,7 @@ describe('FileDefaultFieldComponent', () => {
],
providers: [
SideMenuService,
+ FrontActionService,
{provide: AuthenticationMethodService, useClass: MockAuthenticationMethodService},
{provide: AuthenticationService, useClass: MockAuthenticationService},
{provide: UserResourceService, useClass: MockUserResourceService},
diff --git a/projects/netgrif-components/src/lib/data-fields/file-field/file-default-field/file-default-field.component.ts b/projects/netgrif-components/src/lib/data-fields/file-field/file-default-field/file-default-field.component.ts
index 378008fd9..f770cc156 100644
--- a/projects/netgrif-components/src/lib/data-fields/file-field/file-default-field/file-default-field.component.ts
+++ b/projects/netgrif-components/src/lib/data-fields/file-field/file-default-field/file-default-field.component.ts
@@ -5,7 +5,7 @@ import {
LoggerService,
SnackBarService,
TaskResourceService,
- AbstractFileDefaultFieldComponent
+ AbstractFileDefaultFieldComponent, FrontActionService
} from "@netgrif/components-core";
import {TranslateService} from "@ngx-translate/core";
import {DomSanitizer} from "@angular/platform-browser";
@@ -26,8 +26,9 @@ export class FileDefaultFieldComponent extends AbstractFileDefaultFieldComponent
eventService: EventService,
protected _sanitizer: DomSanitizer,
protected dialog: MatDialog,
+ frontActionService: FrontActionService,
@Optional() @Inject(DATA_FIELD_PORTAL_DATA) dataFieldPortalData: DataFieldPortalData) {
- super(taskResourceService, log, snackbar, translate, eventService, _sanitizer, dataFieldPortalData);
+ super(taskResourceService, log, snackbar, translate, eventService, _sanitizer, frontActionService, dataFieldPortalData);
}
public showPreviewDialog() {
diff --git a/projects/netgrif-components/src/lib/data-fields/file-list-field/file-list-default-field/file-list-default-field.component.spec.ts b/projects/netgrif-components/src/lib/data-fields/file-list-field/file-list-default-field/file-list-default-field.component.spec.ts
index 02b15542d..062c1a3e3 100644
--- a/projects/netgrif-components/src/lib/data-fields/file-list-field/file-list-default-field/file-list-default-field.component.spec.ts
+++ b/projects/netgrif-components/src/lib/data-fields/file-list-field/file-list-default-field/file-list-default-field.component.spec.ts
@@ -7,7 +7,7 @@ import {
ConfigurationService,
DATA_FIELD_PORTAL_DATA,
DataFieldPortalData,
- FileListField,
+ FileListField, FrontActionService,
MaterialModule,
MockAuthenticationMethodService,
MockAuthenticationService,
@@ -42,6 +42,7 @@ describe('FileListDefaultFieldComponent', () => {
],
providers: [
SideMenuService,
+ FrontActionService,
{provide: AuthenticationMethodService, useClass: MockAuthenticationMethodService},
{provide: AuthenticationService, useClass: MockAuthenticationService},
{provide: UserResourceService, useClass: MockUserResourceService},
diff --git a/projects/netgrif-components/src/lib/data-fields/file-list-field/file-list-default-field/file-list-default-field.component.ts b/projects/netgrif-components/src/lib/data-fields/file-list-field/file-list-default-field/file-list-default-field.component.ts
index 9a4d00a7f..e581ce13b 100644
--- a/projects/netgrif-components/src/lib/data-fields/file-list-field/file-list-default-field/file-list-default-field.component.ts
+++ b/projects/netgrif-components/src/lib/data-fields/file-list-field/file-list-default-field/file-list-default-field.component.ts
@@ -7,7 +7,7 @@ import {
EventService,
DATA_FIELD_PORTAL_DATA,
DataFieldPortalData,
- FileListField, AbstractFileListDefaultFieldComponent
+ FileListField, AbstractFileListDefaultFieldComponent, FrontActionService
} from '@netgrif/components-core'
@Component({
@@ -22,7 +22,8 @@ export class FileListDefaultFieldComponent extends AbstractFileListDefaultFieldC
snackbar: SnackBarService,
translate: TranslateService,
eventService: EventService,
+ frontActionService: FrontActionService,
@Optional() @Inject(DATA_FIELD_PORTAL_DATA) dataFieldPortalData: DataFieldPortalData) {
- super(taskResourceService, log, snackbar, translate, eventService, dataFieldPortalData);
+ super(taskResourceService, log, snackbar, translate, eventService, frontActionService, dataFieldPortalData);
}
}