[ADF-459] Copy & move further features (#2187)

* Adding current folder to list by default

* Fix documentlist component's rowFilter and imageResolver

* Adding rowfilter to not show the current node in the list

* Removing unpermitted nodes from the selectable ones (not visually)

* Restore documentlist original behaviour (rowFilter and imageResolver)

* Select event interface works with array from this point on

* Introducing the one and only, mighty Breadcrumb

* Breadcrumb position fix

* Extract hightlight transform functionality from highlight pipe

* Highlight part I.

* Showing breadcrumb with the new redesigned functionality

* Rebase fix

* Error and success callback for the new content actions

* Tests for HighlightDirective

* Update documentation

* Until proper pagination we use this temporary fix

* Fix node unselection on folder change

* Fix accessibility support in dropdown breadcrumb
This commit is contained in:
Popovics András
2017-08-08 16:41:20 +01:00
committed by Mario Romano
parent a8024bbdf5
commit e93a771366
24 changed files with 793 additions and 184 deletions

View File

@@ -52,12 +52,15 @@ import { TranslationService } from './src/services/translation.service';
import { UploadService } from './src/services/upload.service';
import { UserPreferencesService } from './src/services/user-preferences.service';
import { HighlightDirective } from './src/directives/highlight.directive';
import { DeletedNodesApiService } from './src/services/deleted-nodes-api.service';
import { DiscoveryApiService } from './src/services/discovery-api.service';
import { FavoritesApiService } from './src/services/favorites-api.service';
import { HighlightTransformService } from './src/services/highlight-transform.service';
import { NodesApiService } from './src/services/nodes-api.service';
import { PeopleApiService } from './src/services/people-api.service';
import { SearchApiService } from './src/services/search-api.service';
import { SearchService } from './src/services/search.service';
import { SharedLinksApiService } from './src/services/shared-links-api.service';
import { SitesApiService } from './src/services/sites-api.service';
@@ -89,7 +92,7 @@ export { UpdateNotification } from './src/services/card-view-update.service';
export { ClickNotification } from './src/services/card-view-update.service';
export { AppConfigModule } from './src/services/app-config.service';
export { UserPreferencesService } from './src/services/user-preferences.service';
import { SearchService } from './src/services/search.service';
export { HighlightTransformService, HightlightTransformResult } from './src/services/highlight-transform.service';
export { DeletedNodesApiService } from './src/services/deleted-nodes-api.service';
export { FavoritesApiService } from './src/services/favorites-api.service';
@@ -121,6 +124,7 @@ export { CardViewItem } from './src/interface/card-view-item.interface';
export * from './src/components/data-column/data-column.component';
export * from './src/components/data-column/data-column-list.component';
export * from './src/directives/upload.directive';
export * from './src/directives/highlight.directive';
export * from './src/utils/index';
export * from './src/events/base.event';
export * from './src/events/base-ui.event';
@@ -171,7 +175,8 @@ export function providers() {
SearchApiService,
SharedLinksApiService,
SitesApiService,
DiscoveryApiService
DiscoveryApiService,
HighlightTransformService
];
}
@@ -220,6 +225,7 @@ export function createTranslateLoader(http: Http, logService: LogService) {
...obsoleteMdlDirectives(),
UploadDirective,
NodePermissionDirective,
HighlightDirective,
DataColumnComponent,
DataColumnListComponent,
FileSizePipe,
@@ -243,6 +249,7 @@ export function createTranslateLoader(http: Http, logService: LogService) {
...obsoleteMdlDirectives(),
UploadDirective,
NodePermissionDirective,
HighlightDirective,
DataColumnComponent,
DataColumnListComponent,
FileSizePipe,

View File

@@ -0,0 +1,125 @@
/*!
* @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, ViewChildren } from '@angular/core';
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { HighlightTransformService } from '../services/highlight-transform.service';
import { HighlightDirective } from './highlight.directive';
const template: string = `
<div id="outerDiv1" adf-highlight adf-highlight-selector=".highlightable" adf-highlight-class="highlight-for-free-willy">
<div id="innerDiv11" class="highlightable">Lorem ipsum salana-eyong-aysis dolor sit amet</div>
<div id="innerDiv12">Lorem ipsum salana-eyong-aysis dolor sit amet</div>
<div id="innerDiv13" class="highlightable">consectetur adipiscing elit</div>
<div id="innerDiv14" class="highlightable">sed do eiusmod salana-eyong-aysis tempor incididunt</div>
</div>
<div id="outerDiv2" adf-highlight adf-highlight-selector=".highlightable">
<div id="innerDiv21" class="highlightable">Lorem ipsum salana-eyong-aysis dolor sit amet</div>
</div>`;
@Component({ selector: 'adf-test-component', template })
class TestComponent {
@ViewChildren(HighlightDirective) public hightlightDirectives;
}
describe('HighlightDirective', () => {
let fixture: ComponentFixture<TestComponent>;
let component: TestComponent;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [
HighlightDirective,
TestComponent
],
providers: [
HighlightTransformService
]
}).compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(TestComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should replace the searched text with the default hightlight class in the proper element (adf-highlight-selector)', () => {
component.hightlightDirectives.last.highlight('salana-eyong-aysis');
fixture.detectChanges();
const containerElement = fixture.debugElement.query(By.css('#innerDiv21'));
expect(containerElement).not.toBeNull();
expect(containerElement.nativeElement.innerHTML).toBe('Lorem ipsum <span class="adf-highlight">salana-eyong-aysis</span> dolor sit amet');
});
it('should replace the searched text with the default hightlight class in every proper element (highlight-for-free-willy)', () => {
component.hightlightDirectives.first.highlight('salana-eyong-aysis');
fixture.detectChanges();
const containerElement1 = fixture.debugElement.query(By.css('#innerDiv11'));
const containerElement2 = fixture.debugElement.query(By.css('#innerDiv14'));
expect(containerElement1).not.toBeNull();
expect(containerElement2).not.toBeNull();
expect(containerElement1.nativeElement.innerHTML).toBe('Lorem ipsum <span class="highlight-for-free-willy">salana-eyong-aysis</span> dolor sit amet');
expect(containerElement2.nativeElement.innerHTML).toBe('sed do eiusmod <span class="highlight-for-free-willy">salana-eyong-aysis</span> tempor incididunt');
});
it('should NOT replace the searched text in an element without the proper selector class', () => {
component.hightlightDirectives.first.highlight('salana-eyong-aysis');
fixture.detectChanges();
const containerElement1 = fixture.debugElement.query(By.css('#innerDiv12'));
expect(containerElement1).not.toBeNull();
expect(containerElement1.nativeElement.innerHTML).toBe('Lorem ipsum salana-eyong-aysis dolor sit amet');
});
it('should NOT reinsert the same text to the innerText if there was no change at all (search string is not found)', () => {
const highlighter = TestBed.get(HighlightTransformService);
spyOn(highlighter, 'highlight').and.returnValue({ changed: false, text: 'Modified text' });
component.hightlightDirectives.first.highlight('salana-eyong-aysis');
fixture.detectChanges();
const containerElement = fixture.debugElement.query(By.css('#innerDiv11'));
expect(containerElement).not.toBeNull();
expect(containerElement.nativeElement.innerHTML).not.toContain('Modified text');
});
it('should do the search only if there is a search string presented', () => {
const highlighter = TestBed.get(HighlightTransformService);
spyOn(highlighter, 'highlight').and.callThrough();
component.hightlightDirectives.first.highlight('');
fixture.detectChanges();
expect(highlighter.highlight).not.toHaveBeenCalled();
});
it('should do the search only if there is a node selector string presented', () => {
const highlighter = TestBed.get(HighlightTransformService);
spyOn(highlighter, 'highlight').and.callThrough();
const callback = function() {
component.hightlightDirectives.first.highlight('raddish', '');
fixture.detectChanges();
};
expect(callback).not.toThrowError();
expect(highlighter.highlight).not.toHaveBeenCalled();
});
});

View File

@@ -0,0 +1,52 @@
/*!
* @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 { Directive, ElementRef, Input, Renderer } from '@angular/core';
import { HighlightTransformService, HightlightTransformResult } from '../services/highlight-transform.service';
@Directive({
selector: '[adf-highlight]'
})
export class HighlightDirective {
@Input('adf-highlight-selector')
selector: string = '';
@Input('adf-highlight')
search: string = '';
@Input('adf-highlight-class')
classToApply: string = 'adf-highlight';
constructor(
private el: ElementRef,
private renderer: Renderer,
private highlightTransformService: HighlightTransformService) { }
public highlight(search = this.search, selector = this.selector, classToApply = this.classToApply) {
if (search && selector) {
const elements = this.el.nativeElement.querySelectorAll(selector);
elements.forEach((element) => {
const result: HightlightTransformResult = this.highlightTransformService.highlight(element.innerHTML, search, classToApply);
if (result.changed) {
this.renderer.setElementProperty(element, 'innerHTML', result.text);
}
});
}
}
}

View File

@@ -16,25 +16,17 @@
*/
import { Pipe, PipeTransform } from '@angular/core';
import { HighlightTransformService, HightlightTransformResult } from '../services/highlight-transform.service';
@Pipe({
name: 'highlight'
})
export class HighlightPipe implements PipeTransform {
constructor() { }
constructor(private highlightTransformService: HighlightTransformService) { }
transform(text: string, search: string): any {
if (search && text) {
let pattern = search.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
pattern = pattern.split(' ').filter((t) => {
return t.length > 0;
}).join('|');
const regex = new RegExp(pattern, 'gi');
let result = text.replace(regex, (match) => `<span class="highlight">${match}</span>`);
return result;
} else {
return text;
}
transform(text: string, search: string): string {
const result: HightlightTransformResult = this.highlightTransformService.highlight(text, search);
return result.text;
}
}

View File

@@ -0,0 +1,44 @@
/*!
* @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 interface HightlightTransformResult {
text: string;
changed: boolean;
}
export class HighlightTransformService {
public highlight(text: string, search: string, wrapperClass: string = 'highlight'): HightlightTransformResult {
let isMatching = false,
result = text;
if (search && text) {
let pattern = search.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
pattern = pattern.split(' ').filter((t) => {
return t.length > 0;
}).join('|');
const regex = new RegExp(pattern, 'gi');
result = text.replace(regex, (match) => {
isMatching = true;
return `<span class="${wrapperClass}">${match}</span>`;
});
return { text: result, changed: isMatching};
} else {
return { text: result, changed: isMatching};
}
}
}