Skip to content

Commit

Permalink
#23443 Allow filter by content types in the containers endpoint (#24008)
Browse files Browse the repository at this point in the history
* change parameter of content type and update selector

* #23443 show correct content types and remove base types and add content type selector component and test cases

* #23443 add search filter on dropdond add add test case

* #23443 remove unnecessary import and fix typo

* #23927 fixed github issues and typo

* #23927 fixed github issues and typo
  • Loading branch information
zulqarnainvd committed Feb 9, 2023
1 parent ceafccb commit 0ffabd8
Show file tree
Hide file tree
Showing 11 changed files with 180 additions and 20 deletions.
Expand Up @@ -51,9 +51,9 @@
</div>

<ng-template #beforeSearchTemplate>
<dot-base-type-selector
(selected)="changeBaseTypeSelector($event)"
></dot-base-type-selector>
<dot-content-type-selector
(selected)="changeContentTypeSelector($event)"
></dot-content-type-selector>
</ng-template>

<ng-template #rowTemplate *ngIf="vm.tableColumns as tableColumns" let-rowData="rowData">
Expand Down
Expand Up @@ -18,6 +18,6 @@
height: 100%;
}

dot-base-type-selector {
dot-content-type-selector {
margin-right: $spacing-3;
}
Expand Up @@ -193,10 +193,10 @@ class ActivatedRouteMock {
}

@Component({
selector: 'dot-base-type-selector',
selector: 'dot-content-type-selector',
template: ''
})
class MockDotBaseTypeSelectorComponent {
class MockDotContentTypeSelectorComponent {
@Input() value: SelectItem;
@Output() selected = new EventEmitter<string>();
}
Expand All @@ -212,14 +212,14 @@ describe('ContainerListComponent', () => {
let unPublishContainer: DotActionMenuButtonComponent;
let publishContainer: DotActionMenuButtonComponent;
let archivedContainer: DotActionMenuButtonComponent;
let baseTypesSelector: MockDotBaseTypeSelectorComponent;
let contentTypesSelector: MockDotContentTypeSelectorComponent;
let dotContainersService: DotContainersService;

const messageServiceMock = new MockDotMessageService(messages);

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ContainerListComponent, MockDotBaseTypeSelectorComponent],
declarations: [ContainerListComponent, MockDotContentTypeSelectorComponent],
providers: [
{ provide: DotMessageService, useValue: messageServiceMock },
{
Expand Down Expand Up @@ -357,16 +357,19 @@ describe('ContainerListComponent', () => {
});
});

it('should emit changes in base types selector', () => {
it('should emit changes in content types selector', () => {
fixture.detectChanges();
baseTypesSelector = fixture.debugElement.query(
By.css('dot-base-type-selector')
contentTypesSelector = fixture.debugElement.query(
By.css('dot-content-type-selector')
).componentInstance;
spyOn(comp.listing.paginatorService, 'setExtraParams');
spyOn(comp.listing, 'loadFirstPage');
baseTypesSelector.selected.emit('test');
contentTypesSelector.selected.emit('test');

expect(comp.listing.paginatorService.setExtraParams).toHaveBeenCalledWith('type', 'test');
expect(comp.listing.paginatorService.setExtraParams).toHaveBeenCalledWith(
'content_type',
'test'
);
expect(comp.listing.loadFirstPage).toHaveBeenCalledWith();
});

Expand Down
Expand Up @@ -54,14 +54,14 @@ export class ContainerListComponent implements OnDestroy {
}

/**
* Change base type to the selected one
* Change content type to the selected one
* @param {string} value
* @memberof ContainerListComponent
*/
changeBaseTypeSelector(value: string) {
value !== ''
? this.listing.paginatorService.setExtraParams('type', value)
: this.listing.paginatorService.deleteExtraParams('type');
changeContentTypeSelector(value: string) {
value
? this.listing.paginatorService.setExtraParams('content_type', value)
: this.listing.paginatorService.deleteExtraParams('content_type');
this.listing.loadFirstPage();
}

Expand Down
Expand Up @@ -9,7 +9,7 @@ import { MenuModule } from 'primeng/menu';
import { DotActionMenuButtonModule } from '@components/_common/dot-action-menu-button/dot-action-menu-button.module';
import { DotAddToBundleModule } from '@components/_common/dot-add-to-bundle';
import { DotEmptyStateModule } from '@components/_common/dot-empty-state/dot-empty-state.module';
import { DotBaseTypeSelectorModule } from '@components/dot-base-type-selector';
import { DotContentTypeSelectorModule } from '@components/dot-content-type-selector';
import { DotListingDataTableModule } from '@components/dot-listing-data-table';
import { DotPortletBaseModule } from '@components/dot-portlet-base/dot-portlet-base.module';
import { DotSiteBrowserService } from '@dotcms/data-access';
Expand All @@ -27,7 +27,7 @@ import { ContainerListComponent } from './container-list.component';
ContainerListRoutingModule,
DotPortletBaseModule,
DotListingDataTableModule,
DotBaseTypeSelectorModule,
DotContentTypeSelectorModule,
DotMessagePipeModule,
ButtonModule,
CheckboxModule,
Expand Down
@@ -0,0 +1,9 @@
<p-dropdown
[options]="options$ | async"
[style]="{ width: '155px' }"
[filter]="true"
[showClear]="true"
(onChange)="change($event)"
filterBy="label"
>
</p-dropdown>
@@ -0,0 +1,82 @@
import { of as observableOf } from 'rxjs';

import { DebugElement, Injectable } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';

import { SelectItem } from 'primeng/api';
import { Dropdown, DropdownModule } from 'primeng/dropdown';

import { DotContentTypeService, DotMessageService } from '@dotcms/data-access';
import { MockDotMessageService } from '@dotcms/utils-testing';

import { DotContentTypeSelectorComponent } from './dot-content-type-selector.component';

@Injectable()
class MockDotContentTypeService {
getContentTypes = jasmine.createSpy('getContentTypes').and.returnValue(
observableOf([
{ name: 'FORM', variable: 'Form' },
{ name: 'WIDGET', variable: 'Widget' }
])
);
}

describe('DotContentTypeSelectorComponent', () => {
let component: DotContentTypeSelectorComponent;
let fixture: ComponentFixture<DotContentTypeSelectorComponent>;
let de: DebugElement;
const allContentTypesItem: SelectItem = { label: 'Any Content Type', value: '' };
const messageServiceMock = new MockDotMessageService({
'contenttypes.selector.any.content.type': 'Any Content Type'
});

beforeEach(() => {
TestBed.configureTestingModule({
declarations: [DotContentTypeSelectorComponent],
imports: [BrowserAnimationsModule, DropdownModule],
providers: [
{
provide: DotMessageService,
useValue: messageServiceMock
},
{
provide: DotContentTypeService,
useClass: MockDotContentTypeService
}
]
});

fixture = TestBed.createComponent(DotContentTypeSelectorComponent);
component = fixture.componentInstance;
de = fixture.debugElement;
});

it('should emit the selected content type', () => {
const pDropDown: DebugElement = de.query(By.css('p-dropdown'));
spyOn(component.selected, 'emit');
spyOn(component, 'change').and.callThrough();
pDropDown.triggerEventHandler('onChange', allContentTypesItem);

expect(component.change).toHaveBeenCalledWith(allContentTypesItem);
expect(component.selected.emit).toHaveBeenCalledWith(allContentTypesItem.value);
});

it('should add All Content Types option as first position', () => {
fixture.detectChanges();

component.options$.subscribe((options) => {
expect(options[0]).toEqual(allContentTypesItem);
});
});

it('should set attributes to dropdown', () => {
fixture.detectChanges();
const pDropDown: Dropdown = de.query(By.css('p-dropdown')).componentInstance;
expect(pDropDown.filter).toBeDefined();
expect(pDropDown.filterBy).toBeDefined();
expect(pDropDown.showClear).toBeDefined();
expect(pDropDown.style).toEqual({ width: '155px' });
});
});
@@ -0,0 +1,51 @@
import { Observable } from 'rxjs';

import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';

import { SelectItem } from 'primeng/api';

import { map, take } from 'rxjs/operators';

import { DotContentTypeService, DotMessageService } from '@dotcms/data-access';
import { DotCMSContentType } from '@dotcms/dotcms-models';

@Component({
selector: 'dot-content-type-selector',
templateUrl: './dot-content-type-selector.component.html',
styleUrls: ['./dot-content-type-selector.component.scss']
})
export class DotContentTypeSelectorComponent implements OnInit {
@Input() value: SelectItem;
@Output() selected = new EventEmitter<string>();

options$: Observable<SelectItem[]>;

constructor(
private dotContentTypeService: DotContentTypeService,
private dotMessageService: DotMessageService
) {}

ngOnInit() {
this.options$ = this.dotContentTypeService.getContentTypes({ page: 999 }).pipe(
take(1),
map((contentTypes: DotCMSContentType[]) => this.setOptions(contentTypes))
);
}

change(item: SelectItem) {
this.selected.emit(item.value);
}

setOptions(contentTypes: DotCMSContentType[]): SelectItem[] {
return [
{
label: this.dotMessageService.get('contenttypes.selector.any.content.type'),
value: ''
},
...contentTypes.map((contentType: DotCMSContentType) => ({
label: contentType.name,
value: contentType.variable
}))
];
}
}
@@ -0,0 +1,14 @@
import { CommonModule } from '@angular/common';
import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';

import { DropdownModule } from 'primeng/dropdown';

import { DotContentTypeSelectorComponent } from './dot-content-type-selector.component';

@NgModule({
imports: [CommonModule, DropdownModule, FormsModule],
declarations: [DotContentTypeSelectorComponent],
exports: [DotContentTypeSelectorComponent]
})
export class DotContentTypeSelectorModule {}
@@ -0,0 +1 @@
export * from './dot-content-type-selector.module';

0 comments on commit 0ffabd8

Please sign in to comment.