Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AAE-4428] Add selected file counter to attach file widget #6881

Merged
merged 12 commits into from
Apr 15, 2021
28 changes: 28 additions & 0 deletions docs/content-services/directives/node-counter.directive.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
Title: Node Counter directive
Added: v4.4.0
Status: Active
Last reviewed: 2021-04-15
---

# [Node Counter directive](../../../lib/content-services/src/lib/directives/node-counter.directive.ts "Defined in node-counter.directive.ts")

Appends a counter to an element.

## Basic Usage

```html
<adf-toolbar>
<adf-toolbar-title [adf-node-counter]="getSelectedCount()">
...
</adf-toolbar-title>
</adf-toolbar>
```

## Class members

### Properties

| Name | Type | Default value | Description |
| ---- | ---- | ------------- | ----------- |
| counter | `number` | | Number of nodes selected. |
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
</adf-search-panel>
<div class="adf-content-node-selector-document-list-container">
<adf-toolbar>
<adf-toolbar-title>
<adf-toolbar-title [adf-node-counter]="getSelectedCount()">
<ng-container *ngIf="!showBreadcrumbs()">
<span role="heading" aria-level="3" class="adf-search-results-label">{{ 'NODE_SELECTOR.SEARCH_RESULTS' | translate }}</span>
</ng-container>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@ describe('ContentNodeSelectorPanelComponent', () => {
beforeEach(() => {
const documentListService = TestBed.inject(DocumentListService);
const expectedDefaultFolderNode = <NodeEntry> { entry: { path: { elements: [] } } };
component.isSelectionValid = (node: Node) => node.isFile;

spyOn(documentListService, 'getFolderNode').and.returnValue(of(expectedDefaultFolderNode));
spyOn(documentListService, 'getFolder').and.returnValue(of({
Expand Down Expand Up @@ -1026,6 +1027,14 @@ describe('ContentNodeSelectorPanelComponent', () => {
spyOn(sitesService, 'getSites').and.returnValue(of({ list: { entries: [] } }));
});

it('should the selection become the currently navigated folder when the folder loads (Acts as destination for cases like copy action)', () => {
const fakeFolderNode = <Node> { id: 'fakeNodeId', isFolder: true };
component.documentList.folderNode = fakeFolderNode;
component.onFolderLoaded();

expect(component.chosenNode).toEqual([fakeFolderNode]);
});

describe('in the case when isSelectionValid is a custom function for checking permissions,', () => {

beforeEach(() => {
Expand Down Expand Up @@ -1360,5 +1369,24 @@ describe('ContentNodeSelectorPanelComponent', () => {
expect(component.sorting).toEqual(['createdAt', 'desc']);
});
});

describe('Selected nodes counter', () => {
arditdomi marked this conversation as resolved.
Show resolved Hide resolved
it('should getSelectedCount return 0 by default', () => {
expect(component.getSelectedCount()).toBe(0);
});

it('should getSelectedCount return 1 when node is selected', () => {
component.onCurrentSelection([{ entry: new Node({ id: 'fake', isFile: true }) }]);

expect(component.getSelectedCount()).toBe(1);
});

it('should getSelectedCount return 0 when the chosen nodes are reset', () => {
component.onCurrentSelection([{ entry: new Node({ id: 'fake', isFile: true }) }]);
component.resetChosenNode();

expect(component.getSelectedCount()).toBe(0);
});
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,10 @@ export class ContentNodeSelectorPanelComponent implements OnInit, OnDestroy {
return this._chosenNode;
}

getSelectedCount(): number {
return this.chosenNode?.length || 0;
}

ngOnInit() {
this.searchInput.valueChanges
.pipe(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ <h2>{{title}}</h2>
<mat-tab *ngIf="canPerformLocalUpload()"
[disabled]="isNotAllowedToUpload()">
<adf-toolbar>
<adf-toolbar-title>
<adf-toolbar-title [adf-node-counter]="getSelectedCount()">
<adf-dropdown-breadcrumb
class="adf-content-node-selector-content-breadcrumb"
[folderNode]="breadcrumbFolderNode"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
.adf-upload-dialog-container {
height: 456px;
}

.adf-toolbar-title {
place-items: center;
}
}

.adf-content-node-selector-dialog {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -435,4 +435,16 @@ describe('ContentNodeSelectorComponent', () => {
expect(emptyListTemplate).toBeNull();
});
});

describe('Selected nodes counter', () => {
it('should getSelectedCount return 0 by default', () => {
expect(component.getSelectedCount()).toBe(0);
});

it('should getSelectedCount return 1 when a node is selected', () => {
component.onSelect([new Node({ id: 'fake' })]);

expect(component.getSelectedCount()).toBe(1);
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ export class ContentNodeSelectorComponent implements OnInit {
return this.translation.instant(`NODE_SELECTOR.${action}_ITEM`, { name: this.translation.instant(name) });
}

getSelectedCount(): number {
return this.chosenNode?.length || 0;
}

isMultipleSelection(): boolean {
return this.data.selectionMode === 'multiple';
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { DocumentListModule } from '../document-list/document-list.module';
import { NameLocationCellComponent } from './name-location-cell/name-location-cell.component';
import { UploadModule } from '../upload/upload.module';
import { SearchQueryBuilderService } from '../search/search-query-builder.service';
import { ContentDirectiveModule } from '../directives/content-directive.module';

@NgModule({
imports: [
Expand All @@ -42,7 +43,8 @@ import { SearchQueryBuilderService } from '../search/search-query-builder.servic
BreadcrumbModule,
SearchModule,
DocumentListModule,
UploadModule
UploadModule,
ContentDirectiveModule
],
exports: [
ContentNodeSelectorPanelComponent,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,25 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { MaterialModule } from '../material.module';
import { TranslateModule } from '@ngx-translate/core';

import { NodeLockDirective } from './node-lock.directive';
import { NodeCounterComponent, NodeCounterDirective } from './node-counter.directive';

@NgModule({
imports: [
CommonModule,
MaterialModule
MaterialModule,
TranslateModule
],
declarations: [
NodeLockDirective
NodeLockDirective,
NodeCounterDirective,
NodeCounterComponent
],
exports: [
NodeLockDirective
NodeLockDirective,
NodeCounterDirective
]
})
export class ContentDirectiveModule {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*!
* @license
* Copyright 2019 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 { ComponentFixture, TestBed } from '@angular/core/testing';
import { NodeCounterDirective, NodeCounterComponent } from './node-counter.directive';
import { By } from '@angular/platform-browser';
import { TranslateModule } from '@ngx-translate/core';

@Component({
template: `<div [adf-node-counter]="count"></div>`
})
class TestComponent {
count: number = 0;
}

describe('NodeCounterDirective', () => {
let fixture: ComponentFixture<TestComponent>;

beforeEach(() => {
TestBed.configureTestingModule({
imports: [
TranslateModule.forRoot()
],
declarations: [
NodeCounterDirective,
NodeCounterComponent,
TestComponent
]
});
fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges();
});

it('should display the counter component', () => {
fixture.whenStable().then(() => {
const counterElement = fixture.debugElement.query(By.css('adf-node-counter'));
expect(counterElement).not.toBeNull();
expect(counterElement.nativeElement.innerText).toBe('NODE_COUNTER.SELECTED_COUNT');
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*!
* @license
* Copyright 2019 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, Input, Component, OnInit, OnChanges, ComponentFactoryResolver, ViewContainerRef } from '@angular/core';

@Directive({
selector: '[adf-node-counter]'
})
export class NodeCounterDirective implements OnInit, OnChanges {
@Input('adf-node-counter')
counter: number;

componentRef: NodeCounterComponent;

constructor(
private resolver: ComponentFactoryResolver,
public viewContainerRef: ViewContainerRef
) {}

ngOnInit() {
const componentFactory = this.resolver.resolveComponentFactory(NodeCounterComponent);
DenysVuika marked this conversation as resolved.
Show resolved Hide resolved
this.componentRef = this.viewContainerRef.createComponent(componentFactory).instance;
this.componentRef.counter = this.counter;
}

ngOnChanges() {
if (this.componentRef) {
this.componentRef.counter = this.counter;
}
}
}

@Component({
selector: 'adf-node-counter',
template: `
<div>{{ 'NODE_COUNTER.SELECTED_COUNT' | translate: { count: counter } }}</div>
`
})
export class NodeCounterComponent {
counter: number;
}
3 changes: 3 additions & 0 deletions lib/content-services/src/lib/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -474,5 +474,8 @@
"OVER-TABLE-MESSAGE" : "Select property aspects",
"SELECTED": "Selected"
}
},
"NODE_COUNTER": {
"SELECTED_COUNT": "{{ count }} selected"
}
}