[AAE-11496] Move 'content-plugin' to projects folder as 'aca-content' (#2817)

* [AAE-11496] Move content-plugin to projects

* Fix unit test
This commit is contained in:
Bartosz Sekuła
2022-12-20 18:15:34 +01:00
committed by GitHub
parent c87662900e
commit e570ef8da0
263 changed files with 291 additions and 58 deletions

View File

@@ -0,0 +1,56 @@
<h2 mat-dialog-title [innerHTML]="title()"></h2>
<div mat-dialog-content>
<form [formGroup]="form" novalidate>
<mat-form-field class="adf-full-width">
<input
cdkFocusInitial
placeholder="{{ 'NODE_FROM_TEMPLATE.FORM.PLACEHOLDER.NAME' | translate }}"
matInput
formControlName="name"
required
/>
<mat-error *ngIf="form.controls['name'].errors?.message">
{{ form.controls['name'].errors?.message | translate }}
</mat-error>
</mat-form-field>
<mat-form-field class="adf-full-width">
<input
placeholder="{{ 'NODE_FROM_TEMPLATE.FORM.PLACEHOLDER.TITLE' | translate }}"
matInput
formControlName="title"
/>
<mat-error *ngIf="form.controls['title'].hasError('maxlength')">
{{ 'NODE_FROM_TEMPLATE.FORM.ERRORS.TITLE_TOO_LONG' | translate }}
</mat-error>
</mat-form-field>
<mat-form-field class="adf-full-width">
<textarea
matInput
placeholder="{{ 'NODE_FROM_TEMPLATE.FORM.PLACEHOLDER.DESCRIPTION' | translate }}"
rows="2"
formControlName="description"
></textarea>
<mat-error *ngIf="form.controls['description'].hasError('maxlength')">
{{ 'NODE_FROM_TEMPLATE.FORM.ERRORS.DESCRIPTION_TOO_LONG' | translate }}
</mat-error>
</mat-form-field>
</form>
</div>
<div mat-dialog-actions>
<button mat-button mat-dialog-close>
{{ 'NODE_FROM_TEMPLATE.CANCEL' | translate }}
</button>
<button
class="create"
[disabled]="form.invalid"
mat-button
(click)="onSubmit()"
>
{{ 'NODE_FROM_TEMPLATE.CREATE' | translate }}
</button>
</div>

View File

@@ -0,0 +1,57 @@
.aca-create-from-template-dialog {
ng-component {
overflow: visible;
}
.mat-dialog-title {
margin-left: 24px;
margin-right: 24px;
font-size: 20px;
font-style: normal;
font-stretch: normal;
line-height: 1.6;
letter-spacing: -0.5px;
color: var(--theme-text-bold-color);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
.bold {
font-weight: 600;
}
}
.mat-form-field {
margin-bottom: 20px;
}
.mat-dialog-container {
padding-left: 0;
padding-right: 0;
}
.mat-dialog-content {
margin: 0 2px;
overflow: hidden;
}
.mat-dialog-actions {
padding: 8px 22px;
display: flex;
justify-content: flex-end;
color: var(--theme-secondary-text-color);
button {
text-transform: uppercase;
font-weight: normal;
}
.create[disabled] {
opacity: 0.6;
}
.create:enabled {
color: var(--theme-accent-color);
}
}
}

View File

@@ -0,0 +1,164 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* 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 { CreateFromTemplateDialogComponent } from './create-from-template.dialog';
import { TestBed, ComponentFixture } from '@angular/core/testing';
import { AppTestingModule } from '../../testing/app-testing.module';
import { CoreModule, TranslationMock } from '@alfresco/adf-core';
import { MatDialogModule, MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog';
import { Store } from '@ngrx/store';
import { CreateFromTemplate } from '@alfresco/aca-shared/store';
import { Node } from '@alfresco/js-api';
import { TranslateModule } from '@ngx-translate/core';
const text = (length: number) => new Array(length).fill(Math.random().toString().substring(2, 3)).join('');
describe('CreateFileFromTemplateDialogComponent', () => {
let fixture: ComponentFixture<CreateFromTemplateDialogComponent>;
let component: CreateFromTemplateDialogComponent;
let store;
const data = {
id: 'node-id',
name: 'node-name',
isFolder: false,
isFile: true,
properties: {
'cm:title': 'node-title',
'cm:description': ''
}
};
beforeEach(() => {
TestBed.configureTestingModule({
imports: [TranslateModule.forRoot(), CoreModule.forRoot(), AppTestingModule, MatDialogModule],
declarations: [CreateFromTemplateDialogComponent],
providers: [
{
provide: MatDialogRef,
useValue: {
close: jasmine.createSpy('close')
}
},
{
provide: TranslationMock,
useValue: {
instant: jasmine.createSpy('instant')
}
},
{
provide: Store,
useValue: {
dispatch: jasmine.createSpy('dispatch')
}
},
{ provide: MAT_DIALOG_DATA, useValue: {} }
]
});
fixture = TestBed.createComponent(CreateFromTemplateDialogComponent);
store = TestBed.inject(Store);
component = fixture.componentInstance;
component.data = data as Node;
});
it('should populate form with provided dialog data', () => {
fixture.detectChanges();
expect(component.form.controls.name.value).toBe(data.name);
expect(component.form.controls.title.value).toBe(data.properties['cm:title']);
expect(component.form.controls.description.value).toBe(data.properties['cm:description']);
});
it('should invalidate form if required `name` field is invalid', () => {
fixture.detectChanges();
component.form.controls.name.setValue('');
fixture.detectChanges();
expect(component.form.invalid).toBe(true);
});
it('should invalidate form if required `name` field has `only spaces`', () => {
fixture.detectChanges();
component.form.controls.name.setValue(' ');
fixture.detectChanges();
expect(component.form.invalid).toBe(true);
});
it('should invalidate form if required `name` field has `ending dot`', () => {
fixture.detectChanges();
component.form.controls.name.setValue('something.');
fixture.detectChanges();
expect(component.form.invalid).toBe(true);
});
it('should invalidate form if `title` text length is long', () => {
fixture.detectChanges();
component.form.controls.title.setValue(text(260));
fixture.detectChanges();
expect(component.form.invalid).toBe(true);
});
it('should invalidate form if `description` text length is long', () => {
fixture.detectChanges();
component.form.controls.description.setValue(text(520));
fixture.detectChanges();
expect(component.form.invalid).toBe(true);
});
it('should create node from template with form values', () => {
const newNode = {
id: 'node-id',
name: 'new-node-name',
isFolder: false,
isFile: true,
properties: {
'cm:title': 'new-node-title',
'cm:description': 'new-node-description'
}
} as Node;
fixture.detectChanges();
component.form.controls.name.setValue('new-node-name');
component.form.controls.title.setValue('new-node-title');
component.form.controls.description.setValue('new-node-description');
fixture.detectChanges();
component.onSubmit();
expect(store.dispatch['calls'].mostRecent().args[0]).toEqual(new CreateFromTemplate(newNode));
});
});

View File

@@ -0,0 +1,118 @@
/*!
* @license
* Alfresco Example Content Application
*
* Copyright (C) 2005 - 2020 Alfresco Software Limited
*
* This file is part of the Alfresco Example Content Application.
* If the software was purchased under a paid Alfresco license, the terms of
* the paid license agreement will prevail. Otherwise, the software is
* provided under the following open source license terms:
*
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* 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 { Component, ViewEncapsulation, Inject, OnInit } from '@angular/core';
import { MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { Node } from '@alfresco/js-api';
import { UntypedFormBuilder, UntypedFormGroup, Validators, UntypedFormControl, ValidationErrors } from '@angular/forms';
import { Store } from '@ngrx/store';
import { AppStore, CreateFromTemplate } from '@alfresco/aca-shared/store';
import { TranslationService } from '@alfresco/adf-core';
@Component({
templateUrl: './create-from-template.dialog.html',
styleUrls: ['./create-from-template.dialog.scss'],
encapsulation: ViewEncapsulation.None
})
export class CreateFromTemplateDialogComponent implements OnInit {
public form: UntypedFormGroup;
constructor(
private translationService: TranslationService,
private store: Store<AppStore>,
private formBuilder: UntypedFormBuilder,
private dialogRef: MatDialogRef<CreateFromTemplateDialogComponent>,
@Inject(MAT_DIALOG_DATA) public data: Node
) {}
ngOnInit() {
this.form = this.formBuilder.group({
name: [this.data.name, [Validators.required, this.forbidEndingDot, this.forbidOnlySpaces, this.forbidSpecialCharacters]],
title: [this.data.properties ? this.data.properties['cm:title'] : '', Validators.maxLength(256)],
description: [this.data.properties ? this.data.properties['cm:description'] : '', Validators.maxLength(512)]
});
}
onSubmit() {
const update = {
name: this.form.value.name.trim(),
properties: {
'cm:title': this.form.value.title,
'cm:description': this.form.value.description
}
};
const data: Node = Object.assign({}, this.data, update);
this.store.dispatch(new CreateFromTemplate(data));
}
title(): string {
if (this.data.isFolder) {
return this.translationService.instant('NODE_FROM_TEMPLATE.FOLDER_DIALOG_TITLE', { template: this.data.name });
}
return this.translationService.instant('NODE_FROM_TEMPLATE.FILE_DIALOG_TITLE', { template: this.data.name });
}
close() {
this.dialogRef.close();
}
private forbidSpecialCharacters({ value }: UntypedFormControl): ValidationErrors | null {
const specialCharacters = /([\*\"\<\>\\\/\?\:\|])/;
const isValid = !specialCharacters.test(value);
return isValid
? null
: {
message: `NODE_FROM_TEMPLATE.FORM.ERRORS.SPECIAL_CHARACTERS`
};
}
private forbidEndingDot({ value }: UntypedFormControl): ValidationErrors | null {
const isValid: boolean = (value || '').trim().split('').pop() !== '.';
return isValid
? null
: {
message: `NODE_FROM_TEMPLATE.FORM.ERRORS.ENDING_DOT`
};
}
private forbidOnlySpaces({ value }: UntypedFormControl): ValidationErrors | null {
if (value.length) {
const isValid = !!(value || '').trim();
return isValid
? null
: {
message: `NODE_FROM_TEMPLATE.FORM.ERRORS.ONLY_SPACES`
};
} else {
return {
message: `NODE_FROM_TEMPLATE.FORM.ERRORS.REQUIRED`
};
}
}
}