mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2025-05-12 17:04:57 +00:00
AAE-28106 Make the header ( label + style ) optional with a checkbox [Preview/Runtime display] (#10408)
* AAE-28106 Update ContainerModel * AAE-28106 Update HeaderWidgetComponent * AAE-28106 Reorganize span element * AAE-28106 Update tests
This commit is contained in:
parent
b4516bc998
commit
beaf86d987
@ -17,13 +17,154 @@
|
|||||||
|
|
||||||
import { ContainerModel } from './container.model';
|
import { ContainerModel } from './container.model';
|
||||||
import { FormFieldModel } from './form-field.model';
|
import { FormFieldModel } from './form-field.model';
|
||||||
import { FormModel } from './form.model';
|
import { FormFieldTypes } from './form-field-types';
|
||||||
|
|
||||||
describe('ContainerModel', () => {
|
describe('ContainerModel', () => {
|
||||||
|
let field: FormFieldModel;
|
||||||
|
|
||||||
it('should store the form reference', () => {
|
beforeEach(() => {
|
||||||
const form = new FormModel();
|
field = new FormFieldModel(null, {
|
||||||
const model = new ContainerModel(new FormFieldModel(form));
|
id: 'group-id',
|
||||||
expect(model.form).toBe(form);
|
name: 'group-name',
|
||||||
|
type: FormFieldTypes.GROUP,
|
||||||
|
params: {
|
||||||
|
allowCollapse: false,
|
||||||
|
collapseByDefault: false,
|
||||||
|
hideHeader: false
|
||||||
|
},
|
||||||
|
numberOfColumns: 1,
|
||||||
|
tab: null
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should initialize with default values', () => {
|
||||||
|
const container = new ContainerModel(field);
|
||||||
|
|
||||||
|
expect(container.field).toBe(field);
|
||||||
|
expect(container.columns).toEqual([]);
|
||||||
|
expect(container.isExpanded).toBe(true);
|
||||||
|
expect(container.rowspan).toBe(1);
|
||||||
|
expect(container.colspan).toBe(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isVisible getter', () => {
|
||||||
|
it('should return true when field is visible', () => {
|
||||||
|
const container = new ContainerModel(field);
|
||||||
|
|
||||||
|
expect(container.isVisible).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when field is NOT visible', () => {
|
||||||
|
field.isVisible = false;
|
||||||
|
const container = new ContainerModel(field);
|
||||||
|
|
||||||
|
expect(container.isVisible).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isTypeFieldGroup getter', () => {
|
||||||
|
it('should return true when field is a group', () => {
|
||||||
|
const container = new ContainerModel(field);
|
||||||
|
|
||||||
|
expect(container.isTypeFieldGroup).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when field is NOT a group', () => {
|
||||||
|
const container = new ContainerModel(new FormFieldModel(null, { type: FormFieldTypes.CONTAINER }));
|
||||||
|
|
||||||
|
expect(container.isTypeFieldGroup).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isCollapsible getter', () => {
|
||||||
|
it('should return false when field is NOT a group', () => {
|
||||||
|
const container = new ContainerModel(new FormFieldModel(null, { type: FormFieldTypes.CONTAINER }));
|
||||||
|
|
||||||
|
expect(container.isTypeFieldGroup).toBe(false);
|
||||||
|
expect(container.isCollapsible).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when field is group and allowCollapse is false', () => {
|
||||||
|
const container = new ContainerModel(field);
|
||||||
|
|
||||||
|
expect(container.isTypeFieldGroup).toBe(true);
|
||||||
|
expect(container.isCollapsible).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return true when field is a group and allowCollapse is true', () => {
|
||||||
|
field.params.allowCollapse = true;
|
||||||
|
const container = new ContainerModel(field);
|
||||||
|
|
||||||
|
expect(container.isTypeFieldGroup).toBe(true);
|
||||||
|
expect(container.isCollapsible).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when field is a group and allowCollapse is NOT set', () => {
|
||||||
|
field.params.allowCollapse = undefined;
|
||||||
|
const container = new ContainerModel(field);
|
||||||
|
|
||||||
|
expect(container.isTypeFieldGroup).toBe(true);
|
||||||
|
expect(container.isCollapsible).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('isCollapsedByDefault getter', () => {
|
||||||
|
it('should return false when field is NOT a group', () => {
|
||||||
|
const container = new ContainerModel(new FormFieldModel(null, { type: FormFieldTypes.CONTAINER }));
|
||||||
|
|
||||||
|
expect(container.isTypeFieldGroup).toBe(false);
|
||||||
|
expect(container.isCollapsedByDefault).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when field is group and collapseByDefault is false', () => {
|
||||||
|
const container = new ContainerModel(field);
|
||||||
|
|
||||||
|
expect(container.isTypeFieldGroup).toBe(true);
|
||||||
|
expect(container.isCollapsedByDefault).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return true when field is a group and collapseByDefault is true', () => {
|
||||||
|
field.params.collapseByDefault = true;
|
||||||
|
const container = new ContainerModel(field);
|
||||||
|
|
||||||
|
expect(container.isTypeFieldGroup).toBe(true);
|
||||||
|
expect(container.isCollapsedByDefault).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when field is a group and collapseByDefault is NOT set', () => {
|
||||||
|
field.params.collapseByDefault = undefined;
|
||||||
|
const container = new ContainerModel(field);
|
||||||
|
|
||||||
|
expect(container.isTypeFieldGroup).toBe(true);
|
||||||
|
expect(container.isCollapsedByDefault).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('hideHeader getter', () => {
|
||||||
|
it('should return false when field is NOT a group', () => {
|
||||||
|
const container = new ContainerModel(new FormFieldModel(null, { type: FormFieldTypes.CONTAINER }));
|
||||||
|
|
||||||
|
expect(container.hideHeader).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when field is a group and hideHeader is false', () => {
|
||||||
|
const container = new ContainerModel(field);
|
||||||
|
|
||||||
|
expect(container.hideHeader).toBe(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return true when field is a group and hideHeader is true', () => {
|
||||||
|
field.params.hideHeader = true;
|
||||||
|
const container = new ContainerModel(field);
|
||||||
|
|
||||||
|
expect(container.hideHeader).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return false when field is a group and hideHeader is NOT set', () => {
|
||||||
|
field.params.hideHeader = undefined;
|
||||||
|
const container = new ContainerModel(field);
|
||||||
|
|
||||||
|
expect(container.hideHeader).toBe(false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -23,7 +23,6 @@ import { ContainerColumnModel } from './container-column.model';
|
|||||||
import { FormFieldTypes } from './form-field-types';
|
import { FormFieldTypes } from './form-field-types';
|
||||||
|
|
||||||
export class ContainerModel extends FormWidgetModel {
|
export class ContainerModel extends FormWidgetModel {
|
||||||
|
|
||||||
field: FormFieldModel;
|
field: FormFieldModel;
|
||||||
|
|
||||||
readonly columns: ContainerColumnModel[] = [];
|
readonly columns: ContainerColumnModel[] = [];
|
||||||
@ -31,43 +30,35 @@ export class ContainerModel extends FormWidgetModel {
|
|||||||
readonly rowspan: number = 1;
|
readonly rowspan: number = 1;
|
||||||
readonly colspan: number = 1;
|
readonly colspan: number = 1;
|
||||||
|
|
||||||
get isVisible(): boolean {
|
|
||||||
return this.field.isVisible;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(field: FormFieldModel) {
|
constructor(field: FormFieldModel) {
|
||||||
super(field.form, field.json);
|
super(field.form, field.json);
|
||||||
|
|
||||||
if (field) {
|
if (field) {
|
||||||
this.field = field;
|
this.field = field;
|
||||||
this.columns = field.columns || [];
|
this.columns = field.columns || [];
|
||||||
this.isExpanded = !this.isCollapsedByDefault();
|
this.isExpanded = !this.isCollapsedByDefault;
|
||||||
this.colspan = field.colspan;
|
this.colspan = field.colspan;
|
||||||
this.rowspan = field.rowspan;
|
this.rowspan = field.rowspan;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
isGroup(): boolean {
|
get isVisible(): boolean {
|
||||||
|
return this.field.isVisible;
|
||||||
|
}
|
||||||
|
|
||||||
|
get isTypeFieldGroup(): boolean {
|
||||||
return this.type === FormFieldTypes.GROUP;
|
return this.type === FormFieldTypes.GROUP;
|
||||||
}
|
}
|
||||||
|
|
||||||
isCollapsible(): boolean {
|
get isCollapsible(): boolean {
|
||||||
let allowCollapse = false;
|
return this.isTypeFieldGroup && (this.field.params?.allowCollapse ?? false);
|
||||||
|
|
||||||
if (this.isGroup() && this.field.params['allowCollapse']) {
|
|
||||||
allowCollapse = this.field.params['allowCollapse'];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return allowCollapse;
|
get isCollapsedByDefault(): boolean {
|
||||||
|
return this.isTypeFieldGroup && (this.field.params?.collapseByDefault ?? false);
|
||||||
}
|
}
|
||||||
|
|
||||||
isCollapsedByDefault(): boolean {
|
get hideHeader(): boolean {
|
||||||
let collapseByDefault = false;
|
return this.isTypeFieldGroup && (this.field.params?.hideHeader ?? false);
|
||||||
|
|
||||||
if (this.isCollapsible() && this.field.params['collapseByDefault']) {
|
|
||||||
collapseByDefault = this.field.params['collapseByDefault'];
|
|
||||||
}
|
|
||||||
|
|
||||||
return collapseByDefault;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,37 @@
|
|||||||
<div [hidden]="!element?.isGroup()" [style]="element | adfFieldStyle" class="adf-container-widget-header">
|
<div
|
||||||
<h4 class="adf-container-widget-header__text" id="container-header"
|
*ngIf="element?.isTypeFieldGroup"
|
||||||
[class.adf-collapsible]="element?.isCollapsible()">
|
[style]="element | adfFieldStyle"
|
||||||
<button *ngIf="element?.isCollapsible()"
|
class="adf-container-widget-header"
|
||||||
mat-icon-button
|
>
|
||||||
class="mdl-button--icon"
|
<div *ngIf="element?.hideHeader">
|
||||||
(click)="onExpanderClicked(element)">
|
<ng-container *ngTemplateOutlet="expandButton; context: { $implicit: element }" />
|
||||||
<mat-icon>{{ element?.isExpanded ? 'expand_more' : 'expand_less' }}</mat-icon>
|
</div>
|
||||||
</button>
|
<h4
|
||||||
<span (click)="onExpanderClicked(element)"
|
*ngIf="!element?.hideHeader"
|
||||||
|
id="container-header"
|
||||||
|
class="adf-container-widget-header__text"
|
||||||
|
[class.adf-collapsible]="element?.isCollapsible"
|
||||||
|
>
|
||||||
|
<ng-container *ngTemplateOutlet="expandButton; context: { $implicit: element }" />
|
||||||
|
<span
|
||||||
|
[id]="'container-header-label-' + element?.id"
|
||||||
role="button"
|
role="button"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
(keyup.enter)="onExpanderClicked(element)"
|
(keyup.enter)="onExpanderClicked(element)"
|
||||||
[id]="'container-header-label-' + element?.id">
|
(click)="onExpanderClicked(element)"
|
||||||
|
>
|
||||||
{{ element.name | translate }}
|
{{ element.name | translate }}
|
||||||
</span>
|
</span>
|
||||||
</h4>
|
</h4>
|
||||||
|
|
||||||
|
<ng-template #expandButton let-element>
|
||||||
|
<button
|
||||||
|
*ngIf="element?.isCollapsible"
|
||||||
|
mat-icon-button
|
||||||
|
class="mdl-button--icon"
|
||||||
|
(click)="onExpanderClicked(element)"
|
||||||
|
>
|
||||||
|
<mat-icon> {{ element?.isExpanded ? 'expand_more' : 'expand_less' }} </mat-icon>
|
||||||
|
</button>
|
||||||
|
</ng-template>
|
||||||
</div>
|
</div>
|
||||||
|
@ -16,11 +16,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
|
||||||
import { ContainerModel } from '../core/container.model';
|
import { ContainerModel } from '../core/container.model';
|
||||||
import { FormFieldTypes } from '../core/form-field-types';
|
import { FormFieldTypes } from '../core/form-field-types';
|
||||||
import { FormFieldModel } from '../core/form-field.model';
|
import { FormFieldModel } from '../core/form-field.model';
|
||||||
import { HeaderWidgetComponent } from './header.widget';
|
import { HeaderWidgetComponent } from './header.widget';
|
||||||
|
import { NoopTranslateModule } from '../../../../testing';
|
||||||
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
|
||||||
describe('HeaderWidgetComponent', () => {
|
describe('HeaderWidgetComponent', () => {
|
||||||
let component: HeaderWidgetComponent;
|
let component: HeaderWidgetComponent;
|
||||||
@ -28,8 +29,8 @@ describe('HeaderWidgetComponent', () => {
|
|||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({
|
TestBed.configureTestingModule({
|
||||||
imports: [HeaderWidgetComponent, TranslateModule.forRoot()]
|
imports: [HeaderWidgetComponent, NoopTranslateModule, NoopAnimationsModule]
|
||||||
}).compileComponents();
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -46,24 +47,80 @@ describe('HeaderWidgetComponent', () => {
|
|||||||
type: FormFieldTypes.GROUP,
|
type: FormFieldTypes.GROUP,
|
||||||
name: 'test-name',
|
name: 'test-name',
|
||||||
id: 'test-id',
|
id: 'test-id',
|
||||||
params: { allowCollapse: true }
|
params: {
|
||||||
|
hideHeader: false,
|
||||||
|
allowCollapse: false,
|
||||||
|
collapseByDefault: false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
fixture.detectChanges();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should render the header widget template', () => {
|
it('should render header widget template when type is group', () => {
|
||||||
const nativeElement = fixture.nativeElement;
|
fixture.detectChanges();
|
||||||
expect(nativeElement.querySelector('.adf-container-widget-header')).toBeTruthy();
|
|
||||||
expect(nativeElement.querySelector('#container-header-label-test-id').textContent.trim()).toEqual('test-name');
|
expect(fixture.nativeElement.querySelector('.adf-container-widget-header')).not.toBe(null);
|
||||||
|
expect(fixture.nativeElement.querySelector('#container-header-label-test-id').textContent.trim()).toEqual('test-name');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should NOT render header widget template when type is different then group', () => {
|
||||||
|
spyOnProperty(component.element, 'isTypeFieldGroup').and.returnValue(false);
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(fixture.nativeElement.querySelector('.adf-container-widget-header')).toBe(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display header text when hideHeader is set to false', () => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(fixture.nativeElement.querySelector('.adf-container-widget-header__text')).not.toBe(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should NOT display header text when hideHeader is set to true', () => {
|
||||||
|
component.element.json.params.hideHeader = true;
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(fixture.nativeElement.querySelector('.adf-container-widget-header__text')).toBe(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should display expander when allowCollapse is set to true', () => {
|
||||||
|
component.element.json.params.allowCollapse = true;
|
||||||
|
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(fixture.nativeElement.querySelector('.mdl-button--icon')).not.toBe(null);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should NOT display expander when allowCollapse is set to false', () => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
expect(fixture.nativeElement.querySelector('.mdl-button--icon')).toBe(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should call onExpanderClicked method when expander is clicked', () => {
|
it('should call onExpanderClicked method when expander is clicked', () => {
|
||||||
|
component.element.json.params.allowCollapse = true;
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
spyOn(component, 'onExpanderClicked');
|
spyOn(component, 'onExpanderClicked');
|
||||||
const expander = fixture.nativeElement.querySelector('#container-header-label-test-id');
|
|
||||||
|
const expander = fixture.nativeElement.querySelector('.mdl-button--icon');
|
||||||
expander.click();
|
expander.click();
|
||||||
expect(component.onExpanderClicked).toHaveBeenCalled();
|
|
||||||
|
expect(component.onExpanderClicked).toHaveBeenCalledWith(component.element);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should call onExpanderClicked method when header text is clicked', () => {
|
||||||
|
fixture.detectChanges();
|
||||||
|
|
||||||
|
spyOn(component, 'onExpanderClicked');
|
||||||
|
|
||||||
|
const headerText = fixture.nativeElement.querySelector('#container-header-label-test-id');
|
||||||
|
headerText.click();
|
||||||
|
|
||||||
|
expect(component.onExpanderClicked).toHaveBeenCalledWith(component.element);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -19,7 +19,7 @@ import { Component, Input, ViewEncapsulation } from '@angular/core';
|
|||||||
import { ContainerModel } from '../core/container.model';
|
import { ContainerModel } from '../core/container.model';
|
||||||
import { FieldStylePipe } from './../../../pipes/field-style.pipe';
|
import { FieldStylePipe } from './../../../pipes/field-style.pipe';
|
||||||
import { MatIconModule } from '@angular/material/icon';
|
import { MatIconModule } from '@angular/material/icon';
|
||||||
import { NgIf } from '@angular/common';
|
import { NgIf, NgTemplateOutlet } from '@angular/common';
|
||||||
import { TranslateModule } from '@ngx-translate/core';
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
import { MatButtonModule } from '@angular/material/button';
|
import { MatButtonModule } from '@angular/material/button';
|
||||||
|
|
||||||
@ -29,13 +29,13 @@ import { MatButtonModule } from '@angular/material/button';
|
|||||||
styleUrls: ['./header.widget.scss'],
|
styleUrls: ['./header.widget.scss'],
|
||||||
standalone: true,
|
standalone: true,
|
||||||
encapsulation: ViewEncapsulation.None,
|
encapsulation: ViewEncapsulation.None,
|
||||||
imports: [FieldStylePipe, MatIconModule, MatButtonModule, TranslateModule, NgIf]
|
imports: [FieldStylePipe, MatIconModule, MatButtonModule, TranslateModule, NgIf, NgTemplateOutlet]
|
||||||
})
|
})
|
||||||
export class HeaderWidgetComponent {
|
export class HeaderWidgetComponent {
|
||||||
@Input() element: ContainerModel;
|
@Input() element: ContainerModel;
|
||||||
|
|
||||||
onExpanderClicked(content: ContainerModel) {
|
onExpanderClicked(content: ContainerModel) {
|
||||||
if (content?.isCollapsible()) {
|
if (content?.isCollapsible) {
|
||||||
content.isExpanded = !content.isExpanded;
|
content.isExpanded = !content.isExpanded;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user