From 5dabc39841fd12597d0f5bea10580e38cecb8bc5 Mon Sep 17 00:00:00 2001 From: suzanadirla Date: Fri, 3 Nov 2017 16:45:42 +0200 Subject: [PATCH] [ADF-1774] Extend "Create Folder" and add "Edit Folder" dialogs to ADF (#2585) * [ADF-1774] Extend "Create Folder" and add "Edit Folder" dialogs to ADF - added create and edit folder directives and used them inside the demo-shell file component - added FolderDialogComponent for edit/create actions with name validators: forbidSpecialCharacters, forbidEndingDot and forbidOnlySpaces - updated the translation files - added unit tests for the new components - removed the CreateFolderDialogComponent and its usage inside demo-shell - added documentation files for FolderCreateDirective and FolderEditDirective * [ADF-1774] fix messed up translation files because of previous commit * [ADF-1774] changes required on code review comments --- .../app/components/files/files.component.html | 15 +- .../app/components/files/files.component.ts | 47 ++- docs/README.md | 2 + docs/folder-create.directive.md | 40 +++ docs/folder-edit.directive.md | 40 +++ ng2-components/ng2-alfresco-core/index.ts | 18 +- .../src/dialogs/create-folder.dialog.ts | 45 --- .../src/dialogs/folder-name.validators.ts | 45 +++ .../src/dialogs/folder.dialog.html | 64 ++++ .../src/dialogs/folder.dialog.scss | 7 + .../src/dialogs/folder.dialog.spec.ts | 273 ++++++++++++++++++ .../src/dialogs/folder.dialog.ts | 142 +++++++++ .../folder-create.directive.spec.ts | 115 ++++++++ .../src/directives/folder-create.directive.ts | 68 +++++ .../directives/folder-edit.directive.spec.ts | 117 ++++++++ .../src/directives/folder-edit.directive.ts | 69 +++++ .../ng2-alfresco-core/src/i18n/de.json | 45 ++- .../ng2-alfresco-core/src/i18n/en.json | 111 ++++--- .../ng2-alfresco-core/src/i18n/es.json | 31 ++ .../ng2-alfresco-core/src/i18n/fr.json | 33 ++- .../ng2-alfresco-core/src/i18n/it.json | 31 ++ .../ng2-alfresco-core/src/i18n/ja.json | 31 ++ .../ng2-alfresco-core/src/i18n/nb.json | 31 ++ .../ng2-alfresco-core/src/i18n/nl.json | 31 ++ .../ng2-alfresco-core/src/i18n/pt-BR.json | 31 ++ .../ng2-alfresco-core/src/i18n/ru.json | 31 ++ .../ng2-alfresco-core/src/i18n/zh-CN.json | 31 ++ .../src/services/alfresco-content.service.ts | 4 +- 28 files changed, 1431 insertions(+), 117 deletions(-) create mode 100644 docs/folder-create.directive.md create mode 100644 docs/folder-edit.directive.md delete mode 100644 ng2-components/ng2-alfresco-core/src/dialogs/create-folder.dialog.ts create mode 100644 ng2-components/ng2-alfresco-core/src/dialogs/folder-name.validators.ts create mode 100644 ng2-components/ng2-alfresco-core/src/dialogs/folder.dialog.html create mode 100644 ng2-components/ng2-alfresco-core/src/dialogs/folder.dialog.scss create mode 100644 ng2-components/ng2-alfresco-core/src/dialogs/folder.dialog.spec.ts create mode 100644 ng2-components/ng2-alfresco-core/src/dialogs/folder.dialog.ts create mode 100644 ng2-components/ng2-alfresco-core/src/directives/folder-create.directive.spec.ts create mode 100644 ng2-components/ng2-alfresco-core/src/directives/folder-create.directive.ts create mode 100644 ng2-components/ng2-alfresco-core/src/directives/folder-edit.directive.spec.ts create mode 100644 ng2-components/ng2-alfresco-core/src/directives/folder-edit.directive.ts diff --git a/demo-shell-ng2/src/app/components/files/files.component.html b/demo-shell-ng2/src/app/components/files/files.component.html index 77fa0e3f60..0e569e8649 100644 --- a/demo-shell-ng2/src/app/components/files/files.component.html +++ b/demo-shell-ng2/src/app/components/files/files.component.html @@ -34,9 +34,14 @@
+ + + + + + ... + +``` + +### Properties + +| Name | Type | Default | Description | +| ----------------- | ------------------- | --------- | ----------------------------------------------------------------- | +| adf-create-folder | string | '-my-' | Parent folder where the new folder will be located after creation | + +## Details + +'FolderCreateDirective' directive needs the id of the parent folder where we want the new folder node to be created. If no value is provided, the '-my-' alias is used. +It opens the FolderDialogComponent to receive data for the new folder. If data is valid, on dialog close, it emits folderCreate event. \ No newline at end of file diff --git a/docs/folder-edit.directive.md b/docs/folder-edit.directive.md new file mode 100644 index 0000000000..14f1469fba --- /dev/null +++ b/docs/folder-edit.directive.md @@ -0,0 +1,40 @@ +# Folder Edit directive + + + + + +- [Basic Usage](#basic-usage) + * [Properties](#properties) + * [Events](#events) +- [Details](#details) + + + + + +## Basic Usage + +```html + + + + + + ... + +``` + +### Properties + +| Name | Type | Default | Description | +| ----------------- | ---------------------- | ------- | ----------------------------------- | +| adf-edit-folder | MinimalNodeEntryEntity | | The folder node entity for editing | + +## Details + +'FolderEditDirective' directive needs a selection folder entry of #documentList to open the folder dialog component to edit the name and description properties of that selected folder. +If data is valid, on dialog close, it emits folderEdit event. \ No newline at end of file diff --git a/ng2-components/ng2-alfresco-core/index.ts b/ng2-components/ng2-alfresco-core/index.ts index 381cdf2955..db9d68153b 100644 --- a/ng2-components/ng2-alfresco-core/index.ts +++ b/ng2-components/ng2-alfresco-core/index.ts @@ -29,8 +29,8 @@ import { CardViewModule } from './src/components/view/card-view.module'; import { MaterialModule } from './src/material.module'; import { AppConfigModule } from './src/services/app-config.service'; -import { CreateFolderDialogComponent } from './src/dialogs/create-folder.dialog'; import { DownloadZipDialogComponent } from './src/dialogs/download-zip.dialog'; +import { FolderDialogComponent } from './src/dialogs/folder.dialog'; import { AlfrescoApiService } from './src/services/alfresco-api.service'; import { AlfrescoContentService } from './src/services/alfresco-content.service'; @@ -52,6 +52,8 @@ import { AlfrescoTranslateLoader } from './src/services/translate-loader.service import { TRANSLATION_PROVIDER, TranslationService } from './src/services/translation.service'; import { UploadService } from './src/services/upload.service'; +import { FolderCreateDirective } from './src/directives/folder-create.directive'; +import { FolderEditDirective } from './src/directives/folder-edit.directive'; import { HighlightDirective } from './src/directives/highlight.directive'; import { LogoutDirective } from './src/directives/logout.directive'; import { NodeDeleteDirective } from './src/directives/node-delete.directive'; @@ -73,8 +75,8 @@ import { UserPreferencesService } from './src/services/user-preferences.service' export { MomentDateAdapter, MOMENT_DATE_FORMATS } from './src/utils/momentDateAdapter'; import { MomentDateAdapter } from './src/utils/momentDateAdapter'; -export { CreateFolderDialogComponent } from './src/dialogs/create-folder.dialog'; export { DownloadZipDialogComponent } from './src/dialogs/download-zip.dialog'; +export { FolderDialogComponent } from './src/dialogs/folder.dialog'; export { PageTitleService } from './src/services/page-title.service'; export { ContentService } from './src/services/content.service'; @@ -264,6 +266,8 @@ export function createTranslateLoader(http: Http, logService: LogService) { ], declarations: [ ...pipes(), + FolderCreateDirective, + FolderEditDirective, LogoutDirective, UploadDirective, NodeRestoreDirective, @@ -281,8 +285,8 @@ export function createTranslateLoader(http: Http, logService: LogService) { InfoDrawerContentDirective, LanguageMenuComponent, HostSettingsComponent, - CreateFolderDialogComponent, DownloadZipDialogComponent, + FolderDialogComponent, InfinitePaginationComponent, PaginationComponent ], @@ -312,6 +316,8 @@ export function createTranslateLoader(http: Http, logService: LogService) { CollapsableModule, ToolbarModule, ...pipes(), + FolderCreateDirective, + FolderEditDirective, LogoutDirective, UploadDirective, NodeRestoreDirective, @@ -322,8 +328,8 @@ export function createTranslateLoader(http: Http, logService: LogService) { HostSettingsComponent, DataColumnComponent, DataColumnListComponent, - CreateFolderDialogComponent, DownloadZipDialogComponent, + FolderDialogComponent, InfoDrawerComponent, InfoDrawerTabComponent, InfoDrawerLayoutComponent, @@ -335,8 +341,8 @@ export function createTranslateLoader(http: Http, logService: LogService) { PaginationComponent ], entryComponents: [ - CreateFolderDialogComponent, - DownloadZipDialogComponent + DownloadZipDialogComponent, + FolderDialogComponent ] }) export class CoreModule {} diff --git a/ng2-components/ng2-alfresco-core/src/dialogs/create-folder.dialog.ts b/ng2-components/ng2-alfresco-core/src/dialogs/create-folder.dialog.ts deleted file mode 100644 index f568f81d70..0000000000 --- a/ng2-components/ng2-alfresco-core/src/dialogs/create-folder.dialog.ts +++ /dev/null @@ -1,45 +0,0 @@ -/*! - * @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, ViewEncapsulation } from '@angular/core'; - -@Component({ - selector: 'adf-create-folder-dialog', - template: ` -

Create a new folder

-
- - - -
-
- - -
- `, - styles: [ - ` - .create-folder--name { - width: 100%; - } - ` - ], - encapsulation: ViewEncapsulation.None -}) -export class CreateFolderDialogComponent { - value: string = ''; -} diff --git a/ng2-components/ng2-alfresco-core/src/dialogs/folder-name.validators.ts b/ng2-components/ng2-alfresco-core/src/dialogs/folder-name.validators.ts new file mode 100644 index 0000000000..4d7fe2919b --- /dev/null +++ b/ng2-components/ng2-alfresco-core/src/dialogs/folder-name.validators.ts @@ -0,0 +1,45 @@ +/*! + * @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 { FormControl } from '@angular/forms'; + +const I18N_ERRORS_PATH = 'CORE.FOLDER_DIALOG.FOLDER_NAME.ERRORS'; + +export function forbidSpecialCharacters({ value }: FormControl) { + const specialCharacters: RegExp = /([\*\"\<\>\\\/\?\:\|])/; + const isValid: boolean = !specialCharacters.test(value); + + return (isValid) ? null : { + message: `${I18N_ERRORS_PATH}.SPECIAL_CHARACTERS` + }; +} + +export function forbidEndingDot({ value }: FormControl) { + const isValid: boolean = ((value || '').trim().split('').pop() !== '.'); + + return isValid ? null : { + message: `${I18N_ERRORS_PATH}.ENDING_DOT` + }; +} + +export function forbidOnlySpaces({ value }: FormControl) { + const isValid: boolean = !!((value || '')).trim(); + + return isValid ? null : { + message: `${I18N_ERRORS_PATH}.ONLY_SPACES` + }; +} diff --git a/ng2-components/ng2-alfresco-core/src/dialogs/folder.dialog.html b/ng2-components/ng2-alfresco-core/src/dialogs/folder.dialog.html new file mode 100644 index 0000000000..e349a481e1 --- /dev/null +++ b/ng2-components/ng2-alfresco-core/src/dialogs/folder.dialog.html @@ -0,0 +1,64 @@ +

+ {{ + (editing + ? 'CORE.FOLDER_DIALOG.EDIT_FOLDER_TITLE' + : 'CORE.FOLDER_DIALOG.CREATE_FOLDER_TITLE' + ) | translate + }} +

+ + +
+ + + + + + {{ 'CORE.FOLDER_DIALOG.FOLDER_NAME.ERRORS.REQUIRED' | translate }} + + + + {{ form.controls['name'].errors?.message | translate }} + + + + +
+
+ + + + +
+
+ + + + + + + + diff --git a/ng2-components/ng2-alfresco-core/src/dialogs/folder.dialog.scss b/ng2-components/ng2-alfresco-core/src/dialogs/folder.dialog.scss new file mode 100644 index 0000000000..3bda268b54 --- /dev/null +++ b/ng2-components/ng2-alfresco-core/src/dialogs/folder.dialog.scss @@ -0,0 +1,7 @@ +.adf-fill-remaining-space { + flex: 1 1 auto; +} + +.adf-full-width { + width: 100%; +} diff --git a/ng2-components/ng2-alfresco-core/src/dialogs/folder.dialog.spec.ts b/ng2-components/ng2-alfresco-core/src/dialogs/folder.dialog.spec.ts new file mode 100644 index 0000000000..9f8794bc66 --- /dev/null +++ b/ng2-components/ng2-alfresco-core/src/dialogs/folder.dialog.spec.ts @@ -0,0 +1,273 @@ +/*! + * @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 { async, TestBed } from '@angular/core/testing'; +import { ComponentFixture } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { MatDialogModule, MatDialogRef } from '@angular/material'; +import { BrowserDynamicTestingModule } from '@angular/platform-browser-dynamic/testing'; +import { Observable } from 'rxjs/Rx'; + +import { AlfrescoTranslationService, CoreModule } from '../../index'; +import { TranslationMock } from '../assets/translation.service.mock'; +import { NodesApiService } from '../services/nodes-api.service'; +import { NotificationService } from '../services/notification.service'; +import { TranslationService } from '../services/translation.service'; +import { FolderDialogComponent } from './folder.dialog'; + +describe('FolderDialogComponent', () => { + + let fixture: ComponentFixture; + let component: FolderDialogComponent; + let translationService: TranslationService; + let nodesApi: NodesApiService; + let notificationService: NotificationService; + let dialogRef; + + beforeEach(async(() => { + dialogRef = { + close: jasmine.createSpy('close') + }; + + TestBed.configureTestingModule({ + imports: [ + CoreModule, + MatDialogModule, + FormsModule, + ReactiveFormsModule, + BrowserDynamicTestingModule + ], + providers: [ + { provide: MatDialogRef, useValue: dialogRef }, + { provide: AlfrescoTranslationService, useClass: TranslationMock } + ] + }); + + // entryComponents are not supported yet on TestBed, that is why this ugly workaround: + // https://github.com/angular/angular/issues/10760 + TestBed.overrideModule(BrowserDynamicTestingModule, { + set: {entryComponents: [ FolderDialogComponent ]} + }); + + TestBed.compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(FolderDialogComponent); + component = fixture.componentInstance; + + nodesApi = TestBed.get(NodesApiService); + notificationService = TestBed.get(NotificationService); + + translationService = TestBed.get(TranslationService); + spyOn(translationService, 'get').and.returnValue(Observable.of('message')); + }); + + describe('Edit', () => { + + beforeEach(() => { + component.data = { + folder: { + id: 'node-id', + name: 'folder-name', + properties: { + ['cm:description']: 'folder-description' + } + } + }; + fixture.detectChanges(); + }); + + it('should init form with folder name and description', () => { + expect(component.name).toBe('folder-name'); + expect(component.description).toBe('folder-description'); + }); + + it('should update form input', () => { + component.form.controls['name'].setValue('folder-name-update'); + component.form.controls['description'].setValue('folder-description-update'); + + expect(component.name).toBe('folder-name-update'); + expect(component.description).toBe('folder-description-update'); + }); + + it('should submit updated values if form is valid', () => { + spyOn(nodesApi, 'updateNode').and.returnValue(Observable.of({})); + + component.form.controls['name'].setValue('folder-name-update'); + component.form.controls['description'].setValue('folder-description-update'); + + component.submit(); + + expect(nodesApi.updateNode).toHaveBeenCalledWith( + 'node-id', + { + name: 'folder-name-update', + properties: { + 'cm:title': 'folder-name-update', + 'cm:description': 'folder-description-update' + } + } + ); + }); + + it('should call dialog to close with form data when submit is succesfluly', () => { + const folder = { + data: 'folder-data' + }; + + spyOn(nodesApi, 'updateNode').and.returnValue(Observable.of(folder)); + + component.submit(); + + expect(dialogRef.close).toHaveBeenCalledWith(folder); + }); + + it('should not submit if form is invalid', () => { + spyOn(nodesApi, 'updateNode'); + + component.form.controls['name'].setValue(''); + component.form.controls['description'].setValue(''); + + component.submit(); + + expect(component.form.valid).toBe(false); + expect(nodesApi.updateNode).not.toHaveBeenCalled(); + }); + + it('should not call dialog to close if submit fails', () => { + spyOn(nodesApi, 'updateNode').and.returnValue(Observable.throw('error')); + spyOn(component, 'handleError').and.callFake(val => val); + + component.submit(); + + expect(component.handleError).toHaveBeenCalled(); + expect(dialogRef.close).not.toHaveBeenCalled(); + }); + }); + + describe('Create', () => { + beforeEach(() => { + component.data = { + parentNodeId: 'parentNodeId', + folder: null + }; + fixture.detectChanges(); + }); + + it('should init form with empty inputs', () => { + expect(component.name).toBe(''); + expect(component.description).toBe(''); + }); + + it('should update form input', () => { + component.form.controls['name'].setValue('folder-name-update'); + component.form.controls['description'].setValue('folder-description-update'); + + expect(component.name).toBe('folder-name-update'); + expect(component.description).toBe('folder-description-update'); + }); + + it('should submit updated values if form is valid', () => { + spyOn(nodesApi, 'createFolder').and.returnValue(Observable.of({})); + + component.form.controls['name'].setValue('folder-name-update'); + component.form.controls['description'].setValue('folder-description-update'); + + component.submit(); + + expect(nodesApi.createFolder).toHaveBeenCalledWith( + 'parentNodeId', + { + name: 'folder-name-update', + properties: { + 'cm:title': 'folder-name-update', + 'cm:description': 'folder-description-update' + } + } + ); + }); + + it('should call dialog to close with form data when submit is succesfluly', () => { + const folder = { + data: 'folder-data' + }; + + component.form.controls['name'].setValue('name'); + component.form.controls['description'].setValue('description'); + + spyOn(nodesApi, 'createFolder').and.returnValue(Observable.of(folder)); + + component.submit(); + + expect(dialogRef.close).toHaveBeenCalledWith(folder); + }); + + it('should not submit if form is invalid', () => { + spyOn(nodesApi, 'createFolder'); + + component.form.controls['name'].setValue(''); + component.form.controls['description'].setValue(''); + + component.submit(); + + expect(component.form.valid).toBe(false); + expect(nodesApi.createFolder).not.toHaveBeenCalled(); + }); + + it('should not call dialog to close if submit fails', () => { + spyOn(nodesApi, 'createFolder').and.returnValue(Observable.throw('error')); + spyOn(component, 'handleError').and.callFake(val => val); + + component.form.controls['name'].setValue('name'); + component.form.controls['description'].setValue('description'); + + component.submit(); + + expect(component.handleError).toHaveBeenCalled(); + expect(dialogRef.close).not.toHaveBeenCalled(); + }); + }); + + describe('handleError()', () => { + it('should raise error for 409', () => { + spyOn(notificationService, 'openSnackMessage').and.stub(); + + const error = { + message: '{ "error": { "statusCode" : 409 } }' + }; + + component.handleError(error); + + expect(notificationService.openSnackMessage).toHaveBeenCalled(); + expect(translationService.get).toHaveBeenCalledWith('CORE.MESSAGES.ERRORS.EXISTENT_FOLDER'); + }); + + it('should raise generic error', () => { + spyOn(notificationService, 'openSnackMessage').and.stub(); + + const error = { + message: '{ "error": { "statusCode" : 123 } }' + }; + + component.handleError(error); + + expect(notificationService.openSnackMessage).toHaveBeenCalled(); + expect(translationService.get).toHaveBeenCalledWith('CORE.MESSAGES.ERRORS.GENERIC'); + }); + }); +}); diff --git a/ng2-components/ng2-alfresco-core/src/dialogs/folder.dialog.ts b/ng2-components/ng2-alfresco-core/src/dialogs/folder.dialog.ts new file mode 100644 index 0000000000..2a2b1d144d --- /dev/null +++ b/ng2-components/ng2-alfresco-core/src/dialogs/folder.dialog.ts @@ -0,0 +1,142 @@ +/*! + * @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 { Observable } from 'rxjs/Rx'; + +import { Component, Inject, OnInit, Optional } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material'; + +import { MinimalNodeEntryEntity } from 'alfresco-js-api'; +import { NodesApiService } from '../services/nodes-api.service'; +import { NotificationService } from '../services/notification.service'; +import { TranslationService } from '../services/translation.service'; + +import { forbidEndingDot, forbidOnlySpaces, forbidSpecialCharacters } from './folder-name.validators'; + +@Component({ + selector: 'adf-folder-dialog', + styleUrls: ['./folder.dialog.scss'], + templateUrl: './folder.dialog.html' +}) +export class FolderDialogComponent implements OnInit { + form: FormGroup; + folder: MinimalNodeEntryEntity = null; + + constructor( + private formBuilder: FormBuilder, + private dialog: MatDialogRef, + private nodesApi: NodesApiService, + private translation: TranslationService, + private notification: NotificationService, + @Optional() + @Inject(MAT_DIALOG_DATA) + public data: any + ) {} + + get editing(): boolean { + return !!this.data.folder; + } + + ngOnInit() { + const { folder } = this.data; + let name = ''; + let description = ''; + + if (folder) { + const { properties } = folder; + + name = folder.name || ''; + description = properties ? properties['cm:description'] : ''; + } + + const validators = { + name: [ + Validators.required, + forbidSpecialCharacters, + forbidEndingDot, + forbidOnlySpaces + ] + }; + + this.form = this.formBuilder.group({ + name: [ name, validators.name ], + description: [ description ] + }); + } + + get name(): string { + let { name } = this.form.value; + + return (name || '').trim(); + } + + get description(): string { + let { description } = this.form.value; + + return (description || '').trim(); + } + + private get properties(): any { + const { name: title, description } = this; + + return { + 'cm:title': title, + 'cm:description': description + }; + } + + private create(): Observable { + const { name, properties, nodesApi, data: { parentNodeId} } = this; + return nodesApi.createFolder(parentNodeId, { name, properties }); + } + + private edit(): Observable { + const { name, properties, nodesApi, data: { folder: { id: nodeId }} } = this; + return nodesApi.updateNode(nodeId, { name, properties }); + } + + submit() { + const { form, dialog, editing } = this; + + if (!form.valid) { return; } + + (editing ? this.edit() : this.create()) + .subscribe( + (folder: MinimalNodeEntryEntity) => dialog.close(folder), + (error) => this.handleError(error) + ); + } + + handleError(error: any): any { + let i18nMessageString = 'CORE.MESSAGES.ERRORS.GENERIC'; + + try { + const { error: { statusCode } } = JSON.parse(error.message); + + if (statusCode === 409) { + i18nMessageString = 'CORE.MESSAGES.ERRORS.EXISTENT_FOLDER'; + } + } catch (err) { /* Do nothing, keep the original message */ } + + this.translation.get(i18nMessageString).subscribe(message => { + this.notification.openSnackMessage(message, 3000); + }); + + return error; + } +} diff --git a/ng2-components/ng2-alfresco-core/src/directives/folder-create.directive.spec.ts b/ng2-components/ng2-alfresco-core/src/directives/folder-create.directive.spec.ts new file mode 100644 index 0000000000..bbcbe480ee --- /dev/null +++ b/ng2-components/ng2-alfresco-core/src/directives/folder-create.directive.spec.ts @@ -0,0 +1,115 @@ +/*! + * @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 { ComponentFixture, TestBed } from '@angular/core/testing'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { HttpModule } from '@angular/http'; +import { MatDialog, MatDialogModule } from '@angular/material'; +import { By } from '@angular/platform-browser'; +import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; +import { Observable } from 'rxjs/Rx'; + +import { AppConfigService, providers } from '../../index'; +import { AlfrescoContentService } from '../services/alfresco-content.service'; +import { AlfrescoTranslateLoader } from '../services/translate-loader.service'; +import { FolderCreateDirective } from './folder-create.directive'; + +@Component({ + template: '
' +}) +class TestComponent { + parentNode = ''; +} + +describe('FolderCreateDirective', () => { + let fixture: ComponentFixture; + let element; + let node: any; + let dialog: MatDialog; + let contentService: AlfrescoContentService; + let dialogRefMock; + + const event: any = { + type: 'click', + preventDefault: () => null + }; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [ + HttpModule, + MatDialogModule, + FormsModule, + ReactiveFormsModule, + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useClass: AlfrescoTranslateLoader + } + }) + ], + declarations: [ + TestComponent, + FolderCreateDirective + ], + providers: [ + AlfrescoContentService, + AppConfigService, + ...providers() + ] + }); + + TestBed.compileComponents(); + + fixture = TestBed.createComponent(TestComponent); + element = fixture.debugElement.query(By.directive(FolderCreateDirective)); + dialog = TestBed.get(MatDialog); + contentService = TestBed.get(AlfrescoContentService); + }); + + beforeEach(() => { + node = { entry: { id: 'nodeId' } }; + + dialogRefMock = { + afterClosed: val => Observable.of(val) + }; + + spyOn(dialog, 'open').and.returnValue(dialogRefMock); + }); + + it('should emit folderCreate event when input value is not undefined', () => { + spyOn(dialogRefMock, 'afterClosed').and.returnValue(Observable.of(node)); + + contentService.folderCreate.subscribe((val) => { + expect(val).toBe(node); + }); + + element.triggerEventHandler('click', event); + fixture.detectChanges(); + }); + + it('should not emit folderCreate event when input value is undefined', () => { + spyOn(dialogRefMock, 'afterClosed').and.returnValue(Observable.of(null)); + spyOn(contentService.folderCreate, 'next'); + + element.triggerEventHandler('click', event); + fixture.detectChanges(); + + expect(contentService.folderCreate.next).not.toHaveBeenCalled(); + }); +}); diff --git a/ng2-components/ng2-alfresco-core/src/directives/folder-create.directive.ts b/ng2-components/ng2-alfresco-core/src/directives/folder-create.directive.ts new file mode 100644 index 0000000000..4b68b13ab6 --- /dev/null +++ b/ng2-components/ng2-alfresco-core/src/directives/folder-create.directive.ts @@ -0,0 +1,68 @@ +/*! + * @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, HostListener, Input } from '@angular/core'; +import { MatDialog, MatDialogConfig } from '@angular/material'; + +import { MinimalNodeEntryEntity } from 'alfresco-js-api'; + +import { FolderDialogComponent } from '../dialogs/folder.dialog'; +import { AlfrescoContentService } from '../services/alfresco-content.service'; + +const DEFAULT_FOLDER_PARENT_ID = '-my-'; + +@Directive({ + selector: '[adf-create-folder]' +}) +export class FolderCreateDirective { + static DIALOG_WIDTH: number = 400; + + @Input('adf-create-folder') + parentNodeId: string = DEFAULT_FOLDER_PARENT_ID; + + @HostListener('click', [ '$event' ]) + onClick(event) { + event.preventDefault(); + this.openDialog(); + } + + constructor( + public dialogRef: MatDialog, + public content: AlfrescoContentService + ) {} + + private get dialogConfig(): MatDialogConfig { + const { DIALOG_WIDTH: width } = FolderCreateDirective; + const { parentNodeId } = this; + + return { + data: { parentNodeId }, + width: `${width}px` + }; + } + + private openDialog(): void { + const { dialogRef, dialogConfig, content } = this; + const dialogInstance = dialogRef.open(FolderDialogComponent, dialogConfig); + + dialogInstance.afterClosed().subscribe((node: MinimalNodeEntryEntity) => { + if (node) { + content.folderCreate.next(node); + } + }); + } +} diff --git a/ng2-components/ng2-alfresco-core/src/directives/folder-edit.directive.spec.ts b/ng2-components/ng2-alfresco-core/src/directives/folder-edit.directive.spec.ts new file mode 100644 index 0000000000..75e161d7d5 --- /dev/null +++ b/ng2-components/ng2-alfresco-core/src/directives/folder-edit.directive.spec.ts @@ -0,0 +1,117 @@ +/*! + * @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 { ComponentFixture, TestBed } from '@angular/core/testing'; +import { HttpModule } from '@angular/http'; +import { MatDialog, MatDialogModule } from '@angular/material'; +import { By } from '@angular/platform-browser'; + +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; +import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; +import { Observable } from 'rxjs/Rx'; + +import { AppConfigService, providers } from '../../index'; +import { AlfrescoContentService } from '../services/alfresco-content.service'; +import { AlfrescoTranslateLoader } from '../services/translate-loader.service'; +import { FolderEditDirective } from './folder-edit.directive'; + +@Component({ + template: '
' +}) +class TestComponent { + folder = {}; +} + +describe('FolderEditDirective', () => { + let fixture: ComponentFixture; + let element; + let node: any; + let dialog: MatDialog; + let contentService: AlfrescoContentService; + let dialogRefMock; + + const event = { + type: 'click', + preventDefault: () => null + }; + + beforeEach(() => { + TestBed.configureTestingModule({ + imports: [ + HttpModule, + MatDialogModule, + FormsModule, + ReactiveFormsModule, + TranslateModule.forRoot({ + loader: { + provide: TranslateLoader, + useClass: AlfrescoTranslateLoader + } + }) + ], + declarations: [ + TestComponent, + FolderEditDirective + ] + , + providers: [ + AlfrescoContentService, + AppConfigService, + ...providers() + ] + }); + + TestBed.compileComponents(); + + fixture = TestBed.createComponent(TestComponent); + element = fixture.debugElement.query(By.directive(FolderEditDirective)); + dialog = TestBed.get(MatDialog); + contentService = TestBed.get(AlfrescoContentService); + }); + + beforeEach(() => { + node = { entry: { id: 'folderId' } }; + + dialogRefMock = { + afterClosed: val => Observable.of(val) + }; + + spyOn(dialog, 'open').and.returnValue(dialogRefMock); + }); + + it('should emit folderEdit event when input value is not undefined', () => { + spyOn(dialogRefMock, 'afterClosed').and.returnValue(Observable.of(node)); + + contentService.folderEdit.subscribe((val) => { + expect(val).toBe(node); + }); + + element.triggerEventHandler('click', event); + fixture.detectChanges(); + }); + + it('should not emit folderEdit event when input value is undefined', () => { + spyOn(dialogRefMock, 'afterClosed').and.returnValue(Observable.of(null)); + spyOn(contentService.folderEdit, 'next'); + + element.triggerEventHandler('click', event); + fixture.detectChanges(); + + expect(contentService.folderEdit.next).not.toHaveBeenCalled(); + }); +}); diff --git a/ng2-components/ng2-alfresco-core/src/directives/folder-edit.directive.ts b/ng2-components/ng2-alfresco-core/src/directives/folder-edit.directive.ts new file mode 100644 index 0000000000..42f56ed418 --- /dev/null +++ b/ng2-components/ng2-alfresco-core/src/directives/folder-edit.directive.ts @@ -0,0 +1,69 @@ +/*! + * @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, HostListener, Input } from '@angular/core'; +import { MatDialog, MatDialogConfig } from '@angular/material'; + +import { MinimalNodeEntryEntity } from 'alfresco-js-api'; + +import { FolderDialogComponent } from '../dialogs/folder.dialog'; +import { AlfrescoContentService } from '../services/alfresco-content.service'; + +@Directive({ + selector: '[adf-edit-folder]' +}) +export class FolderEditDirective { + static DIALOG_WIDTH: number = 400; + + @Input('adf-edit-folder') + folder: MinimalNodeEntryEntity; + + @HostListener('click', [ '$event' ]) + onClick(event) { + event.preventDefault(); + if (this.folder) { + this.openDialog(); + } + } + + constructor( + public dialogRef: MatDialog, + public elementRef: ElementRef, + public content: AlfrescoContentService + ) {} + + private get dialogConfig(): MatDialogConfig { + const { DIALOG_WIDTH: width } = FolderEditDirective; + const { folder } = this; + + return { + data: { folder }, + width: `${width}px` + }; + } + + private openDialog(): void { + const { dialogRef, dialogConfig, content } = this; + const dialogInstance = dialogRef.open(FolderDialogComponent, dialogConfig); + + dialogInstance.afterClosed().subscribe((node: MinimalNodeEntryEntity) => { + if (node) { + content.folderEdit.next(node); + } + }); + } +} diff --git a/ng2-components/ng2-alfresco-core/src/i18n/de.json b/ng2-components/ng2-alfresco-core/src/i18n/de.json index 29ee58a5e4..e27595fad8 100644 --- a/ng2-components/ng2-alfresco-core/src/i18n/de.json +++ b/ng2-components/ng2-alfresco-core/src/i18n/de.json @@ -4,14 +4,45 @@ "ITEMS_RANGE": "Angezeigt werden {{ range }} von {{ total }}", "ITEMS_PER_PAGE": "Elemente pro Seite", "CURRENT_PAGE": "Seite {{ number }}", - "TOTAL_PAGES": "von {{ total }}", - "HOST_SETTINGS": { - "TITLE": "Einstellungen", - "CS-HOST": "Konfiguration der Host-URL für Content Services", - "BP-HOST": "Konfiguration der Host-URL für Process Services", - "BACK": "Zurück", - "APPLY": "ANWENDEN" + "TOTAL_PAGES": "von {{ total }}" + }, + "FOLDER_DIALOG": { + "CREATE_FOLDER_TITLE": "Neuen Ordner erstellen", + "EDIT_FOLDER_TITLE": "Ordner bearbeiten", + "FOLDER_NAME": { + "LABEL": "Name", + "ERRORS": { + "REQUIRED": "Ordnername ist erforderlich", + "SPECIAL_CHARACTERS": "Ordnername darf die folgenden Zeichen nicht enthalten: * \" < > \\ / ? : |", + "ENDING_DOT": "Ordnername darf nicht mit einem Punkt enden.", + "ONLY_SPACES": "Ordnername darf nicht nur aus Leerzeichen bestehen." + } + }, + "FOLDER_DESCRIPTION": { + "LABEL": "Beschreibung" + }, + "CREATE_BUTTON": { + "LABEL": "Erstellen" + }, + "UPDATE_BUTTON": { + "LABEL": "Aktualisieren" + }, + "CANCEL_BUTTON": { + "LABEL": "Abbrechen" } + }, + "MESSAGES": { + "ERRORS": { + "GENERIC": "Die Aktion war nicht erfolgreich. Versuchen Sie es noch einmal oder wenden Sie sich an Ihr IT-Team.", + "EXISTENT_FOLDER": "Es gibt bereits einen Ordner mit diesem Namen. Probieren Sie es mit einem anderen Namen." + } + }, + "HOST_SETTINGS": { + "TITLE": "Einstellungen", + "CS-HOST": "Konfiguration der Host-URL für Content Services", + "BP-HOST": "Konfiguration der Host-URL für Process Services", + "BACK": "Zurück", + "APPLY": "ANWENDEN" } } } diff --git a/ng2-components/ng2-alfresco-core/src/i18n/en.json b/ng2-components/ng2-alfresco-core/src/i18n/en.json index a502588236..99ca30bfff 100644 --- a/ng2-components/ng2-alfresco-core/src/i18n/en.json +++ b/ng2-components/ng2-alfresco-core/src/i18n/en.json @@ -1,45 +1,76 @@ { - "CORE": { - "PAGINATION": { - "ITEMS_RANGE": "Showing {{ range }} of {{ total }}", - "ITEMS_PER_PAGE": "Items per page", - "CURRENT_PAGE": "Page {{ number }}", - "TOTAL_PAGES": "of {{ total }}" + "CORE": { + "PAGINATION": { + "ITEMS_RANGE": "Showing {{ range }} of {{ total }}", + "ITEMS_PER_PAGE": "Items per page", + "CURRENT_PAGE": "Page {{ number }}", + "TOTAL_PAGES": "of {{ total }}" + }, + "DIALOG": { + "DOWNLOAD_ZIP": { + "ACTIONS": { + "CANCEL": "Cancel" }, - "DIALOG": { - "DOWNLOAD_ZIP": { - "ACTIONS": { - "CANCEL": "Cancel" - }, - "TITLE": "Adding files to zip, this could take a few minutes" - } - }, - "RESTORE_NODE": { - "VIEW": "View", - "PARTIAL_PLURAL": "{{ number }} items not restored because of issues with the restore location", - "NODE_EXISTS": "Can't restore, {{ name }} item already exists", - "LOCATION_MISSING": "Can't restore {{ name }} item, the original location no longer exists", - "GENERIC": "There was a problem restoring {{ name }} item", - "PLURAL": "Restore successful", - "SINGULAR": "{{ name }} item restored" - }, - "DELETE_NODE": { - "SINGULAR": "{{ name }} deleted", - "PLURAL": "{{ number }} items deleted", - "PARTIAL_SINGULAR": "Deleted {{ success }} item, {{ failed }} couldn't be deleted", - "PARTIAL_PLURAL": "Deleted {{ success }} items, {{ failed }} couldn't be deleted", - "ERROR_SINGULAR": "{{ name }} couldn't be deleted", - "ERROR_PLURAL": "{{ number }} items couldn't be deleted" - }, - "HOST_SETTINGS" : { - "CS_URL_ERROR":"Content service address does not match the pattern", - "PS_URL_ERROR":"Process service address does not match the pattern", - "TITLE": "Settings", - "CS-HOST": "Content Services host URL configuration", - "BP-HOST": "Process Services host URL configuration", - "BACK": "Back", - "APPLY": "APPLY", - "NOT_VALID": "Host not valid! http(s)://host|ip:port(/path)" + "TITLE": "Adding files to zip, this could take a few minutes" + } + }, + "FOLDER_DIALOG": { + "CREATE_FOLDER_TITLE": "Create new folder", + "EDIT_FOLDER_TITLE": "Edit folder", + "FOLDER_NAME": { + "LABEL": "Name", + "ERRORS": { + "REQUIRED": "Folder name is required", + "SPECIAL_CHARACTERS": "Folder name can't contain these characters * \" < > \\ / ? : |", + "ENDING_DOT": "Folder name can't end with a period .", + "ONLY_SPACES": "Folder name can't contain only spaces" } + }, + "FOLDER_DESCRIPTION": { + "LABEL": "Description" + }, + "CREATE_BUTTON": { + "LABEL": "Create" + }, + "UPDATE_BUTTON": { + "LABEL": "Update" + }, + "CANCEL_BUTTON": { + "LABEL": "Cancel" + } + }, + "MESSAGES": { + "ERRORS": { + "GENERIC": "The action was unsuccessful. Try again or contact your IT Team.", + "EXISTENT_FOLDER": "There's already a folder with this name. Try a different name." + } + }, + "RESTORE_NODE": { + "VIEW": "View", + "PARTIAL_PLURAL": "{{ number }} items not restored because of issues with the restore location", + "NODE_EXISTS": "Can't restore, {{ name }} item already exists", + "LOCATION_MISSING": "Can't restore {{ name }} item, the original location no longer exists", + "GENERIC": "There was a problem restoring {{ name }} item", + "PLURAL": "Restore successful", + "SINGULAR": "{{ name }} item restored" + }, + "DELETE_NODE": { + "SINGULAR": "{{ name }} deleted", + "PLURAL": "{{ number }} items deleted", + "PARTIAL_SINGULAR": "Deleted {{ success }} item, {{ failed }} couldn't be deleted", + "PARTIAL_PLURAL": "Deleted {{ success }} items, {{ failed }} couldn't be deleted", + "ERROR_SINGULAR": "{{ name }} couldn't be deleted", + "ERROR_PLURAL": "{{ number }} items couldn't be deleted" + }, + "HOST_SETTINGS": { + "CS_URL_ERROR": "Content service address does not match the pattern", + "PS_URL_ERROR": "Process service address does not match the pattern", + "TITLE": "Settings", + "CS-HOST": "Content Services host URL configuration", + "BP-HOST": "Process Services host URL configuration", + "BACK": "Back", + "APPLY": "APPLY", + "NOT_VALID": "Host not valid! http(s)://host|ip:port(/path)" } + } } diff --git a/ng2-components/ng2-alfresco-core/src/i18n/es.json b/ng2-components/ng2-alfresco-core/src/i18n/es.json index e90b6dc2b1..6edffceba8 100644 --- a/ng2-components/ng2-alfresco-core/src/i18n/es.json +++ b/ng2-components/ng2-alfresco-core/src/i18n/es.json @@ -6,6 +6,37 @@ "CURRENT_PAGE": "Página {{ number }}", "TOTAL_PAGES": "de {{ total }}" }, + "FOLDER_DIALOG": { + "CREATE_FOLDER_TITLE": "Crear nueva carpeta", + "EDIT_FOLDER_TITLE": "Editar carpeta", + "FOLDER_NAME": { + "LABEL": "Nombre", + "ERRORS": { + "REQUIRED": "Se necesita un nombre de carpeta", + "SPECIAL_CHARACTERS": "El nombre de la carpeta no puede tener los caracteres * \" < > \\ / ? : |", + "ENDING_DOT": "El nombre de la carpeta no puede terminar en punto .", + "ONLY_SPACES": "El nombre de la carpeta no puede tener solo espacios" + } + }, + "FOLDER_DESCRIPTION": { + "LABEL": "Descripción" + }, + "CREATE_BUTTON": { + "LABEL": "Crear" + }, + "UPDATE_BUTTON": { + "LABEL": "Actualizar" + }, + "CANCEL_BUTTON": { + "LABEL": "Cancelar" + } + }, + "MESSAGES": { + "ERRORS": { + "GENERIC": "La acción no ha sido satisfactoria. Vuelva a intentarlo o póngase en contacto con el equipo de TI.", + "EXISTENT_FOLDER": "Ya existe una carpeta con este nombre. Pruebe un nombre diferente." + } + }, "HOST_SETTINGS": { "TITLE": "Configuración", "CS-HOST": "Configuración de URL de host de Content Services", diff --git a/ng2-components/ng2-alfresco-core/src/i18n/fr.json b/ng2-components/ng2-alfresco-core/src/i18n/fr.json index ca37851c0d..4648c221df 100644 --- a/ng2-components/ng2-alfresco-core/src/i18n/fr.json +++ b/ng2-components/ng2-alfresco-core/src/i18n/fr.json @@ -6,12 +6,43 @@ "CURRENT_PAGE": "Page {{ number }}", "TOTAL_PAGES": "sur {{ total }}" }, + "FOLDER_DIALOG": { + "CREATE_FOLDER_TITLE": "Créer un nouveau filtre", + "EDIT_FOLDER_TITLE": "Modifier le dossier", + "FOLDER_NAME": { + "LABEL": "Nom", + "ERRORS": { + "REQUIRED": "Nom de dossier requis", + "SPECIAL_CHARACTERS": "Un nom de dossier ne peut pas contenir les caractères * \" < > \\ / ? : |", + "ENDING_DOT": "Un nom de dossier ne peut pas se terminer par un point .", + "ONLY_SPACES": "Un nom de dossier ne peut pas contenir uniquement des espaces" + } + }, + "FOLDER_DESCRIPTION": { + "LABEL": "Description" + }, + "CREATE_BUTTON": { + "LABEL": "Créer" + }, + "UPDATE_BUTTON": { + "LABEL": "Mis à jour" + }, + "CANCEL_BUTTON": { + "LABEL": "Annuler" + } + }, + "MESSAGES": { + "ERRORS": { + "GENERIC": "L'action a échoué. Réessayez ou contactez le service informatique.", + "EXISTENT_FOLDER": "Un dossier du même nom existe déjà. Essayez avec un nom différent." + } + }, "HOST_SETTINGS": { "TITLE": "Paramètres", "CS-HOST": "Configuration de l'URL de l'hôte de Content Services", "BP-HOST": "Configuration de l'URL de l'hôte de Process Services", "BACK": "Retour", "APPLY": "APPLIQUER" - }, + } } } diff --git a/ng2-components/ng2-alfresco-core/src/i18n/it.json b/ng2-components/ng2-alfresco-core/src/i18n/it.json index b810130457..0f1174b4e1 100644 --- a/ng2-components/ng2-alfresco-core/src/i18n/it.json +++ b/ng2-components/ng2-alfresco-core/src/i18n/it.json @@ -6,6 +6,37 @@ "CURRENT_PAGE": "Pagina {{ number }}", "TOTAL_PAGES": "di {{ total }}" }, + "FOLDER_DIALOG": { + "CREATE_FOLDER_TITLE": "Crea nuova cartella", + "EDIT_FOLDER_TITLE": "Modifica cartella", + "FOLDER_NAME": { + "LABEL": "Nome", + "ERRORS": { + "REQUIRED": "Nome cartella obbligatorio", + "SPECIAL_CHARACTERS": "Il nome della cartella non può contenere questi caratteri * \" < > \\ / ? : |", + "ENDING_DOT": "Il nome della cartella non può terminare con un punto.", + "ONLY_SPACES": "Il nome della cartella non può contenere solo spazi" + } + }, + "FOLDER_DESCRIPTION": { + "LABEL": "Descrizione" + }, + "CREATE_BUTTON": { + "LABEL": "Crea" + }, + "UPDATE_BUTTON": { + "LABEL": "Aggiorna" + }, + "CANCEL_BUTTON": { + "LABEL": "Annulla" + } + }, + "MESSAGES": { + "ERRORS": { + "GENERIC": "Azione non eseguita correttamente. Riprovare o contattare il team IT.", + "EXISTENT_FOLDER": "Esiste già una cartella con questo nome. Provare un nome diverso." + } + }, "HOST_SETTINGS": { "TITLE": "Impostazioni", "CS-HOST": "Configurazione URL host Content Services", diff --git a/ng2-components/ng2-alfresco-core/src/i18n/ja.json b/ng2-components/ng2-alfresco-core/src/i18n/ja.json index 701bc7089d..c216ece41f 100644 --- a/ng2-components/ng2-alfresco-core/src/i18n/ja.json +++ b/ng2-components/ng2-alfresco-core/src/i18n/ja.json @@ -6,6 +6,37 @@ "CURRENT_PAGE": "ページ: {{ number }}", "TOTAL_PAGES": "/ {{ total }}" }, + "FOLDER_DIALOG": { + "CREATE_FOLDER_TITLE": "新しいフォルダの作成", + "EDIT_FOLDER_TITLE": "フォルダの編集", + "FOLDER_NAME": { + "LABEL": "名前", + "ERRORS": { + "REQUIRED": "フォルダ名を指定してください", + "SPECIAL_CHARACTERS": "名前に次の文字を含めることはできません。 * \" < > \\ / ? : |", + "ENDING_DOT": "フォルダ名の最後にピリオド (.) を付けることはできません。", + "ONLY_SPACES": "フォルダ名にスペースだけを含めることはできません" + } + }, + "FOLDER_DESCRIPTION": { + "LABEL": "説明" + }, + "CREATE_BUTTON": { + "LABEL": "作成" + }, + "UPDATE_BUTTON": { + "LABEL": "更新" + }, + "CANCEL_BUTTON": { + "LABEL": "キャンセル" + } + }, + "MESSAGES": { + "ERRORS": { + "GENERIC": "処理が失敗しました。もう一度操作をやり直すか、IT 担当者に連絡してください。", + "EXISTENT_FOLDER": "この名前のフォルダが既に存在します。別の名前を使用してください。" + } + }, "HOST_SETTINGS": { "TITLE": "設定", "CS-HOST": "Content Services ホストの URL の設定", diff --git a/ng2-components/ng2-alfresco-core/src/i18n/nb.json b/ng2-components/ng2-alfresco-core/src/i18n/nb.json index 4ded03b5bb..e3c62c27a4 100644 --- a/ng2-components/ng2-alfresco-core/src/i18n/nb.json +++ b/ng2-components/ng2-alfresco-core/src/i18n/nb.json @@ -6,6 +6,37 @@ "CURRENT_PAGE": "Side {{ number }}", "TOTAL_PAGES": "av {{ total }}" }, + "FOLDER_DIALOG": { + "CREATE_FOLDER_TITLE": "Opprett ny mappe", + "EDIT_FOLDER_TITLE": "Rediger mappe", + "FOLDER_NAME": { + "LABEL": "Navn", + "ERRORS": { + "REQUIRED": "Mappenavn påkrevd", + "SPECIAL_CHARACTERS": "Mappenavn kan ikke inneholde disse tegnene * \" < > \\ / ? : |", + "ENDING_DOT": "Mappenavn kan ikke slutte med punktum .", + "ONLY_SPACES": "Mappenavn kan ikke inneholde bare mellomrom" + } + }, + "FOLDER_DESCRIPTION": { + "LABEL": "Beskrivelse" + }, + "CREATE_BUTTON": { + "LABEL": "Opprett" + }, + "UPDATE_BUTTON": { + "LABEL": "Oppdater" + }, + "CANCEL_BUTTON": { + "LABEL": "Avbryt" + } + }, + "MESSAGES": { + "ERRORS": { + "GENERIC": "Handlingen var mislykket. Prøv på nytt, eller kontakt IT-teamet.", + "EXISTENT_FOLDER": "Det finnes allerede en mappe med det navnet, Prøv med et annet navn." + } + }, "HOST_SETTINGS": { "TITLE": "Innstillinger", "CS-HOST": "Innholdstjenestevert URL-konfigurasjon", diff --git a/ng2-components/ng2-alfresco-core/src/i18n/nl.json b/ng2-components/ng2-alfresco-core/src/i18n/nl.json index 2e0ed1442d..15ef8e2fed 100644 --- a/ng2-components/ng2-alfresco-core/src/i18n/nl.json +++ b/ng2-components/ng2-alfresco-core/src/i18n/nl.json @@ -6,6 +6,37 @@ "CURRENT_PAGE": "Pagina {{ number }}", "TOTAL_PAGES": "van {{ total }}" }, + "FOLDER_DIALOG": { + "CREATE_FOLDER_TITLE": "Nieuwe map maken", + "EDIT_FOLDER_TITLE": "Map bewerken", + "FOLDER_NAME": { + "LABEL": "Naam", + "ERRORS": { + "REQUIRED": "Mapnaam is vereist", + "SPECIAL_CHARACTERS": "Mapnaam mag de volgende tekens niet bevatten: * \" < > \\ / ? : |", + "ENDING_DOT": "Mapnaam mag niet eindigen met een punt .", + "ONLY_SPACES": "Mapnaam mag niet alleen uit spaties bestaan" + } + }, + "FOLDER_DESCRIPTION": { + "LABEL": "Beschrijving" + }, + "CREATE_BUTTON": { + "LABEL": "Maken" + }, + "UPDATE_BUTTON": { + "LABEL": "Bijwerken" + }, + "CANCEL_BUTTON": { + "LABEL": "Annuleren" + } + }, + "MESSAGES": { + "ERRORS": { + "GENERIC": "De actie is mislukt. Probeer het opnieuw of neem contact op met het IT-team.", + "EXISTENT_FOLDER": "Er bestaat al een map met deze naam. Probeer een andere naam." + } + }, "HOST_SETTINGS": { "TITLE": "Instellingen", "CS-HOST": "URL-configuratie Content Services-host", diff --git a/ng2-components/ng2-alfresco-core/src/i18n/pt-BR.json b/ng2-components/ng2-alfresco-core/src/i18n/pt-BR.json index 0d1ff14f6c..162858fac4 100644 --- a/ng2-components/ng2-alfresco-core/src/i18n/pt-BR.json +++ b/ng2-components/ng2-alfresco-core/src/i18n/pt-BR.json @@ -6,6 +6,37 @@ "CURRENT_PAGE": "Página {{ number }}", "TOTAL_PAGES": "de {{ total }}" }, + "FOLDER_DIALOG": { + "CREATE_FOLDER_TITLE": "Criar nova pasta", + "EDIT_FOLDER_TITLE": "Editar pasta", + "FOLDER_NAME": { + "LABEL": "Nome", + "ERRORS": { + "REQUIRED": "O nome da pasta é obrigatório", + "SPECIAL_CHARACTERS": "O nome da pasta não pode conter estes caracteres * \" < > \\ / ? : |", + "ENDING_DOT": "O nome da pasta não pode terminar com ponto final .", + "ONLY_SPACES": "O nome da pasta não pode conter somente espaços" + } + }, + "FOLDER_DESCRIPTION": { + "LABEL": "Descrição" + }, + "CREATE_BUTTON": { + "LABEL": "Criar" + }, + "UPDATE_BUTTON": { + "LABEL": "Atualizar" + }, + "CANCEL_BUTTON": { + "LABEL": "Cancelar" + } + }, + "MESSAGES": { + "ERRORS": { + "GENERIC": "A ação não teve êxito. Tente novamente ou entre em contato com a Equipe de TI.", + "EXISTENT_FOLDER": "Já existe uma pasta com este nome. Tente outro nome." + } + }, "HOST_SETTINGS": { "TITLE": "Configurações", "CS-HOST": "Configuração de URL de host do Content Services", diff --git a/ng2-components/ng2-alfresco-core/src/i18n/ru.json b/ng2-components/ng2-alfresco-core/src/i18n/ru.json index f32663b7a1..4123669fba 100644 --- a/ng2-components/ng2-alfresco-core/src/i18n/ru.json +++ b/ng2-components/ng2-alfresco-core/src/i18n/ru.json @@ -6,6 +6,37 @@ "CURRENT_PAGE": "Страница {{ number }}", "TOTAL_PAGES": "из {{ total }}" }, + "FOLDER_DIALOG": { + "CREATE_FOLDER_TITLE": "Создать новую папку", + "EDIT_FOLDER_TITLE": "Редактировать папку", + "FOLDER_NAME": { + "LABEL": "Имя", + "ERRORS": { + "REQUIRED": "Имя папки является обязательным", + "SPECIAL_CHARACTERS": "Имя папки не может содержать следующие символы * \" < > \\ / ? : |", + "ENDING_DOT": "Имя папки не может заканчиваться точкой .", + "ONLY_SPACES": "Имя папки не может состоять только из пробелов" + } + }, + "FOLDER_DESCRIPTION": { + "LABEL": "Описание" + }, + "CREATE_BUTTON": { + "LABEL": "Создать" + }, + "UPDATE_BUTTON": { + "LABEL": "Обновить" + }, + "CANCEL_BUTTON": { + "LABEL": "Отмена" + } + }, + "MESSAGES": { + "ERRORS": { + "GENERIC": "Действие не выполнено. Повторите попытку или обратитесь к IT-специалистам.", + "EXISTENT_FOLDER": "Папка с таким же именем уже существует. Используйте другое имя." + } + }, "HOST_SETTINGS": { "TITLE": "Параметры", "CS-HOST": "Конфигурация URL-адреса хоста Content Services", diff --git a/ng2-components/ng2-alfresco-core/src/i18n/zh-CN.json b/ng2-components/ng2-alfresco-core/src/i18n/zh-CN.json index 15e9d2c8f4..5a3530de0b 100644 --- a/ng2-components/ng2-alfresco-core/src/i18n/zh-CN.json +++ b/ng2-components/ng2-alfresco-core/src/i18n/zh-CN.json @@ -6,6 +6,37 @@ "CURRENT_PAGE": "第 {{number}} 页", "TOTAL_PAGES": "/共 {{total}} 页" }, + "FOLDER_DIALOG": { + "CREATE_FOLDER_TITLE": "新建文件夹", + "EDIT_FOLDER_TITLE": "编辑文件夹", + "FOLDER_NAME": { + "LABEL": "名称", + "ERRORS": { + "REQUIRED": "需要文件夹名称", + "SPECIAL_CHARACTERS": "文件夹名称不能包含 * \" < > \\ / ? : | 字符", + "ENDING_DOT": "文件夹名称不能以句点结尾。", + "ONLY_SPACES": "文件夹名称不能只包含空格" + } + }, + "FOLDER_DESCRIPTION": { + "LABEL": "说明" + }, + "CREATE_BUTTON": { + "LABEL": "创建" + }, + "UPDATE_BUTTON": { + "LABEL": "更新" + }, + "CANCEL_BUTTON": { + "LABEL": "取消" + } + }, + "MESSAGES": { + "ERRORS": { + "GENERIC": "此操作未成功,请重试或联系您的 IT 团队.", + "EXISTENT_FOLDER": "存在使用此名称的文件夹。请尝试使用其他名称。" + } + }, "HOST_SETTINGS": { "TITLE": "设置", "CS-HOST": "Content Services 主机 URL 配置", diff --git a/ng2-components/ng2-alfresco-core/src/services/alfresco-content.service.ts b/ng2-components/ng2-alfresco-core/src/services/alfresco-content.service.ts index 084ad4c715..576e13eeb4 100644 --- a/ng2-components/ng2-alfresco-core/src/services/alfresco-content.service.ts +++ b/ng2-components/ng2-alfresco-core/src/services/alfresco-content.service.ts @@ -16,7 +16,7 @@ */ import { Injectable } from '@angular/core'; -import { ContentApi } from 'alfresco-js-api'; +import { ContentApi, MinimalNodeEntryEntity } from 'alfresco-js-api'; import { Observable, Subject } from 'rxjs/Rx'; import { FolderCreatedEvent } from '../events/folder-created.event'; import { PermissionsEnum } from '../models/permissions.enum'; @@ -28,6 +28,8 @@ import { LogService } from './log.service'; export class AlfrescoContentService { folderCreated: Subject = new Subject(); + folderCreate: Subject = new Subject(); + folderEdit: Subject = new Subject(); constructor(public authService: AuthenticationService, public apiService: AlfrescoApiService,