[ADF-2650] Error with rootDir at insights folder fixed (#3215)

* [ADF-1939] Responsive button to edit reports

* [ADF-1939] Removed unused dependencies in material module

* [ADF-1939] Edit buttons now use flex layout

* [ADF-2650] Report action menu component created

* [ADF-2650] Added Button Model

* [ADF-2650] Buttons component finished

* [ADF-2650] Buttons menu component moved to core library

* [ADF-2650] Included index.ts in core/buttons-menu

* [ADF-2650] cleaned the module and public api file

* Revert "[ADF-2650] Included index.ts in core/buttons-menu"

This reverts commit 6bdf1f2f48a30bb4622eb4c000e5318370503710.

* [ADF-2650] Applied the peer review changes

* [ADF-2650] Comment removed

* [ADF-2650] Failing tests fixed

* [ADF-2650] Dynamic theming for analytic reports

* [ADF-2650] Themes not ap
This commit is contained in:
davidcanonieto 2018-04-26 14:56:05 +01:00 committed by Eugenio Romano
parent 2c0e7aa035
commit b2b3625929
21 changed files with 604 additions and 174 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

View File

@ -0,0 +1,90 @@
---
Added: v2.4.0
Status: Active
---
# Buttons Menu Component
Displays buttons on a responsive menu.
## Basic Usage
This component shows buttons on a responsive menu that changes depending on the device's screen.
```html
<adf-buttons-action-menu
[buttons]="buttons">
</adf-buttons-action-menu>
```
You will need to declare all the buttons that you want to have inside your menu in the parent component.
```ts
buttons: MenuButton[] = [];
setButtons() {
this.buttons = [
new MenuButton({
label: 'Settings',
icon: 'settings',
handler: this.settings.bind(this)
}),
new MenuButton({
label: 'Delete',
icon: 'delete',
handler: this.deleteItem.bind(this, this.reportId),
id: 'delete-button'
}),
new MenuButton({
label: 'Export',
icon: 'file_download',
handler: this.exportItem.bind(this),
id: 'export-button',
isVisible: this.isItemValid.bind(this)
}),
new MenuButton({
label: 'Save',
icon: 'save',
handler: this.saveItem.bind(this),
id: 'save-button',
isVisible: this.isItemValid.bind(this)
})
];
```
## Properties
####Buttons Menu Component
| Name | Type | Description |
| --- | --- | -- |
| buttons | `MenuButton []` | The array that contains all the buttons for the menu |
####Button Model
| Name | Type | Description |
| --- | --- | -- |
| label | `string` | Label to display for the button. |
| icon | `string` | Icon to display for the button. |
| handler | `function` | Callback for the event handler once the button is clicked. |
| styles | `string` | Classes to apply to the button. |
| id | `string` | Id of the button. |
| isVisible | `function` | Variable to define if button is visible or hidden. This function must return a boolean parameter. For instance, if it returns true the button will be visible. If it returns false the button will be hiden. |
## Details
This component uses [Angular Material](https://material.angular.io/) to style the menu.
Desktop view of the menu
![adf-buttons-menu-desktop](../docassets/images/adf-buttons-menu-desktop.png)
Mobile view of the menu
![adf-buttons-menu-mobile](../docassets/images/adf-buttons-menu-mobile.png)
Menu Button Model
## See also
- [Menu Button Model](./menu-button.model.md)

View File

@ -0,0 +1,27 @@
<div fxShow fxHide.xs="true" *ngIf="hasButtons()" id="adf-buttons-menu">
<ng-container *ngFor="let button of buttons">
<ng-container *ngTemplateOutlet="desktopMenu; context: button"></ng-container>
</ng-container>
</div>
<div fxHide fxShow.xs="true" *ngIf="hasButtons()" id="adf-buttons-menu">
<button mat-icon-button [matMenuTriggerFor]="editReportMenu">
<mat-icon>more_vert</mat-icon>
</button>
<mat-menu #editReportMenu="matMenu">
<ng-container *ngFor="let button of buttons">
<ng-container *ngTemplateOutlet="mobileMenu; context:button"></ng-container>
</ng-container>
</mat-menu>
</div>
<ng-template #desktopMenu let-handler="handler" let-icon="icon" let-label="label" let-styles="styles" let-id="id" let-isVisible="isVisible">
<button mat-button (click)="handler()" id="{{id}}" *ngIf="isVisible()" class="styles">
<mat-icon>{{icon}}</mat-icon>
</button>
</ng-template>
<ng-template #mobileMenu let-handler="handler" let-icon="icon" let-label="label" let-styles="styles" let-id="id" let-isVisible="isVisible">
<button mat-menu-item (click)="handler()" id="{{id}}" *ngIf="isVisible()" class="styles">
<mat-icon>{{icon}}</mat-icon><span>{{label | translate}}</span>
</button>
</ng-template>

View File

@ -0,0 +1,94 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { TestBed, async } from '@angular/core/testing';
import { ButtonsMenuComponent } from './buttons-menu.component';
import { MenuButton } from './menu-button.model';
import { MaterialModule } from '../material.module';
import { CoreTestingModule } from '../testing/core.testing.module';
/*tslint:disable:ban*/
fdescribe('ButtonsMenuComponent', () => {
let fixture;
let buttonsMenuComponent: ButtonsMenuComponent;
let element: HTMLElement;
beforeEach(async(() => {
TestBed.configureTestingModule({
imports: [
MaterialModule,
CoreTestingModule
]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(ButtonsMenuComponent);
element = fixture.nativeElement;
buttonsMenuComponent = <ButtonsMenuComponent> fixture.debugElement.componentInstance;
});
afterEach(() => {
fixture.destroy();
TestBed.resetTestingModule();
});
it('should hide buttons menu div if buttons input is empty', async(() => {
buttonsMenuComponent.buttons = [];
fixture.detectChanges();
fixture.whenStable().then(() => {
const buttonsMenuElement = element.querySelector('#adf-buttons-menu');
expect(buttonsMenuElement).toBeNull();
});
}));
it('should render buttons menu when there is at least one button declared in the buttons array', async(() => {
const button = new MenuButton({
label: 'button',
icon: 'button',
id: 'clickMe'
});
buttonsMenuComponent.buttons = [button];
fixture.detectChanges();
fixture.whenStable().then(() => {
const buttonsMenuElement = element.querySelector('#adf-buttons-menu');
expect(buttonsMenuElement).not.toBeNull();
expect(buttonsMenuElement).toBeDefined();
});
}));
it('should call the handler function when button is clicked', async(() => {
const button = new MenuButton({
label: 'button',
icon: 'button',
id: 'clickMe'
});
button.handler = jasmine.createSpy('handler');
buttonsMenuComponent.buttons = [button];
fixture.detectChanges();
fixture.whenStable().then(() => {
const buttonsMenuElement: HTMLButtonElement = <HTMLButtonElement> element.querySelector('#clickMe');
expect(buttonsMenuElement).not.toBeNull();
expect(buttonsMenuElement).toBeDefined();
buttonsMenuElement.click();
fixture.detectChanges();
expect(button.handler).toHaveBeenCalled();
});
}));
});

View File

@ -0,0 +1,38 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* tslint:disable:component-selector no-access-missing-member no-input-rename */
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
import { MenuButton } from './menu-button.model';
@Component({
selector: 'adf-buttons-action-menu',
templateUrl: './buttons-menu.component.html'
})
export class ButtonsMenuComponent implements OnChanges {
@Input() buttons: MenuButton[];
ngOnChanges(changes: SimpleChanges) {
this.buttons = changes['buttons'].currentValue;
}
hasButtons() {
return this.buttons.length > 0 ? true : false;
}
}

View File

@ -0,0 +1,39 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { TranslateModule } from '@ngx-translate/core';
import { MaterialModule } from '../material.module';
import { ButtonsMenuComponent } from './buttons-menu.component';
import { FlexLayoutModule } from '@angular/flex-layout';
@NgModule({
imports: [
CommonModule,
MaterialModule,
TranslateModule,
FlexLayoutModule
],
declarations: [
ButtonsMenuComponent
],
exports: [
ButtonsMenuComponent
]
})
export class ButtonsMenuModule {}

View File

@ -0,0 +1,18 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export * from './public-api';

View File

@ -0,0 +1,37 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export type VisibiltyFunction = (obj?: any) => boolean;
const defaultValidation = () => true;
export class MenuButton {
label: string;
icon: string;
handler: any;
styles: string;
id: string;
isVisible: VisibiltyFunction;
constructor(obj?: any) {
this.label = obj.label;
this.icon = obj.icon;
this.handler = obj.handler;
this.styles = obj.styles || null;
this.id = obj.id || null;
this.isVisible = obj.isVisible ? obj.isVisible : defaultValidation;
}
}

View File

@ -0,0 +1,20 @@
/*!
* @license
* Copyright 2016 Alfresco Software, Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export * from './buttons-menu.component';
export * from './menu-button.model';
export * from './buttons-menu.module';

View File

@ -40,6 +40,7 @@ import { FormModule } from './form/form.module';
import { SidenavLayoutModule } from './sidenav-layout/sidenav-layout.module';
import { SideBarActionModule } from './sidebar/sidebar-action.module';
import { CommentsModule } from './comments/comments.module';
import { ButtonsMenuModule } from './buttons-menu/buttons-menu.module';
import { DirectiveModule } from './directives/directive.module';
import { PipeModule } from './pipes/pipe.module';
@ -151,6 +152,7 @@ export function providers() {
InfoDrawerModule,
DataColumnModule,
DataTableModule,
ButtonsMenuModule,
TranslateModule.forChild({
loader: {
provide: TranslateLoader,
@ -185,7 +187,8 @@ export function providers() {
InfoDrawerModule,
DataColumnModule,
DataTableModule,
TranslateModule
TranslateModule,
ButtonsMenuModule
]
})
export class CoreModuleLazy {
@ -218,6 +221,7 @@ export class CoreModuleLazy {
InfoDrawerModule,
DataColumnModule,
DataTableModule,
ButtonsMenuModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
@ -252,7 +256,8 @@ export class CoreModuleLazy {
InfoDrawerModule,
DataColumnModule,
DataTableModule,
TranslateModule
TranslateModule,
ButtonsMenuModule
],
providers: [
...providers(),

View File

@ -33,6 +33,7 @@ export * from './app-config/index';
export * from './form/index';
export * from './sidenav-layout/index';
export * from './comments/index';
export * from './buttons-menu/index';
export * from './pipes/index';
export * from './services/index';

View File

@ -1,9 +1,11 @@
@import '../../../content-services/styles/index';
@import '../../../process-services/styles/index';
@import '../../../core/styles/index';
@import '../../../insights/styles/index';
@mixin alfresco-material-theme($theme) {
@include adf-content-services-theme($theme);
@include adf-process-services-theme($theme);
@include adf-core-theme($theme);
@include adf-insights-theme($theme);
}

View File

@ -24,7 +24,7 @@ import { MaterialModule } from '../material.module';
import { ChartsModule } from 'ng2-charts';
import { ToolbarModule } from '@alfresco/adf-core';
import { ToolbarModule, ButtonsMenuModule } from '@alfresco/adf-core';
import { AnalyticsGeneratorComponent } from './components/analytics-generator.component';
import { AnalyticsReportHeatMapComponent } from './components/analytics-report-heat-map.component';
import { AnalyticsReportListComponent } from './components/analytics-report-list.component';
@ -37,7 +37,10 @@ import { DropdownWidgetAanalyticsComponent } from './components/widgets/dropdown
import { DurationWidgetComponent } from './components/widgets/duration/duration.widget';
import { NumberWidgetAanlyticsComponent } from './components/widgets/number/number.widget';
import { AnalyticsService } from './services/analytics.service';
import { FlexLayoutModule } from '@angular/flex-layout';
@NgModule({
imports: [
@ -48,7 +51,9 @@ import { AnalyticsService } from './services/analytics.service';
DiagramsModule,
MaterialModule,
TranslateModule,
ToolbarModule
ToolbarModule,
FlexLayoutModule,
ButtonsMenuModule
],
declarations: [
AnalyticsComponent,

View File

@ -1,5 +1,8 @@
@mixin adf-analytics-report-list-theme($theme) {
$primary: map-get($theme, primary);
$accent: map-get($theme, accent );
$background: map-get($theme, background);
$foreground: map-get($theme, foreground);
.adf-analytics-report-list {
@ -43,7 +46,7 @@
position: relative;
min-height: 200px;
overflow: hidden;
background-color: #269abc;
background-color: mat-color($background, background);
display: flex;
flex-direction: column;
cursor: pointer;
@ -56,7 +59,7 @@
&-icon {
font-size: 70px;
color: #168aac;
color: mat-color($accent);
width: 1em;
height: 1em;
display: inline-block;
@ -79,16 +82,16 @@
}
&-actions {
border-top: 1px solid rgba(0,0,0,.1);
border-top: 1px solid mat-color($foreground, divider);
padding: 8px;
box-sizing: border-box;
height: 40px;
&-icon {
color: #e9f1f3;
color: mat-color($primary, 50);
&:hover {
color: #b7dfea;
color: mat-color($primary, 100);
}
}
}

View File

@ -24,27 +24,10 @@
<mat-icon class="adf-report-icon" >mode_edit</mat-icon>
<h4>{{reportParameters.name}}</h4>
</div>
</adf-toolbar-title>
<div *ngIf="!isEditable">
<button mat-button matTooltip="{{'ANALYTICS.MESSAGES.ICON-SETTING' | translate}}"
(click)="toggleParameters()">
<mat-icon>settings</mat-icon>
</button>
<button mat-button id="delete-button" (click)="deleteReport(reportId)"
matTooltip="{{'ANALYTICS.MESSAGES.ICON-DELETE' | translate}}">
<mat-icon>delete</mat-icon>
</button>
<span *ngIf="isFormValid()">
<button mat-button id="export-button" (click)="showDialog('Export')"
matTooltip="{{'ANALYTICS.MESSAGES.ICON-EXPORT-CSV' | translate}}">
<mat-icon>file_download</mat-icon>
</button>
<button mat-button id="save-button" (click)="showDialog('Save')"
matTooltip="{{'ANALYTICS.MESSAGES.ICON-SAVE' | translate}}">
<mat-icon>save</mat-icon>
</button>
</span>
</div>
</adf-toolbar-title>
<adf-buttons-action-menu *ngIf="!isEditable"
[buttons]="buttons">
</adf-buttons-action-menu>
</adf-toolbar>
<div *ngFor="let field of reportParameters.definition.parameters"
[class.is-hide]="isParametersHide()">
@ -136,4 +119,4 @@
</form>
</div>
</div>
</div>
</div>

View File

@ -1,103 +1,110 @@
.dropdown-widget {
width: 100%;
}
@mixin adf-analytics-report-parameters-theme($theme) {
$primary: map-get($theme, primary);
$accent: map-get($theme, accent);
$warn: map-get($theme, warn);
$foreground: map-get($theme, foreground);
$background: map-get($theme, background);
.dropdown-widget__select {
width: 100%;
}
.dropdown-widget__invalid .dropdown-widget__select {
border-color: #d50000;
}
.dropdown-widget__invalid .dropdown-widget__label {
color: #d50000;
}
.dropdown-widget__invalid .dropdown-widget__label:after {
background-color: #d50000;
}
.adf-edit-report-title {
float: left;
font-size: 20px!important;
padding-top: 19px;
}
.adf-report-icon {
float: left;
padding: 5px 5px 0 0;
visibility: hidden;
}
.adf-report-title-container {
cursor: pointer;
width: 100%;
margin-bottom: 12px;
:hover .adf-report-icon {
color: rgb(68, 138, 255);
visibility: visible;
}
}
.adf-report-title {
padding-top: 10px;
}
.adf-full-width-input {
width: 100%;
}
.is-hide {
height: 0;
overflow: hidden;
transition: height 0.5s;
}
.adf-report-report-container {
border-bottom: solid 1px rgb(212, 212, 212);
padding-top: 10px;
.mat-toolbar {
border: 0 !important;
padding: 0 !important;
}
}
.report-container-setting {
padding-left: 10px;
}
.option_button_details {
padding-top: 20px;
}
.export-message {
background-color: lightgray;
}
.save-export-input {
width: 100%;
}
.delete-parameter {
position: absolute;
margin-left: 60%;
padding-top: 5px;
}
.hide {
display: none;
}
.adf-report-dialog {
.mat-form-field {
.dropdown-widget {
width: 100%;
}
.mat-dialog-actions {
justify-content: flex-end;
.dropdown-widget__select {
width: 100%;
}
.dropdown-widget__invalid .dropdown-widget__select {
border-color: mat-color($warn);
}
.dropdown-widget__invalid .dropdown-widget__label {
color: mat-color($warn);
}
.dropdown-widget__invalid .dropdown-widget__label:after {
background-color: mat-color($warn);
}
.adf-edit-report-title {
float: left;
font-size: 20px!important;
padding-top: 19px;
}
.adf-report-icon {
float: left;
padding: 5px 5px 0 0;
visibility: hidden;
}
.adf-report-title-container {
cursor: pointer;
width: 100%;
margin-bottom: 12px;
:hover .adf-report-icon {
color: mat-color($primary);
visibility: visible;
}
}
.adf-report-title {
padding-top: 10px;
}
.adf-full-width-input {
width: 100%;
}
.is-hide {
height: 0;
overflow: hidden;
transition: height 0.5s;
}
.adf-report-report-container {
border-bottom: solid 1px mat-color($foreground, divider);
padding-top: 10px;
.mat-toolbar {
border: 0 !important;
padding: 0 !important;
}
}
.report-container-setting {
padding-left: 10px;
}
.option_button_details {
padding-top: 20px;
}
.export-message {
background-color: mat-color($background, background);
}
.save-export-input {
width: 100%;
}
.delete-parameter {
position: absolute;
margin-left: 60%;
padding-top: 5px;
}
.hide {
display: none;
}
.adf-report-dialog {
.mat-form-field {
width: 100%;
}
.mat-dialog-actions {
justify-content: flex-end;
}
}
}

View File

@ -30,6 +30,7 @@ describe('AnalyticsReportParametersComponent', () => {
let component: AnalyticsReportParametersComponent;
let fixture: ComponentFixture<AnalyticsReportParametersComponent>;
let element: HTMLElement;
let validForm = false;
setupTestBed({
imports: [InsightsTestingModule]
@ -39,6 +40,9 @@ describe('AnalyticsReportParametersComponent', () => {
fixture = TestBed.createComponent(AnalyticsReportParametersComponent);
component = fixture.componentInstance;
element = fixture.nativeElement;
spyOn(component, 'isFormValid').and.callFake(() => {
return validForm;
});
fixture.detectChanges();
});
@ -393,7 +397,7 @@ describe('AnalyticsReportParametersComponent', () => {
});
describe('When the form is rendered correctly', () => {
let validForm: boolean = true;
let values: any = {
dateRange: {
startDate: '2016-09-01', endDate: '2016-10-05'
@ -435,18 +439,10 @@ describe('AnalyticsReportParametersComponent', () => {
fixture.whenStable().then(() => {
component.toggleParameters();
component.reportId = '1';
spyOn(component, 'isFormValid').and.callFake(() => {
return validForm;
});
fixture.detectChanges();
});
}));
afterEach(() => {
validForm = true;
});
it('Should be able to change the report title', (done) => {
let title: HTMLElement = element.querySelector('h4');
@ -546,50 +542,77 @@ describe('AnalyticsReportParametersComponent', () => {
});
}));
it('Should raise an event for report deleted', async(() => {
let deleteButton: HTMLButtonElement = <HTMLButtonElement> element.querySelector('#delete-button');
expect(deleteButton).toBeDefined();
expect(deleteButton).not.toBeNull();
component.deleteReportSuccess.subscribe((reportId) => {
expect(reportId).not.toBeNull();
it('should render adf-buttons-menu component', async(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
const buttonsMenuComponent = element.querySelector('adf-buttons-action-menu');
expect(buttonsMenuComponent).not.toBeNull();
expect(buttonsMenuComponent).toBeDefined();
});
}));
deleteButton.click();
it('should render delete button', async(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
const buttonsMenuComponent = element.querySelector('#delete-button');
expect(buttonsMenuComponent).not.toBeNull();
expect(buttonsMenuComponent).toBeDefined();
});
}));
jasmine.Ajax.requests.mostRecent().respondWith({
status: 200,
contentType: 'json'
it('Should raise an event for report deleted', async(() => {
fixture.detectChanges();
fixture.whenStable().then(() => {
let deleteButton = fixture.debugElement.nativeElement.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'
});
});
}));
it('Should hide export button if the form is not valid', async(() => {
let exportButton: HTMLButtonElement = <HTMLButtonElement> element.querySelector('#export-button');
expect(exportButton).toBeDefined();
expect(exportButton).not.toBeNull();
validForm = false;
validForm = true;
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
exportButton = <HTMLButtonElement> element.querySelector('#export-button');
expect(exportButton).toBeNull();
let exportButton = fixture.debugElement.nativeElement.querySelector('#export-button');
expect(exportButton).toBeDefined();
expect(exportButton).not.toBeNull();
validForm = false;
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
exportButton = fixture.debugElement.nativeElement.querySelector('#export-button');
expect(exportButton).toBeNull();
});
});
}));
it('Should hide save button if the form is not valid', async(() => {
let saveButton: HTMLButtonElement = <HTMLButtonElement> element.querySelector('#save-button');
expect(saveButton).toBeDefined();
expect(saveButton).not.toBeNull();
validForm = false;
validForm = true;
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
saveButton = <HTMLButtonElement> element.querySelector('#save-button');
expect(saveButton).toBeNull();
let saveButton = fixture.debugElement.nativeElement.querySelector('#save-button');
expect(saveButton).toBeDefined();
expect(saveButton).not.toBeNull();
validForm = false;
fixture.detectChanges();
fixture.whenStable().then(() => {
fixture.detectChanges();
saveButton = fixture.debugElement.nativeElement.querySelector('#save-button');
expect(saveButton).toBeNull();
});
});
}));
@ -615,6 +638,5 @@ describe('AnalyticsReportParametersComponent', () => {
});
}));
});
});
});

View File

@ -15,7 +15,7 @@
* limitations under the License.
*/
import { ContentService, LogService } from '@alfresco/adf-core';
import { ContentService, LogService, MenuButton } from '@alfresco/adf-core';
import {
AfterContentChecked,
Component,
@ -38,6 +38,8 @@ import { ReportParametersModel } from '../../diagram/models/report/reportParamet
import { ReportQuery } from '../../diagram/models/report/reportQuery.model';
import { AnalyticsService } from '../services/analytics.service';
// @deprecated 2.3.0 analytics-report-parameters tag removed
@Component({
selector: 'adf-analytics-report-parameters, analytics-report-parameters',
@ -95,6 +97,8 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges, On
reportName: string;
buttons: MenuButton[] = [];
private dropDownSub;
private reportParamsSub;
private paramOpts;
@ -107,6 +111,7 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges, On
private logService: LogService,
private contentService: ContentService,
private dialog: MatDialog) {
}
ngOnInit() {
@ -130,9 +135,12 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges, On
if (this.reportForm) {
this.reportForm.reset();
}
let reportId = changes['reportId'];
if (reportId && reportId.currentValue) {
this.reportId = reportId.currentValue;
this.getReportParams(reportId.currentValue);
this.setButtons();
}
let appId = changes['appId'];
@ -145,7 +153,7 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges, On
let formBuilderGroup: any = {};
parameters.forEach((param: ReportParameterDetailsModel) => {
switch (param.type) {
case 'dateRange' :
case 'dateRange':
formBuilderGroup.dateRange = new FormGroup({}, Validators.required);
break;
case 'processDefinition':
@ -348,10 +356,6 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges, On
return this.action === 'Save';
}
isFormValid() {
return this.reportForm && this.reportForm.dirty && this.reportForm.valid;
}
doExport(paramQuery: ReportQuery) {
this.analyticsService.exportReportToCsv(this.reportId, paramQuery).subscribe(
(data: any) => {
@ -385,4 +389,38 @@ export class AnalyticsReportParametersComponent implements OnInit, OnChanges, On
isParametersHide() {
return this.hideParameters;
}
isFormValid() {
return this.reportForm && this.reportForm.dirty && this.reportForm.valid;
}
setButtons() {
this.buttons = [
new MenuButton({
label: 'ANALYTICS.MESSAGES.ICON-SETTING',
icon: 'settings',
handler: this.toggleParameters.bind(this)
}),
new MenuButton({
label: 'ANALYTICS.MESSAGES.ICON-DELETE',
icon: 'delete',
handler: this.deleteReport.bind(this, this.reportId),
id: 'delete-button'
}),
new MenuButton({
label: 'ANALYTICS.MESSAGES.ICON-EXPORT-CSV',
icon: 'file_download',
handler: this.showDialog.bind(this, 'Export'),
id: 'export-button',
isVisible: this.isFormValid.bind(this)
}),
new MenuButton({
label: 'ANALYTICS.MESSAGES.ICON-SAVE',
icon: 'save',
handler: this.showDialog.bind(this, 'Save'),
id: 'save-button',
isVisible: this.isFormValid.bind(this)
})
];
}
}

View File

@ -21,7 +21,7 @@ import {
MatChipsModule, MatDatepickerModule, MatDialogModule, MatGridListModule, MatIconModule,
MatInputModule, MatListModule, MatNativeDateModule, MatOptionModule, MatProgressSpinnerModule, MatRadioModule,
MatRippleModule, MatSelectModule, MatSlideToggleModule, MatTableModule, MatTabsModule,
MatTooltipModule
MatTooltipModule, MatMenuModule
} from '@angular/material';
export function modules() {
@ -30,7 +30,7 @@ export function modules() {
MatCheckboxModule, MatDatepickerModule, MatGridListModule, MatIconModule, MatInputModule,
MatListModule, MatOptionModule, MatRadioModule, MatSelectModule, MatSlideToggleModule, MatTableModule,
MatTabsModule, MatProgressSpinnerModule, MatNativeDateModule, MatRippleModule, MatTooltipModule,
MatChipsModule
MatChipsModule, MatMenuModule
];
}

View File

@ -1,5 +1,5 @@
@import '../diagram/components/tooltip/diagram-tooltip.component';
@import '../analytics-process/components/analytics-report-parameters.component';
@import '../analytics-process/components/analytics-report-list.component';
@import '../analytics-process/components/widgets/date-range/date-range.widget';
@ -7,4 +7,5 @@
@include adf-diagram-tooltip-theme($theme);
@include adf-analytics-report-list-theme($theme);
@include adf-analytics-date-range-widget-theme($theme);
@include adf-analytics-report-parameters-theme($theme);
}