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

[ACA-1956] Library - metadata info #760

Merged
merged 21 commits into from
Oct 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 129 additions & 3 deletions src/app/components/info-drawer/info-drawer.component.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,137 @@
* You should have received a copy of the GNU Lesser General Public License
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/

import { NO_ERRORS_SCHEMA } from '@angular/core';
import { InfoDrawerComponent } from './info-drawer.component';
import { TestBed, ComponentFixture, async } from '@angular/core/testing';
import { Store } from '@ngrx/store';
import { SetInfoDrawerStateAction } from '../../store/actions';
import { AppTestingModule } from '../../testing/app-testing.module';
import { AppExtensionService } from '../../extensions/extension.service';
import { ContentApiService } from '../../services/content-api.service';
import { of } from 'rxjs';

describe('InfoDrawerComponent', () => {
it('should be defined', () => {
expect(InfoDrawerComponent).toBeDefined();
let fixture: ComponentFixture<InfoDrawerComponent>;
let component: InfoDrawerComponent;
let contentApiService;
let tab;
let appExtensionService;
const storeMock = {
dispatch: jasmine.createSpy('dispatch')
};
const extensionServiceMock = {
getSidebarTabs: () => {}
};

beforeEach(() => {
TestBed.configureTestingModule({
imports: [AppTestingModule],
declarations: [InfoDrawerComponent],
providers: [
ContentApiService,
{ provide: AppExtensionService, useValue: extensionServiceMock },
{ provide: Store, useValue: storeMock }
],
schemas: [NO_ERRORS_SCHEMA]
});

fixture = TestBed.createComponent(InfoDrawerComponent);
component = fixture.componentInstance;
appExtensionService = TestBed.get(AppExtensionService);
contentApiService = TestBed.get(ContentApiService);

tab = <any>{ title: 'tab1' };
spyOn(appExtensionService, 'getSidebarTabs').and.returnValue([tab]);
});

it('should get tabs configuration on initialization', () => {
fixture.detectChanges();

expect(component.tabs).toEqual([tab]);
});

it('should set state to false OnDestroy event', () => {
fixture.detectChanges();
component.ngOnDestroy();

expect(storeMock.dispatch).toHaveBeenCalledWith(
new SetInfoDrawerStateAction(false)
);
});

it('should set displayNode when node is from personal list', () => {
spyOn(contentApiService, 'getNodeInfo');
const nodeMock = { entry: { id: 'nodeId' } };
component.node = nodeMock;

fixture.detectChanges();
component.ngOnChanges();

expect(component.displayNode).toBe(nodeMock.entry);
expect(contentApiService.getNodeInfo).not.toHaveBeenCalled();
});

it('should set displayNode when node is library', async(() => {
spyOn(contentApiService, 'getNodeInfo');
const nodeMock = <any>{
entry: { id: 'nodeId' },
isLibrary: true
};
component.node = nodeMock;

fixture.detectChanges();
component.ngOnChanges();

expect(component.displayNode).toBe(nodeMock);
expect(contentApiService.getNodeInfo).not.toHaveBeenCalled();
}));

it('should call getNodeInfo() when node is a shared file', async(() => {
const response = { entry: { id: 'nodeId' } };
spyOn(contentApiService, 'getNodeInfo').and.returnValue(of(response));
const nodeMock = { entry: { nodeId: 'nodeId' }, isLibrary: false };
component.node = nodeMock;

fixture.detectChanges();
component.ngOnChanges();

expect(component.displayNode).toBe(response);
expect(contentApiService.getNodeInfo).toHaveBeenCalled();
}));

it('should call getNodeInfo() when node is a favorite file', async(() => {
const response = { entry: { id: 'nodeId' } };
spyOn(contentApiService, 'getNodeInfo').and.returnValue(of(response));
const nodeMock = <any>{
entry: { id: 'nodeId', guid: 'guidId' },
isLibrary: false
};
component.node = nodeMock;

fixture.detectChanges();
component.ngOnChanges();

expect(component.displayNode).toBe(response);
expect(contentApiService.getNodeInfo).toHaveBeenCalled();
}));

it('should call getNodeInfo() when node is a recent file', async(() => {
const response = { entry: { id: 'nodeId' } };
spyOn(contentApiService, 'getNodeInfo').and.returnValue(of(response));
const nodeMock = <any>{
entry: {
id: 'nodeId',
content: { mimeType: 'image/jpeg' }
},
isLibrary: false
};
component.node = nodeMock;

fixture.detectChanges();
component.ngOnChanges();

expect(component.displayNode).toBe(response);
expect(contentApiService.getNodeInfo).toHaveBeenCalled();
}));
});
67 changes: 50 additions & 17 deletions src/app/components/info-drawer/info-drawer.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,35 @@
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
*/

import { Component, Input, OnChanges, OnInit } from '@angular/core';
import { MinimalNodeEntity, MinimalNodeEntryEntity } from 'alfresco-js-api';
import { Component, Input, OnChanges, OnInit, OnDestroy } from '@angular/core';
import {
MinimalNodeEntity,
MinimalNodeEntryEntity,
SiteEntry
} from 'alfresco-js-api';
import { ContentApiService } from '../../services/content-api.service';
import { AppExtensionService } from '../../extensions/extension.service';
import { SidebarTabRef } from '@alfresco/adf-extensions';
import { Store } from '@ngrx/store';
import { AppStore } from '../../store/states/app.state';
import { SetInfoDrawerStateAction } from '../../store/actions';

@Component({
selector: 'aca-info-drawer',
templateUrl: './info-drawer.component.html'
})
export class InfoDrawerComponent implements OnChanges, OnInit {
export class InfoDrawerComponent implements OnChanges, OnInit, OnDestroy {
@Input()
nodeId: string;
@Input()
node: MinimalNodeEntity;

isLoading = false;
displayNode: MinimalNodeEntryEntity;
displayNode: MinimalNodeEntryEntity | SiteEntry;
tabs: Array<SidebarTabRef> = [];

constructor(
private store: Store<AppStore>,
private contentApi: ContentApiService,
private extensions: AppExtensionService
) {}
Expand All @@ -52,22 +60,31 @@ export class InfoDrawerComponent implements OnChanges, OnInit {
this.tabs = this.extensions.getSidebarTabs();
}

ngOnDestroy() {
this.store.dispatch(new SetInfoDrawerStateAction(false));
}

ngOnChanges() {
if (this.node) {
const entry = this.node.entry;
if (entry.nodeId) {
this.loadNodeInfo(entry.nodeId);
} else if ((<any>entry).guid) {
// workaround for Favorite files
this.loadNodeInfo(entry.id);
} else {
// workaround Recent
if (this.isTypeImage(entry) && !this.hasAspectNames(entry)) {
this.loadNodeInfo(this.node.entry.id);
} else {
this.setDisplayNode(this.node.entry);
}

if (this.isLibraryListNode(this.node)) {
return this.setDisplayNode(this.node);
}

if (this.isSharedFilesNode(this.node)) {
return this.loadNodeInfo(entry.nodeId);
}

if (this.isFavoriteListNode(this.node)) {
return this.loadNodeInfo(entry.id);
}

if (this.isRecentListFileNode(this.node)) {
return this.loadNodeInfo(entry.id);
}

this.setDisplayNode(entry);
}
}

Expand Down Expand Up @@ -96,7 +113,23 @@ export class InfoDrawerComponent implements OnChanges, OnInit {
}
}

private setDisplayNode(node: MinimalNodeEntryEntity) {
private setDisplayNode(node: MinimalNodeEntryEntity | SiteEntry) {
this.displayNode = node;
}

private isLibraryListNode(node: SiteEntry): boolean {
return (<any>node).isLibrary;
}

private isFavoriteListNode(node: MinimalNodeEntity): boolean {
return !this.isLibraryListNode(node) && (<any>node).entry.guid;
}

private isSharedFilesNode(node: MinimalNodeEntity): boolean {
return !!node.entry.nodeId;
}

private isRecentListFileNode(node: MinimalNodeEntity): boolean {
return this.isTypeImage(node.entry) && !this.hasAspectNames(node.entry);
}
}
6 changes: 5 additions & 1 deletion src/app/components/info-drawer/info.drawer.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,18 @@ import { MaterialModule } from '../../material.module';
import { CommentsTabComponent } from './comments-tab/comments-tab.component';
import { InfoDrawerComponent } from './info-drawer.component';
import { MetadataTabComponent } from './metadata-tab/metadata-tab.component';
import { LibraryMetadataTabComponent } from './library-metadata-tab/library-metadata-tab.component';
import { LibraryMetadataFormComponent } from './library-metadata-tab/library-metadata-form.component';
import { VersionsTabComponent } from './versions-tab/versions-tab.component';

export function components() {
return [
InfoDrawerComponent,
MetadataTabComponent,
CommentsTabComponent,
VersionsTabComponent
VersionsTabComponent,
LibraryMetadataTabComponent,
LibraryMetadataFormComponent
];
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<mat-card *ngIf="node">
<mat-card-content *ngIf="!edit">
<div class="mat-form-field mat-form-field-type-mat-input mat-form-field-can-float mat-form-field-should-float adf-full-width">
<div class="mat-form-field-wrapper">
<div class="mat-form-field-flex">
<div class="mat-form-field-infix">
<span class="mat-form-field-label-wrapper">
<span class="mat-form-field-label">
{{ 'LIBRARY.DIALOG.FORM.NAME' | translate }}
</span>
</span>

<span class="mat-input-element">
{{ form.controls.title.value }}
</span>
</div>
</div>
</div>
</div>

<div class="mat-form-field mat-primary mat-form-field-type-mat-input mat-form-field-can-float mat-form-field-should-float adf-full-width">
<div class="mat-form-field-wrapper">
<div class="mat-form-field-flex">
<div class="mat-form-field-infix">
<span class="mat-form-field-label-wrapper">
<span class="mat-form-field-label">
{{ 'LIBRARY.DIALOG.FORM.SITE_ID' | translate }}
</span>
</span>

<span class="mat-input-element">
{{ form.controls.id.value }}
</span>
</div>
</div>
</div>
</div>

<div class="mat-form-field mat-primary mat-form-field-type-mat-input mat-form-field-can-float mat-form-field-should-float adf-full-width">
<div class="mat-form-field-wrapper">
<div class="mat-form-field-flex">
<div class="mat-form-field-infix">
<span class="mat-form-field-label-wrapper">
<span class="mat-form-field-label">
{{ 'LIBRARY.DIALOG.FORM.TYPE' | translate }}
</span>
</span>

<span class="mat-input-element">
{{ (getVisibilityLabel(form.controls.visibility.value)) | translate }}
</span>
</div>
</div>
</div>
</div>

<div class="mat-form-field mat-primary mat-form-field-type-mat-input mat-form-field-can-float mat-form-field-should-float adf-full-width">
<div class="mat-form-field-wrapper">
<div class="mat-form-field-flex">
<div class="mat-form-field-infix">
<span class="mat-form-field-label-wrapper">
<span class="mat-form-field-label">
{{ 'LIBRARY.DIALOG.FORM.DESCRIPTION' | translate }}
</span>
</span>

<span class="mat-input-element">
{{ form.controls.description?.value }}
</span>
</div>
</div>
</div>
</div>
</mat-card-content>

<mat-card-actions align="end" *ngIf="!edit">
<button mat-button color="primary" (click)="toggleEdit()">
{{ 'LIBRARY.DIALOG.EDIT' | translate }}
</button>
</mat-card-actions>

<mat-card-content *ngIf="edit">
<form [formGroup]="form" autocomplete="off">
<mat-form-field class="adf-full-width">
<input matInput cdkFocusInitial required placeholder="{{ 'LIBRARY.DIALOG.FORM.NAME' | translate }}"
formControlName="title">

<mat-error *ngIf="form.controls['title'].hasError('maxlength')">
{{ 'LIBRARY.ERRORS.TITLE_TOO_LONG' | translate }}
</mat-error>
</mat-form-field>

<mat-form-field class="adf-full-width">
<input matInput placeholder="{{ 'LIBRARY.DIALOG.FORM.SITE_ID' | translate }}" formControlName="id">
</mat-form-field>

<mat-form-field class="adf-full-width">
<mat-select placeholder="{{ 'LIBRARY.DIALOG.FORM.TYPE' | translate }}" formControlName="visibility">
<mat-option [value]="type.value" *ngFor="let type of libraryType">
{{ type.label | translate }}
</mat-option>
</mat-select>
</mat-form-field>

<mat-form-field class="adf-full-width">
<textarea matInput placeholder="{{ 'LIBRARY.DIALOG.FORM.DESCRIPTION' | translate }}" rows="3"
formControlName="description"></textarea>

<mat-error *ngIf="form.controls['description'].hasError('maxlength')">
{{ 'LIBRARY.ERRORS.DESCRIPTION_TOO_LONG' | translate }}
</mat-error>
</mat-form-field>
</form>
</mat-card-content>

<mat-card-actions align="end" *ngIf="edit && canUpdateLibrary">
<button mat-button color="secondary" (click)="cancel()">
{{ 'LIBRARY.DIALOG.CANCEL' | translate }}
</button>
<button mat-button color="primary" [disabled]="form.invalid" (click)="update()">
{{ 'LIBRARY.DIALOG.UPDATE' | translate }}
</button>
</mat-card-actions>
</mat-card>
Loading