Custom Filter Component (#1823)

* Add Accordion component

* Add property to hide icon

* Use accordion component in demo shell

* Add basic doc

* Add adf prefix

* Add element id and change unit test
This commit is contained in:
Maurizio Vitale
2017-04-21 10:26:59 +01:00
committed by Mario Romano
parent 0e4dab8b66
commit 1de625d960
18 changed files with 442 additions and 14 deletions

View File

@@ -248,6 +248,25 @@ If both `appId` and `appName` are specified then `appName` will take precedence
| `onError` | Emitted when an error occurs |
| `ilterClick` | Emitted when the user selects a filter from the list |
### How to create an accordion menu with the processes filter
You can create an accordion menu using the AccordionComponent that wrap the activiti task filter.
The AccordionComponent is exposed by the alfresco-core.
```html
<accordion>
<accordion-group [heading]="'Processes'" [isSelected]="true" [headingIcon]="'assessment'">
<activiti-process-instance-filters
[appId]="appId"
(filterClick)="onProcessFilterClick($event)"
(onSuccess)="onSuccessProcessFilterList($event)">
</activiti-process-instance-filters>
</accordion-group>
</accordion>
```
![how-create-accordion-menu](docs/assets/how-to-create-accordion-menu.png)
### Start Process Button component
Displays a button which in turn displays a dialog when clicked, allowing the user

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

View File

@@ -14,6 +14,10 @@
color: rgb(68,138,255);
}
.activiti-filters__entry:hover {
opacity: 0.8;
}
.activiti-filters__entry.active .activiti-filters__entry-icon {
color: rgb(68,138,255);
}
}

View File

@@ -211,11 +211,12 @@ Here's the list of available properties you can define for a Data Column definit
### Properties
| Name | Description |
| --- | --- |
| --- | --- | --- | --- |
|`appId`| { string } The id of the app. |
|`processDefinitionKey`| { string } The processDefinitionKey of the process. |
|`assignment`| { string } The assignment of the process. <ul>Possible values are: <li>assignee : where the current user is the assignee</li> <li>candidate: where the current user is a task candidate </li><li>group_x: where the task is assigned to a group where the current user is a member of.</li> <li>no value: where the current user is involved</li> </ul> |
|`state`| { string } Define state of the processes. Possible values are: completed, active |
|`hasIcon` | boolean | true | Show/Hide the icon on the left . |
|`landingTaskId`| { string } Define which task id should be selected after the reloading. If the task id doesn't exist or nothing is passed it will select the first task |
|`sort`| { string } Define the sort of the processes. Possible values are : created-desc, created-asc, due-desc, due-asc |
| `data` | { DataTableAdapter } (optional) JSON object that represent the number and the type of the columns that you want show |
@@ -354,6 +355,27 @@ The component shows all the available filters.
No options
### How to create an accordion menu with the task filter
You can create an accordion menu using the AccordionComponent that wrap the activiti task filter.
The AccordionComponent is exposed by the alfresco-core.
```html
<accordion>
<accordion-group [heading]="'Tasks'" [isSelected]="true" [headingIcon]="'assignment'">
<activiti-filters
[appId]="appId"
[hasIcon]="false"
(filterClick)="onTaskFilterClick($event)"
(onSuccess)="onSuccessTaskFilterList($event)"
#activitifilter>
</activiti-filters>
</accordion-group>
</accordion>
```
![how-create-accordion-menu](docs/assets/how-to-create-accordion-menu.png)
## Basic usage example Activiti Checklist
The component shows the checklist task functionality.

Binary file not shown.

After

Width:  |  Height:  |  Size: 84 KiB

View File

@@ -14,6 +14,10 @@
color: rgb(68,138,255);
}
.activiti-filters__entry:hover {
opacity: 0.8;
}
.activiti-filters__entry.active .activiti-filters__entry-icon {
color: rgb(68,138,255);
}

View File

@@ -3,7 +3,7 @@
<li class="mdl-list__item activiti-filters__entry" (click)="selectFilter(filter)" *ngFor="let filter of filters"
[class.active]="currentFilter === filter">
<span class="mdl-list__item-primary-content">
<i class="material-icons mdl-list__item-icon activiti-filters__entry-icon" [attr.data-automation-id]="filter.name + '_filter'" >assignment</i>
<i *ngIf="hasIcon" class="material-icons mdl-list__item-icon activiti-filters__entry-icon" [attr.data-automation-id]="filter.name + '_filter'" >assignment</i>
{{filter.name}}
</span>
</li>

View File

@@ -47,6 +47,9 @@ export class ActivitiFilters implements OnInit, OnChanges {
@Input()
appName: string;
@Input()
hasIcon: boolean = true;
private filterObserver: Observer<FilterRepresentationModel>;
filter$: Observable<FilterRepresentationModel>;

View File

@@ -45,11 +45,13 @@ import { DataColumnComponent } from './src/components/data-column/data-column.co
import { DataColumnListComponent } from './src/components/data-column/data-column-list.component';
import { MATERIAL_DESIGN_DIRECTIVES } from './src/components/material/index';
import { CONTEXT_MENU_PROVIDERS, CONTEXT_MENU_DIRECTIVES } from './src/components/context-menu/index';
import { COLLAPSABLE_DIRECTIVES } from './src/components/collapsable/index';
export * from './src/services/index';
export * from './src/components/index';
export * from './src/components/data-column/data-column.component';
export * from './src/components/data-column/data-column-list.component';
export * from './src/components/collapsable/index';
export * from './src/directives/upload.directive';
export * from './src/utils/index';
export * from './src/events/base.event';
@@ -94,6 +96,7 @@ export function createTranslateLoader(http: Http, logService: LogService) {
declarations: [
...MATERIAL_DESIGN_DIRECTIVES,
...CONTEXT_MENU_DIRECTIVES,
...COLLAPSABLE_DIRECTIVES,
UploadDirective,
DataColumnComponent,
DataColumnListComponent
@@ -110,6 +113,7 @@ export function createTranslateLoader(http: Http, logService: LogService) {
TranslateModule,
...MATERIAL_DESIGN_DIRECTIVES,
...CONTEXT_MENU_DIRECTIVES,
...COLLAPSABLE_DIRECTIVES,
UploadDirective,
DataColumnComponent,
DataColumnListComponent

View File

@@ -0,0 +1,35 @@
.adf-panel-heading {
float: left;
font-size: 14px;
font-weight: bold;
font-style: normal;
font-stretch: normal;
line-height: normal;
letter-spacing: normal;
text-align: left;
color: #000000;
width: 100%;
}
.adf-panel-heading-selected {
color: #448aff;
}
.adf-panel-heading-icon {
float: left;
}
.adf-panel-heading-text {
float: left;
padding-left: 20px;
padding-top: 4px;
}
.adf-panel-heading-toggle {
float: right;
cursor: pointer;
}
.adf-panel-heading-toggle:hover {
opacity: 0.4;
}

View File

@@ -0,0 +1,16 @@
<div class="adf-panel adf-panel-default" [ngClass]="{'adf-panel-open': isOpen}">
<div class="adf-panel-heading" [ngClass]="{'adf-panel-heading-selected': isSelected}">
<div *ngIf="hasHeadingIcon()" class="adf-panel-heading-icon">
<i class="material-icons">{{headingIcon}}</i>
</div>
<div class="adf-panel-heading-text">{{heading}}</div>
<div id="accordion-button" class="adf-panel-heading-toggle" (click)="toggleOpen($event)">
<i class="material-icons">{{getAccordionIcon()}}</i>
</div>
</div>
<div class="adf-panel-collapse" [hidden]="!isOpen">
<div class="adf-panel-body">
<ng-content></ng-content>
</div>
</div>
</div>

View File

@@ -0,0 +1,76 @@
/*!
* @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 { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { AccordionComponent } from './accordion.component';
import { AccordionGroupComponent } from './accordion-group.component';
describe('AccordionGroupComponent', () => {
let fixture: ComponentFixture<AccordionGroupComponent>;
let component: AccordionGroupComponent;
let element: any;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
AccordionGroupComponent
],
providers: [AccordionComponent]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AccordionGroupComponent);
element = fixture.nativeElement;
component = fixture.componentInstance;
});
it('should be closed by default', () => {
component.heading = 'Fake Header';
component.headingIcon = 'fake-icon';
fixture.whenStable().then(() => {
fixture.detectChanges();
let headerToggle = fixture.nativeElement.querySelector('.adf-panel-heading-toggle .material-icons');
expect(headerToggle.innerText).toEqual('expand_more');
let headerText = fixture.nativeElement.querySelector('.adf-panel-heading-text');
expect(headerText.innerText).toEqual('Fake Header');
let headerIcon = fixture.nativeElement.querySelector('.adf-panel-heading-icon .material-icons');
expect(headerIcon.innerText).toEqual('fake-icon');
});
});
it('should be open when click', () => {
component.isSelected = true;
component.heading = 'Fake Header';
component.headingIcon = 'fake-icon';
fixture.detectChanges();
element.querySelector('#accordion-button').click();
fixture.whenStable().then(() => {
fixture.detectChanges();
let headerText = fixture.nativeElement.querySelector('.adf-panel-heading-text');
expect(headerText.innerText).toEqual('Fake Header');
let headerIcon = fixture.nativeElement.querySelector('.adf-panel-heading-icon .material-icons');
expect(headerIcon.innerText).toEqual('fake-icon');
let headerToggle = fixture.nativeElement.querySelector('.adf-panel-heading-toggle .material-icons');
expect(headerToggle.innerText).toEqual('expand_less');
});
});
});

View File

@@ -0,0 +1,79 @@
/*!
* @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 { Component, Input, OnDestroy } from '@angular/core';
import { AccordionComponent } from './accordion.component';
@Component({
selector: 'accordion-group',
moduleId: module.id,
templateUrl: 'accordion-group.component.html',
styleUrls: ['./accordion-group.component.css']
})
export class AccordionGroupComponent implements OnDestroy {
private _isOpen: boolean = false;
private _isSelected: boolean = false;
@Input()
heading: string;
@Input()
headingIcon: string;
@Input()
set isOpen(value: boolean) {
this._isOpen = value;
if (value) {
this.accordion.closeOthers(this);
}
}
get isOpen() {
return this._isOpen;
}
@Input()
set isSelected(value: boolean) {
this._isSelected = value;
}
get isSelected() {
return this._isSelected;
}
constructor(private accordion: AccordionComponent) {
this.accordion.addGroup(this);
}
ngOnDestroy() {
this.accordion.removeGroup(this);
}
hasHeadingIcon() {
return this.headingIcon ? true : false;
}
toggleOpen(event: MouseEvent): void {
event.preventDefault();
this.isOpen = !this.isOpen;
}
getAccordionIcon(): string {
return this.isOpen ? 'expand_less' : 'expand_more';
}
}

View File

@@ -0,0 +1,81 @@
/*!
* @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 { ComponentFixture, TestBed, async } from '@angular/core/testing';
import { AccordionComponent } from './accordion.component';
import { AccordionGroupComponent } from './accordion-group.component';
describe('AccordionComponent', () => {
let fixture: ComponentFixture<AccordionComponent>;
let component: AccordionComponent;
let componentGroup1: AccordionGroupComponent;
let componentGroup2: AccordionGroupComponent;
let componentGroup3: AccordionGroupComponent;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
AccordionComponent
]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(AccordionComponent);
component = fixture.componentInstance;
});
afterEach(() => {
component.groups = [];
});
it('should create the component', () => {
expect(component).toBeTruthy();
});
it('should add the AccordionGroup', () => {
component.addGroup(componentGroup1);
expect(component.groups.length).toBe(1);
});
it('should close all the other group', () => {
componentGroup1 = new AccordionGroupComponent(component);
componentGroup2 = new AccordionGroupComponent(component);
componentGroup3 = new AccordionGroupComponent(component);
componentGroup1.isOpen = false;
componentGroup2.isOpen = true;
componentGroup3.isOpen = false;
expect(component.groups[0].isOpen).toBeFalsy();
expect(component.groups[1].isOpen).toBeTruthy();
expect(component.groups[2].isOpen).toBeFalsy();
componentGroup1.isOpen = true;
expect(component.groups[0].isOpen).toBeTruthy();
expect(component.groups[1].isOpen).toBeFalsy();
expect(component.groups[2].isOpen).toBeFalsy();
});
it('should remove the AccordionGroup', () => {
component.addGroup(componentGroup1);
component.removeGroup(componentGroup1);
expect(component.groups.length).toBe(0);
});
});

View File

@@ -0,0 +1,51 @@
/*!
* @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 { Component } from '@angular/core';
import { AccordionGroupComponent } from './accordion-group.component';
@Component({
selector: 'accordion',
template: `
<ng-content></ng-content>
`,
host: {
'class': 'panel-group'
}
})
export class AccordionComponent {
groups: Array<AccordionGroupComponent> = [];
addGroup(group: AccordionGroupComponent): void {
this.groups.push(group);
}
closeOthers(openGroup: AccordionGroupComponent): void {
this.groups.forEach((group: AccordionGroupComponent) => {
if (group !== openGroup) {
group.isOpen = false;
}
});
}
removeGroup(group: AccordionGroupComponent): void {
const index = this.groups.indexOf(group);
if (index !== -1) {
this.groups.splice(index, 1);
}
}
}

View File

@@ -0,0 +1,24 @@
/*!
* @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 {AccordionComponent} from './accordion.component';
import {AccordionGroupComponent} from './accordion-group.component';
export const COLLAPSABLE_DIRECTIVES: [any] = [
AccordionComponent,
AccordionGroupComponent
];

View File

@@ -17,3 +17,4 @@
export * from './context-menu/index';
export * from './material/index';
export * from './collapsable/index';