diff --git a/demo-shell-ng2/app/components/activiti/activiti-demo.component.html b/demo-shell-ng2/app/components/activiti/activiti-demo.component.html index 4f00688632..8fdcae6d86 100644 --- a/demo-shell-ng2/app/components/activiti/activiti-demo.component.html +++ b/demo-shell-ng2/app/components/activiti/activiti-demo.component.html @@ -119,7 +119,9 @@ + (editReport)="onEditReport($event)" + (reportSaved)="onReportSaved()" + (reportDeleted)="onReportDeleted()"> diff --git a/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts b/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts index 0fee1a1127..7c030da7f1 100644 --- a/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts +++ b/demo-shell-ng2/app/components/activiti/activiti-demo.component.ts @@ -104,8 +104,8 @@ export class ActivitiDemoComponent implements AfterViewInit { this.dataTasks = new ObjectDataTableAdapter( [], [ - {type: 'text', key: 'name', title: 'Name', cssClass: 'full-width name-column', sortable: true}, - {type: 'text', key: 'created', title: 'Created', cssClass: 'hidden', sortable: true} + { type: 'text', key: 'name', title: 'Name', cssClass: 'full-width name-column', sortable: true }, + { type: 'text', key: 'created', title: 'Created', cssClass: 'hidden', sortable: true } ] ); this.dataTasks.setSorting(new DataSorting('created', 'desc')); @@ -113,8 +113,8 @@ export class ActivitiDemoComponent implements AfterViewInit { this.dataProcesses = new ObjectDataTableAdapter( [], [ - {type: 'text', key: 'name', title: 'Name', cssClass: 'full-width name-column', sortable: true}, - {type: 'text', key: 'started', title: 'Started', cssClass: 'hidden', sortable: true} + { type: 'text', key: 'name', title: 'Name', cssClass: 'full-width name-column', sortable: true }, + { type: 'text', key: 'started', title: 'Started', cssClass: 'hidden', sortable: true } ] ); this.dataProcesses.setSorting(new DataSorting('started', 'desc')); @@ -154,7 +154,7 @@ export class ActivitiDemoComponent implements AfterViewInit { } onTaskFilterClick(event: FilterRepresentationModel) { - if(event){ + if (event) { this.taskFilter = event; } } @@ -202,6 +202,21 @@ export class ActivitiDemoComponent implements AfterViewInit { this.analyticsreportlist.reload(); } + onReportSaved() { + this.analyticsreportlist.reload(); + } + + onReportDeleted() { + this.analyticsreportlist.reload(); + this.selectFirstElementInReportList(); + } + + selectFirstElementInReportList(){ + if (! this.analyticsreportlist.isReportsEmpty()) { + this.analyticsreportlist.selectReport(this.analyticsreportlist.reports[0]); + } + } + navigateStartProcess() { this.resetProcessFilters(); this.reloadProcessFilters(); diff --git a/ng2-components/ng2-activiti-analytics/README.md b/ng2-components/ng2-activiti-analytics/README.md index bc9bae8974..9c7eb99a83 100644 --- a/ng2-components/ng2-activiti-analytics/README.md +++ b/ng2-components/ng2-activiti-analytics/README.md @@ -251,6 +251,8 @@ platformBrowserDynamic().bootstrapModule(AppModule); | --- | --- | |`onSuccess` | The event is emitted when the report parameters are loaded | |`onError` | The event is emitted when an error occur during the loading | +|`reportSaved` | The event is emitted when a report is saved | +|`reportDeleted` | The event is emitted when a report is deleted | #### Options diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.css b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.css index 947c5d475a..f703726852 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.css +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.css @@ -63,3 +63,29 @@ .report-container-setting { padding-left: 10px; } + +.option_button_details{ + padding-top: 20px; +} + +.mdl-dialog__title.choose_name{ + padding: 0px; +} + +.mdl-dialog.options-name-dialog { + width: 30%; +} + +.export-message{ + background-color: lightgray; +} + +.save-export-input{ + width:100%; +} + +.delete-parameter { + position: absolute; + margin-left: 60%; + padding-top: 5px; +} diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.html b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.html index 91b38999f5..f2bfcdcbe2 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.html +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.html @@ -2,8 +2,8 @@
-
- + -
-
-
+
+ +
+ mode_edit +

{{reportParameters.name}}

+
+
+ -
- mode_edit -

{{reportParameters.name}}

-
-
-
-
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
-
- -
-
- {{'ANALYTICS.MESSAGES.UNKNOWN-WIDGET-TYPE' | translate}}: {{field.type}} +
+
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+
+ +
+
+ {{'ANALYTICS.MESSAGES.UNKNOWN-WIDGET-TYPE' | translate}}: {{field.type}} +
-
-
-

ReportForm valid : {{ reportForm.valid }}

-

ReportForm status : {{ reportForm.errors | json }}

-

ReportForm FormGroup valid : {{reportForm && reportForm.controls.dateRange.valid | json }}

-
+
+
+ + +
+
+ +
{{action}} report
+
+
{{'DIALOG.SAVE_MESSAGE' | translate}}
+
+ + +
+
+
+ + +
+
+
+

ReportForm valid : {{ reportForm.valid }}

+

ReportForm status : {{ reportForm.errors | json }}

+

ReportForm FormGroup valid : {{reportForm && reportForm.controls.dateRange.valid | json }}

+
diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.spec.ts b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.spec.ts index 4354d1bb25..6d46a4ac98 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.spec.ts +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.spec.ts @@ -55,7 +55,9 @@ describe('AnalyticsReportParametersComponent', () => { let translateService = TestBed.get(AlfrescoTranslationService); spyOn(translateService, 'addTranslationFolder').and.stub(); - spyOn(translateService, 'get').and.callFake((key) => { return Observable.of(key); }); + spyOn(translateService, 'get').and.callFake((key) => { + return Observable.of(key); + }); componentHandler = jasmine.createSpyObj('componentHandler', [ 'upgradeAllRegistered' @@ -80,17 +82,22 @@ describe('AnalyticsReportParametersComponent', () => { jasmine.Ajax.uninstall(); }); - it('Should initialize the Report form with a Form Group ', () => { - expect(component.reportForm.get('dateRange')).toBeDefined(); - expect(component.reportForm.get('dateRange').get('startDate')).toBeDefined(); - expect(component.reportForm.get('dateRange').get('endDate')).toBeDefined(); + it('Should initialize the Report form with a Form Group ', (done) => { + let fakeReportParam = new ReportParametersModel(analyticParamsMock.reportDefParamTask); + component.onSuccessReportParams.subscribe(() => { + fixture.detectChanges(); + expect(component.reportForm.get('taskGroup')).toBeDefined(); + expect(component.reportForm.get('taskGroup').get('taskName')).toBeDefined(); + done(); + }); + component.onSuccessReportParams.emit(fakeReportParam); }); it('Should render a dropdown with all the status when the definition parameter type is \'status\' ', (done) => { component.onSuccessReportParams.subscribe(() => { fixture.detectChanges(); let dropDown: any = element.querySelector('#select-status'); - expect(element.querySelector('h4').innerHTML).toEqual('Fake Task overview status'); + expect(element.querySelector('h4').textContent.trim()).toEqual('Fake Task overview status'); expect(dropDown).toBeDefined(); expect(dropDown.length).toEqual(4); expect(dropDown[0].innerHTML).toEqual('Choose One'); @@ -400,5 +407,148 @@ describe('AnalyticsReportParametersComponent', () => { let numberConvert = component.convertNumber('2'); expect(numberConvert).toEqual(2); }); + + describe('When the form is rendered correctly', () => { + let values: any = { + dateRange: { + startDate: '2016-09-01', endDate: '2016-10-05' + }, + statusGroup: { + status: 'All' + }, + processDefGroup: { + processDefinitionId: 'FakeProcess:1:22' + }, + taskGroup: { + taskName: 'FakeTaskName' + }, + durationGroup: { + duration: 22 + }, + dateIntervalGroup: { + dateRangeInterval: 120 + }, + processInstanceGroup: { + slowProcessInstanceInteger: 2 + }, + typeFilteringGroup: { + typeFiltering: true + } + }; + + beforeEach(async(() => { + let reportId = 1; + let change = new SimpleChange(null, reportId); + component.ngOnChanges({ 'reportId': change }); + fixture.detectChanges(); + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'json', + responseText: analyticParamsMock.reportDefParamStatus + }); + fixture.whenStable().then(() => { + component.toggleParameters(); + component.reportId = '1'; + spyOn(component, 'isFormValid').and.returnValue(true); + fixture.detectChanges(); + }); + })); + + it('Should be able to change the report title', async(() => { + let title: HTMLElement = element.querySelector('h4'); + title.click(); + fixture.detectChanges(); + let reportName: HTMLInputElement = element.querySelector('#reportName'); + expect(reportName).not.toBeNull(); + reportName.focus(); + component.reportParameters.name = 'FAKE_TEST_NAME'; + reportName.value = 'FAKE_TEST_NAME'; + reportName.blur(); + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'json', + responseText: analyticParamsMock.reportDefParamStatus + }); + fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.detectChanges(); + let titleChanged: HTMLElement = element.querySelector('h4'); + expect(titleChanged.textContent.trim()).toEqual('FAKE_TEST_NAME'); + }); + })); + + it('Should show a dialog to allowing report save', async(() => { + component.saveReportSuccess.subscribe(() => { + let reportDialogTitle: HTMLElement = element.querySelector('#report-dialog'); + expect(reportDialogTitle.getAttribute('open')).toBeNull(); + }); + + component.submit(values); + fixture.detectChanges(); + let saveButton: HTMLButtonElement = element.querySelector('#save-button'); + expect(saveButton).toBeDefined(); + expect(saveButton).not.toBeNull(); + saveButton.click(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.detectChanges(); + let reportDialogTitle: HTMLElement = element.querySelector('#report-dialog-title'); + let saveTitleSubMessage: HTMLElement = element.querySelector('#save-title-submessage'); + let inputSaveName: HTMLInputElement = element.querySelector('#repName'); + let performActionButton: HTMLButtonElement = element.querySelector('#action-dialog-button'); + let todayDate = component.getTodayDate(); + expect(reportDialogTitle).not.toBeNull(); + expect(saveTitleSubMessage).not.toBeNull(); + expect(inputSaveName.value.trim()).toEqual(analyticParamsMock.reportDefParamStatus.name + ' ( ' + todayDate + ' )'); + expect(performActionButton).not.toBeNull(); + performActionButton.click(); + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'json' + }); + }); + })); + + it('Should show a dialog to allowing report export', async(() => { + component.submit(values); + spyOn(component, 'generateDownloadElement').and.stub(); + fixture.detectChanges(); + let exportButton: HTMLButtonElement = element.querySelector('#export-button'); + expect(exportButton).toBeDefined(); + expect(exportButton).not.toBeNull(); + exportButton.click(); + fixture.detectChanges(); + fixture.whenStable().then(() => { + fixture.detectChanges(); + let reportDialogTitle: HTMLElement = element.querySelector('#report-dialog-title'); + let inputSaveName: HTMLInputElement = element.querySelector('#repName'); + let performActionButton: HTMLButtonElement = element.querySelector('#action-dialog-button'); + let todayDate = component.getTodayDate(); + expect(reportDialogTitle).not.toBeNull(); + expect(inputSaveName.value.trim()).toEqual(analyticParamsMock.reportDefParamStatus.name + ' ( ' + todayDate + ' )'); + expect(performActionButton).not.toBeNull(); + performActionButton.click(); + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'json' + }); + }); + })); + + it('Should raise an event for report deleted', async(() => { + let deleteButton: HTMLButtonElement = element.querySelector('#delete-button'); + expect(deleteButton).toBeDefined(); + expect(deleteButton).not.toBeNull(); + + component.deleteReportSuccess.subscribe((reportId) => { + expect(reportId).not.toBeNull(); + }); + deleteButton.click(); + jasmine.Ajax.requests.mostRecent().respondWith({ + status: 200, + contentType: 'json' + }); + })); + }); }); }); diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.ts b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.ts index b1e3297328..b7c5e45386 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.ts +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics-report-parameters.component.ts @@ -24,7 +24,8 @@ import { Output, SimpleChanges, OnDestroy, - AfterViewChecked + AfterViewChecked, + ViewChild } from '@angular/core'; import { FormGroup, FormBuilder, FormControl } from '@angular/forms'; import * as moment from 'moment'; @@ -38,6 +39,7 @@ import { } from '../models/report.model'; declare var componentHandler; +declare let dialogPolyfill: any; @Component({ moduleId: module.id, @@ -47,7 +49,7 @@ declare var componentHandler; }) export class AnalyticsReportParametersComponent implements OnInit, OnChanges, OnDestroy, AfterViewChecked { - public static FORMAT_DATE_ACTIVITI: string = 'YYYY-MM-DD'; + public static FORMAT_DATE_ACTIVITI: string = 'YYYY-MM-DD'; @Input() appId: string; @@ -70,6 +72,15 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges, On @Output() onFormValueChanged = new EventEmitter(); + @Output() + saveReportSuccess = new EventEmitter(); + + @Output() + deleteReportSuccess = new EventEmitter(); + + @ViewChild('reportNameDialog') + reportNameDialog: any; + onDropdownChanged = new EventEmitter(); onSuccessReportParams = new EventEmitter(); @@ -84,6 +95,9 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges, On private reportParamsSub; private paramOpts; private isEditable: boolean = false; + private action: string; + private reportParamQuery: ReportQuery; + private reportName: string; private hideParameters: boolean = true; constructor(private translateService: AlfrescoTranslationService, @@ -96,8 +110,6 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges, On } ngOnInit() { - this.initForm(); - this.dropDownSub = this.onDropdownChanged.subscribe((field) => { let paramDependOn: ReportParameterDetailsModel = this.reportParameters.definition.parameters.find(p => p.dependsOn === field.id); if (paramDependOn) { @@ -108,10 +120,9 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges, On this.paramOpts = this.onSuccessReportParams.subscribe((report: ReportParametersModel) => { if (report.hasParameters()) { this.retrieveParameterOptions(report.definition.parameters, this.appId); + this.generateFormGroupFromParameter(report.definition.parameters); } }); - - this.reportForm.valueChanges.subscribe(data => this.onValueChanged(data)); } ngOnChanges(changes: SimpleChanges) { @@ -127,31 +138,54 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges, On } } - initForm() { - this.reportForm = this.formBuilder.group({ - dateRange: new FormGroup({}), - statusGroup: new FormGroup({ - status: new FormControl() - }), - processInstanceGroup: new FormGroup({ - slowProcessInstanceInteger: new FormControl() - }), - taskGroup: new FormGroup({ - taskName: new FormControl() - }), - typeFilteringGroup: new FormGroup({ - typeFiltering: new FormControl() - }), - dateIntervalGroup: new FormGroup({ - dateRangeInterval: new FormControl() - }), - durationGroup: new FormGroup({ - duration: new FormControl() - }), - processDefGroup: new FormGroup({ - processDefinitionId: new FormControl() - }) + private generateFormGroupFromParameter(parameters: ReportParameterDetailsModel[]) { + let formBuilderGroup: any = {}; + parameters.forEach((param: ReportParameterDetailsModel) => { + switch (param.type) { + case 'dateRange' : + formBuilderGroup.dateRange = new FormGroup({}); + break; + case 'processDefinition': + formBuilderGroup.processDefGroup = new FormGroup({ + processDefinitionId: new FormControl() + }); + break; + case 'duration': + formBuilderGroup.durationGroup = new FormGroup({ + duration: new FormControl() + }); + break; + case 'dateInterval': + formBuilderGroup.dateIntervalGroup = new FormGroup({ + dateRangeInterval: new FormControl() + }); + break; + case 'boolean': + formBuilderGroup.typeFilteringGroup = new FormGroup({ + typeFiltering: new FormControl() + }); + break; + case 'task': + formBuilderGroup.taskGroup = new FormGroup({ + taskName: new FormControl() + }); + break; + case 'integer': + formBuilderGroup.processInstanceGroup = new FormGroup({ + slowProcessInstanceInteger: new FormControl() + }); + break; + case 'status': + formBuilderGroup.statusGroup = new FormGroup({ + status: new FormControl() + }); + break; + default: + return; + } }); + this.reportForm = this.formBuilder.group(formBuilderGroup); + this.reportForm.valueChanges.subscribe(data => this.onValueChanged(data)); } public getReportParams(reportId: string) { @@ -193,8 +227,8 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges, On } public submit(values: any) { - let reportParamQuery = this.convertFormValuesToReportParamQuery(values); - this.onSuccess.emit(reportParamQuery); + this.reportParamQuery = this.convertFormValuesToReportParamQuery(values); + this.onSuccess.emit(this.reportParamQuery); } onValueChanged(values: any) { @@ -209,21 +243,41 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges, On .format(AnalyticsReportParametersComponent.FORMAT_DATE_ACTIVITI) + 'T00:00:00.000Z'; } + public getTodayDate() { + return moment().format(AnalyticsReportParametersComponent.FORMAT_DATE_ACTIVITI); + } + public convertNumber(value: string): number { return value != null ? parseInt(value, 10) : 0; } convertFormValuesToReportParamQuery(values: any): ReportQuery { let reportParamQuery: ReportQuery = new ReportQuery(); - reportParamQuery.dateRange.startDate = this.convertMomentDate(values.dateRange.startDate); - reportParamQuery.dateRange.endDate = this.convertMomentDate(values.dateRange.endDate); - reportParamQuery.status = values.statusGroup.status; - reportParamQuery.processDefinitionId = values.processDefGroup.processDefinitionId; - reportParamQuery.taskName = values.taskGroup.taskName; - reportParamQuery.duration = values.durationGroup.duration; - reportParamQuery.dateRangeInterval = values.dateIntervalGroup.dateRangeInterval; - reportParamQuery.slowProcessInstanceInteger = this.convertNumber(values.processInstanceGroup.slowProcessInstanceInteger); - reportParamQuery.typeFiltering = values.typeFilteringGroup.typeFiltering; + if (values.dateRange) { + reportParamQuery.dateRange.startDate = this.convertMomentDate(values.dateRange.startDate); + reportParamQuery.dateRange.endDate = this.convertMomentDate(values.dateRange.endDate); + } + if (values.statusGroup) { + reportParamQuery.status = values.statusGroup.status; + } + if (values.processDefGroup) { + reportParamQuery.processDefinitionId = values.processDefGroup.processDefinitionId; + } + if (values.taskGroup) { + reportParamQuery.taskName = values.taskGroup.taskName; + } + if (values.durationGroup) { + reportParamQuery.duration = values.durationGroup.duration; + } + if (values.dateIntervalGroup) { + reportParamQuery.dateRangeInterval = values.dateIntervalGroup.dateRangeInterval; + } + if (values.processInstanceGroup) { + reportParamQuery.slowProcessInstanceInteger = this.convertNumber(values.processInstanceGroup.slowProcessInstanceInteger); + } + if (values.typeFilteringGroup) { + reportParamQuery.typeFiltering = values.typeFilteringGroup.typeFiltering; + } return reportParamQuery; } @@ -236,7 +290,7 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges, On } public editEnable() { - this.isEditable = true; + this.isEditable = true; } public editDisable() { @@ -256,6 +310,74 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges, On ); } + public showDialog(event: string) { + if (!this.reportNameDialog.nativeElement.showModal) { + dialogPolyfill.registerDialog(this.reportNameDialog.nativeElement); + } + this.reportNameDialog.nativeElement.showModal(); + this.action = event; + this.reportName = this.reportParameters.name + ' ( ' + this.getTodayDate() + ' )'; + } + + closeDialog() { + if (this.reportNameDialog) { + this.reportNameDialog.nativeElement.close(); + } + } + + performAction(action: string, reportParamQuery: ReportQuery) { + reportParamQuery.reportName = this.reportName; + this.closeDialog(); + if (action === 'Save') { + this.doSave(reportParamQuery); + } else if (action === 'Export') { + this.doExport(reportParamQuery); + } + this.resetActions(); + } + + resetActions() { + this.action = ''; + this.reportName = ''; + } + + isFormValid() { + return this.reportForm && this.reportForm.valid && this.reportForm.dirty; + } + + isSaveAction() { + return this.action === 'Save'; + } + + doExport(paramQuery: ReportQuery) { + this.analyticsService.exportReportToCsv(this.reportId, paramQuery).subscribe( + (data: any) => { + let blob: Blob = new Blob([data], { type: 'text/csv' }); + let downloadUrl = window.URL.createObjectURL(blob); + this.generateDownloadElement(downloadUrl, paramQuery); + }); + } + + private generateDownloadElement(downloadUrl: string, paramQuery: ReportQuery) { + let downloadElement = window.document.createElement('a'); + downloadElement.setAttribute('id', 'export-download'); + downloadElement.setAttribute('href', downloadUrl); + downloadElement.setAttribute('download', paramQuery.reportName); + downloadElement.click(); + } + + doSave(paramQuery: ReportQuery) { + this.analyticsService.saveReport(this.reportId, paramQuery).subscribe(() => { + this.saveReportSuccess.emit(); + }); + } + + deleteReport(reportId: string) { + this.analyticsService.deleteReport(reportId).subscribe(() => { + this.deleteReportSuccess.emit(reportId); + }, error => this.logService.error(error)); + } + ngAfterViewChecked() { // workaround for MDL issues with dynamic components if (componentHandler) { diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics.component.html b/ng2-components/ng2-activiti-analytics/src/components/analytics.component.html index 0cfae9ccdc..3f16077c5c 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics.component.html +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics.component.html @@ -2,6 +2,8 @@ diff --git a/ng2-components/ng2-activiti-analytics/src/components/analytics.component.ts b/ng2-components/ng2-activiti-analytics/src/components/analytics.component.ts index 21572dd43e..959d82329a 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/analytics.component.ts +++ b/ng2-components/ng2-activiti-analytics/src/components/analytics.component.ts @@ -41,6 +41,12 @@ export class AnalyticsComponent implements OnChanges { @Output() editReport = new EventEmitter(); + @Output() + reportSaved = new EventEmitter(); + + @Output() + reportDeleted = new EventEmitter(); + @ViewChild('analyticsgenerator') analyticsgenerator: AnalyticsGeneratorComponent; @@ -71,4 +77,12 @@ export class AnalyticsComponent implements OnChanges { this.editReport.emit(name); } + public onSaveReportSuccess() { + this.reportSaved.emit(); + } + + public onDeleteReportSuccess() { + this.reportDeleted.emit(); + } + } diff --git a/ng2-components/ng2-activiti-analytics/src/components/widgets/dropdown/dropdown.widget.ts b/ng2-components/ng2-activiti-analytics/src/components/widgets/dropdown/dropdown.widget.ts index 4e9450b361..9f6ca1434f 100644 --- a/ng2-components/ng2-activiti-analytics/src/components/widgets/dropdown/dropdown.widget.ts +++ b/ng2-components/ng2-activiti-analytics/src/components/widgets/dropdown/dropdown.widget.ts @@ -16,7 +16,7 @@ */ import { Component, Input, Output, EventEmitter } from '@angular/core'; -import { FormGroup, Validators } from '@angular/forms'; +import { FormGroup, Validators, FormControl } from '@angular/forms'; import { WidgetComponent } from './../widget.component'; @Component({ @@ -54,7 +54,20 @@ export class DropdownWidget extends WidgetComponent { ngOnInit() { if (this.required) { - this.formGroup.get(this.controllerName).setValidators(Validators.required); + this.formGroup.get(this.controllerName).setValidators(Validators.compose(this.buildValidatorList())); } } + + validateDropDown(controller: FormControl) { + return controller.value !== 'null' ? null : { controllerName: false }; + } + + buildValidatorList() { + let validatorList = []; + validatorList.push(Validators.required); + if (this.showDefaultOption) { + validatorList.push(this.validateDropDown); + } + return validatorList; + } } diff --git a/ng2-components/ng2-activiti-analytics/src/i18n/en.json b/ng2-components/ng2-activiti-analytics/src/i18n/en.json index 9e5cd9ca95..19d67e515d 100644 --- a/ng2-components/ng2-activiti-analytics/src/i18n/en.json +++ b/ng2-components/ng2-activiti-analytics/src/i18n/en.json @@ -43,5 +43,9 @@ }, "PROCESS-STATUS": "Process status", "TASK-STATUS": "Task status" + }, + "DIALOG":{ + "SAVE_MESSAGE" : "The current parameter settings will be stored, and a new report will be shown in the reports list. When that particular report is clicked, the report will be generated using these saved parameter values.", + "EXPORT_MESSAGE":"" } } diff --git a/ng2-components/ng2-activiti-analytics/src/models/report.model.ts b/ng2-components/ng2-activiti-analytics/src/models/report.model.ts index df82947ac2..5014a3c0e3 100644 --- a/ng2-components/ng2-activiti-analytics/src/models/report.model.ts +++ b/ng2-components/ng2-activiti-analytics/src/models/report.model.ts @@ -106,6 +106,7 @@ export class ParameterValueModel { } export class ReportQuery { + reportName: string; processDefinitionId: string; status: string; taskName: string; @@ -116,6 +117,7 @@ export class ReportQuery { duration: number; constructor(obj?: any) { + this.reportName = obj && obj.reportName || null; this.processDefinitionId = obj && obj.processDefinitionId || null; this.status = obj && obj.status || null; this.taskName = obj && obj.taskName || null; @@ -125,15 +127,18 @@ export class ReportQuery { this.duration = obj && obj.duration || 0; this.dateRange = new ReportDateRange(obj); } + } export class ReportDateRange { startDate: string; endDate: string; + rangeId: string; constructor(obj?: any) { this.startDate = obj && obj.startDate || null; this.endDate = obj && obj.endDate || null; + this.rangeId = obj && obj.rangeId || null; } } diff --git a/ng2-components/ng2-activiti-analytics/src/services/analytics.service.ts b/ng2-components/ng2-activiti-analytics/src/services/analytics.service.ts index c1b3242e4d..50ac073941 100644 --- a/ng2-components/ng2-activiti-analytics/src/services/analytics.service.ts +++ b/ng2-components/ng2-activiti-analytics/src/services/analytics.service.ts @@ -184,6 +184,28 @@ export class AnalyticsService { }).catch(err => this.handleError(err)); } + exportReportToCsv(reportId: string, paramsQuery: any): Observable { + return Observable.fromPromise(this.apiService.getInstance().activiti.reportApi.exportToCsv(reportId, paramsQuery)) + .map((res: any) => { + this.logService.info('export'); + return res; + }).catch(err => this.handleError(err)); + } + + saveReport(reportId: string, paramsQuery: any): Observable { + return Observable.fromPromise(this.apiService.getInstance().activiti.reportApi.saveReport(reportId, paramsQuery)) + .map(() => { + this.logService.info('save'); + }).catch(err => this.handleError(err)); + } + + deleteReport(reportId: string): Observable { + return Observable.fromPromise(this.apiService.getInstance().activiti.reportApi.deleteReport(reportId)) + .map(() => { + this.logService.info('delete'); + }).catch(err => this.handleError(err)); + } + private handleError(error: Response) { this.logService.error(error); return Observable.throw(error.json().error || 'Server error');