diff --git a/demo-shell/resources/i18n/en.json b/demo-shell/resources/i18n/en.json index b37beae63e..0514695eed 100644 --- a/demo-shell/resources/i18n/en.json +++ b/demo-shell/resources/i18n/en.json @@ -9,6 +9,12 @@ "TITLE": "Manage Versions" } }, + "METADATA": { + "DIALOG": { + "CLOSE": "Close", + "TITLE": "Metadata" + } + }, "APP_LAYOUT": { "APP_NAME": "ADF Demo Application", "HOME": "Home", @@ -74,6 +80,8 @@ "DELETE":"Delete" }, "ACTIONS": { + "VERSIONS": "Manage versions", + "METADATA": "Info", "DOWNLOAD": "Download", "FOLDER": { "COPY": "Copy", diff --git a/demo-shell/src/app/app.module.ts b/demo-shell/src/app/app.module.ts index 6a023f0f15..267ec44d16 100644 --- a/demo-shell/src/app/app.module.ts +++ b/demo-shell/src/app/app.module.ts @@ -36,6 +36,7 @@ import { WebscriptComponent } from './components/webscript/webscript.component'; import { TagComponent } from './components/tag/tag.component'; import { SocialComponent } from './components/social/social.component'; import { VersionManagerDialogAdapterComponent } from './components/files/version-manager-dialog-adapter.component'; +import { MetadataDialogAdapterComponent } from './components/files/metadata-dialog-adapter.component'; import { ThemePickerModule } from './components/theme-picker/theme-picker'; import { DebugAppConfigService } from './services/debug-app-config.service'; @@ -87,6 +88,7 @@ import { SharedLinkViewComponent } from './components/shared-link-view/shared-li SocialComponent, CustomSourcesComponent, VersionManagerDialogAdapterComponent, + MetadataDialogAdapterComponent, TaskAttachmentsComponent, ProcessAttachmentsComponent, OverlayViewerComponent, @@ -112,7 +114,8 @@ import { SharedLinkViewComponent } from './components/shared-link-view/shared-li } ], entryComponents: [ - VersionManagerDialogAdapterComponent + VersionManagerDialogAdapterComponent, + MetadataDialogAdapterComponent ], bootstrap: [AppComponent] }) diff --git a/demo-shell/src/app/components/files/files.component.html b/demo-shell/src/app/components/files/files.component.html index a279618558..fdec4f6c04 100644 --- a/demo-shell/src/app/components/files/files.component.html +++ b/demo-shell/src/app/components/files/files.component.html @@ -245,11 +245,16 @@ (success)="onDeleteActionSuccess($event)" handler="delete"> + + +
diff --git a/demo-shell/src/app/components/files/files.component.ts b/demo-shell/src/app/components/files/files.component.ts index be8cd66cad..0814e25407 100644 --- a/demo-shell/src/app/components/files/files.component.ts +++ b/demo-shell/src/app/components/files/files.component.ts @@ -34,6 +34,7 @@ import { DocumentListComponent, PermissionStyleModel } from '@alfresco/adf-conte import { SelectAppsDialogComponent } from '@alfresco/adf-process-services'; import { VersionManagerDialogAdapterComponent } from './version-manager-dialog-adapter.component'; +import { MetadataDialogAdapterComponent } from './metadata-dialog-adapter.component'; import { Subscription } from 'rxjs/Subscription'; const DEFAULT_FOLDER_TO_SHOW = '-my-'; @@ -342,6 +343,21 @@ export class FilesComponent implements OnInit, OnChanges, OnDestroy { } } + onManageMetadata(event) { + const contentEntry = event.value.entry; + + if (this.contentService.hasPermission(contentEntry, 'update')) { + this.dialog.open(MetadataDialogAdapterComponent, { + data: { contentEntry }, + panelClass: 'adf-metadata-manager-dialog', + width: '630px' + }); + } else { + const translatedErrorMessage: any = this.translateService.get('OPERATION.ERROR.PERMISSION'); + this.notificationService.openSnackMessage(translatedErrorMessage.value, 4000); + } + } + getSiteContent(site: SiteEntry) { this.currentFolderId = site && site.entry.guid ? site.entry.guid : DEFAULT_FOLDER_TO_SHOW; } diff --git a/demo-shell/src/app/components/files/metadata-dialog-adapter.component.html b/demo-shell/src/app/components/files/metadata-dialog-adapter.component.html new file mode 100644 index 0000000000..70b69c389d --- /dev/null +++ b/demo-shell/src/app/components/files/metadata-dialog-adapter.component.html @@ -0,0 +1,7 @@ +
{{'METADATA.DIALOG.TITLE' | translate}}
+
+ +
+
+ +
diff --git a/demo-shell/src/app/components/files/metadata-dialog-adapter.component.ts b/demo-shell/src/app/components/files/metadata-dialog-adapter.component.ts new file mode 100644 index 0000000000..b1ca9c213d --- /dev/null +++ b/demo-shell/src/app/components/files/metadata-dialog-adapter.component.ts @@ -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. + */ + +import { Component, Inject, ViewEncapsulation } from '@angular/core'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material'; +import { MinimalNodeEntryEntity } from 'alfresco-js-api'; + +@Component({ + templateUrl: './metadata-dialog-adapter.component.html', + encapsulation: ViewEncapsulation.None +}) +export class MetadataDialogAdapterComponent { + + public contentEntry: MinimalNodeEntryEntity; + + constructor(@Inject(MAT_DIALOG_DATA) data: any, + private containingDialog?: MatDialogRef) { + this.contentEntry = data.contentEntry; + } + + close() { + this.containingDialog.close(); + } +} diff --git a/lib/content-services/content-metadata/components/content-metadata/content-metadata.component.spec.ts b/lib/content-services/content-metadata/components/content-metadata/content-metadata.component.spec.ts index 4627f35a21..359b2687c4 100644 --- a/lib/content-services/content-metadata/components/content-metadata/content-metadata.component.spec.ts +++ b/lib/content-services/content-metadata/components/content-metadata/content-metadata.component.spec.ts @@ -28,7 +28,13 @@ import { BasicPropertiesService } from '../../services/basic-properties.service' import { PropertyGroupTranslatorService } from '../../services/property-groups-translator.service'; import { PropertyDescriptorsService } from '../../services/property-descriptors.service'; import { AlfrescoApiService } from '@alfresco/adf-core'; -import { CardViewBaseItemModel, CardViewComponent, CardViewUpdateService, NodesApiService, LogService } from '@alfresco/adf-core'; +import { + CardViewBaseItemModel, + CardViewComponent, + CardViewUpdateService, + NodesApiService, + LogService +} from '@alfresco/adf-core'; import { ErrorObservable } from 'rxjs/observable/ErrorObservable'; import { Observable } from 'rxjs/Observable'; import { ContentMetadataConfigFactory } from '../../services/config/content-metadata-config.factory'; @@ -38,6 +44,7 @@ describe('ContentMetadataComponent', () => { let component: ContentMetadataComponent, fixture: ComponentFixture, node: MinimalNodeEntryEntity, + folderNode: MinimalNodeEntryEntity, preset = 'custom-preset'; beforeEach(async(() => { @@ -76,6 +83,14 @@ describe('ContentMetadataComponent', () => { modifiedByUser: {} }; + folderNode = { + id: 'folder-id', + aspectNames: [], + nodeType: '', + createdByUser: {}, + modifiedByUser: {} + }; + component.node = node; component.preset = preset; fixture.detectChanges(); @@ -101,6 +116,22 @@ describe('ContentMetadataComponent', () => { }); }); + describe('Folder', () => { + + it('should show the folder node', () => { + component.expanded = false; + fixture.detectChanges(); + + component.ngOnChanges({ node: new SimpleChange(node, folderNode, false) }); + + component.basicProperties$.subscribe(() => { + fixture.detectChanges(); + const basicPropertiesComponent = fixture.debugElement.query(By.directive(CardViewComponent)).componentInstance; + expect(basicPropertiesComponent.properties).toBeDefined(); + }); + }); + }); + describe('Saving', () => { it('should save the node on itemUpdate', () => { diff --git a/lib/content-services/content-metadata/services/basic-properties.service.ts b/lib/content-services/content-metadata/services/basic-properties.service.ts index a583172d7b..d4389af92e 100644 --- a/lib/content-services/content-metadata/services/basic-properties.service.ts +++ b/lib/content-services/content-metadata/services/basic-properties.service.ts @@ -22,9 +22,17 @@ import { CardViewDateItemModel, CardViewTextItemModel, FileSizePipe } from '@alf @Injectable() export class BasicPropertiesService { - constructor(private fileSizePipe: FileSizePipe) {} + constructor(private fileSizePipe: FileSizePipe) { + } getProperties(node: MinimalNodeEntryEntity) { + + const sizeInBytes = node.content ? node.content.sizeInBytes : '', + mimeTypeName = node.content ? node.content.mimeTypeName : '', + author = node.properties ? node.properties['cm:author'] : '', + description = node.properties ? node.properties['cm:description'] : '', + title = node.properties ? node.properties['cm:title'] : ''; + return [ new CardViewTextItemModel({ label: 'CORE.METADATA.BASIC.NAME', @@ -34,7 +42,7 @@ export class BasicPropertiesService { }), new CardViewTextItemModel({ label: 'CORE.METADATA.BASIC.TITLE', - value: node.properties['cm:title'], + value: title, key: 'properties.cm:title', editable: true }), @@ -52,7 +60,7 @@ export class BasicPropertiesService { }), new CardViewTextItemModel({ label: 'CORE.METADATA.BASIC.SIZE', - value: node.content.sizeInBytes, + value: sizeInBytes, key: 'content.sizeInBytes', pipes: [{ pipe: this.fileSizePipe }], editable: false @@ -71,19 +79,19 @@ export class BasicPropertiesService { }), new CardViewTextItemModel({ label: 'CORE.METADATA.BASIC.MIMETYPE', - value: node.content.mimeTypeName, + value: mimeTypeName, key: 'content.mimeTypeName', editable: false }), new CardViewTextItemModel({ label: 'CORE.METADATA.BASIC.AUTHOR', - value: node.properties['cm:author'], + value: author, key: 'properties.cm:author', editable: true }), new CardViewTextItemModel({ label: 'CORE.METADATA.BASIC.DESCRIPTION', - value: node.properties['cm:description'], + value: description, key: 'properties.cm:description', multiline: true, editable: true diff --git a/lib/content-services/content-metadata/services/content-metadata.service.ts b/lib/content-services/content-metadata/services/content-metadata.service.ts index eafe62f5b3..91ef392f7f 100644 --- a/lib/content-services/content-metadata/services/content-metadata.service.ts +++ b/lib/content-services/content-metadata/services/content-metadata.service.ts @@ -28,31 +28,30 @@ import { PropertyDescriptorsService } from './property-descriptors.service'; @Injectable() export class ContentMetadataService { - constructor( - private basicPropertiesService: BasicPropertiesService, - private contentMetadataConfigFactory: ContentMetadataConfigFactory, - private propertyGroupTranslatorService: PropertyGroupTranslatorService, - private propertyDescriptorsService: PropertyDescriptorsService - ) {} + constructor(private basicPropertiesService: BasicPropertiesService, + private contentMetadataConfigFactory: ContentMetadataConfigFactory, + private propertyGroupTranslatorService: PropertyGroupTranslatorService, + private propertyDescriptorsService: PropertyDescriptorsService) { + } getBasicProperties(node: MinimalNodeEntryEntity): Observable { return Observable.of(this.basicPropertiesService.getProperties(node)); } getGroupedProperties(node: MinimalNodeEntryEntity, presetName: string = 'default'): Observable { - const config = this.contentMetadataConfigFactory.get(presetName), - groupNames = node.aspectNames - .concat(node.nodeType) - .filter(groupName => config.isGroupAllowed(groupName)); + let groupedProperties = Observable.of([]); - let groupedProperties; + if (node.aspectNames) { + const config = this.contentMetadataConfigFactory.get(presetName), + groupNames = node.aspectNames + .concat(node.nodeType) + .filter(groupName => config.isGroupAllowed(groupName)); - if (groupNames.length > 0) { - groupedProperties = this.propertyDescriptorsService.load(groupNames) - .map(groups => config.reorganiseByConfig(groups)) - .map(groups => this.propertyGroupTranslatorService.translateToCardViewGroups(groups, node.properties)); - } else { - groupedProperties = Observable.of([]); + if (groupNames.length > 0) { + groupedProperties = this.propertyDescriptorsService.load(groupNames) + .map(groups => config.reorganiseByConfig(groups)) + .map(groups => this.propertyGroupTranslatorService.translateToCardViewGroups(groups, node.properties)); + } } return groupedProperties;