-
Notifications
You must be signed in to change notification settings - Fork 467
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(edit-content) add search to category-field #28879
- Loading branch information
Showing
21 changed files
with
616 additions
and
37 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
41 changes: 41 additions & 0 deletions
41
...d/components/dot-category-field-search-list/dot-category-field-search-list.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
<div #tableContainer class="category-field__search-list"> | ||
@if (!isLoading()) { | ||
<p-table | ||
(selectionChange)="selected.emit($event)" | ||
[scrollHeight]="scrollHeight()" | ||
[scrollable]="true" | ||
[value]="categories()" | ||
dataKey="key" | ||
selectionMode="multiple" | ||
styleClass="dotTable "> | ||
<ng-template pTemplate="header"> | ||
<tr> | ||
<th> | ||
<p-tableHeaderCheckbox style="width: 4rem"></p-tableHeaderCheckbox> | ||
</th> | ||
<th>{{ 'edit.content.category-field.search.name' | dm }}</th> | ||
<th>{{ 'edit.content.category-field.search.assignee' | dm }}</th> | ||
</tr> | ||
</ng-template> | ||
|
||
<ng-template let-category pTemplate="body"> | ||
<tr> | ||
<td> | ||
<p-tableCheckbox [value]="category"></p-tableCheckbox> | ||
</td> | ||
<td>{{ category.categoryName }}</td> | ||
<td>{{ category.path }}</td> | ||
</tr> | ||
</ng-template> | ||
</p-table> | ||
} @else { | ||
|
||
<dot-table-skeleton | ||
[columns]="[ | ||
'', | ||
'edit.content.category-field.search.name' | dm, | ||
'edit.content.category-field.search.assignee' | dm | ||
]" /> | ||
|
||
} | ||
</div> |
11 changes: 11 additions & 0 deletions
11
...d/components/dot-category-field-search-list/dot-category-field-search-list.component.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
.category-field__search-list { | ||
display: flex; | ||
flex-direction: column; | ||
height: 100%; | ||
overflow: hidden; | ||
} | ||
|
||
::ng-deep .dotTable.p-datatable > .p-datatable-wrapper { | ||
border-radius: 0; | ||
border: none; | ||
} |
22 changes: 22 additions & 0 deletions
22
...omponents/dot-category-field-search-list/dot-category-field-search-list.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||
|
||
import { DotCategoryFieldSearchListComponent } from './dot-category-field-search-list.component'; | ||
|
||
describe('DotCategoryFieldSearchListComponent', () => { | ||
let component: DotCategoryFieldSearchListComponent; | ||
let fixture: ComponentFixture<DotCategoryFieldSearchListComponent>; | ||
|
||
beforeEach(async () => { | ||
await TestBed.configureTestingModule({ | ||
imports: [DotCategoryFieldSearchListComponent] | ||
}).compileComponents(); | ||
|
||
fixture = TestBed.createComponent(DotCategoryFieldSearchListComponent); | ||
component = fixture.componentInstance; | ||
fixture.detectChanges(); | ||
}); | ||
|
||
it('should create', () => { | ||
expect(component).toBeTruthy(); | ||
}); | ||
}); |
68 changes: 68 additions & 0 deletions
68
...eld/components/dot-category-field-search-list/dot-category-field-search-list.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
import { CommonModule } from '@angular/common'; | ||
import { | ||
AfterViewInit, | ||
ChangeDetectionStrategy, | ||
Component, | ||
DestroyRef, | ||
ElementRef, | ||
EventEmitter, | ||
inject, | ||
input, | ||
Output, | ||
signal, | ||
ViewChild | ||
} from '@angular/core'; | ||
|
||
import { SkeletonModule } from 'primeng/skeleton'; | ||
import { TableModule } from 'primeng/table'; | ||
|
||
import { DotMessagePipe } from '@dotcms/ui'; | ||
|
||
import { | ||
DotCategoryFieldCategory, | ||
DotCategoryFieldCategorySearchedItems | ||
} from '../../models/dot-category-field.models'; | ||
import { DotTableSkeletonComponent } from '../dot-table-skeleton/dot-table-skeleton.component'; | ||
|
||
@Component({ | ||
selector: 'dot-category-field-search-list', | ||
standalone: true, | ||
imports: [CommonModule, TableModule, SkeletonModule, DotTableSkeletonComponent, DotMessagePipe], | ||
templateUrl: './dot-category-field-search-list.component.html', | ||
styleUrl: './dot-category-field-search-list.component.scss', | ||
changeDetection: ChangeDetectionStrategy.OnPush | ||
}) | ||
export class DotCategoryFieldSearchListComponent implements AfterViewInit { | ||
@ViewChild('tableContainer', { static: false }) tableContainer!: ElementRef; | ||
scrollHeight = signal<string>('0px'); | ||
|
||
/** | ||
* Represents the required categories input for DotCategoryFieldCategory. | ||
* | ||
* @typedef {DotCategoryFieldCategory[]} RequiredCategories | ||
*/ | ||
categories = input.required<DotCategoryFieldCategorySearchedItems[]>(); | ||
|
||
@Output() selected = new EventEmitter<DotCategoryFieldCategorySearchedItems[]>(); | ||
|
||
/** | ||
* Represents the selected categories in the DotCategoryFieldCategory class. | ||
*/ | ||
selectedCategories: DotCategoryFieldCategory; | ||
isLoading = input.required<boolean>(); | ||
#destroyRef = inject(DestroyRef); | ||
|
||
ngAfterViewInit(): void { | ||
this.calculateScrollHeight(); | ||
window.addEventListener('resize', this.calculateScrollHeight.bind(this)); | ||
|
||
this.#destroyRef.onDestroy(() => { | ||
window.removeEventListener('resize', this.calculateScrollHeight.bind(this)); | ||
}); | ||
} | ||
|
||
private calculateScrollHeight(): void { | ||
const containerHeight = this.tableContainer.nativeElement.offsetHeight; | ||
this.scrollHeight.set(`${containerHeight}px`); | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
...egory-field/components/dot-category-field-search/dot-category-field-search.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<div class="p-inputgroup w-full"> | ||
<input | ||
#searchInput | ||
class="category-field__search-input" | ||
pInputText | ||
placeholder="{{ 'edit.content.category-field.search.input.placeholder' | dm }}" | ||
type="text" /> | ||
@if (searchInput.value && !isLoading()) { | ||
<span (click)="clearInput()" class="p-inputgroup-addon category-field__search-icon-clear"> | ||
<i class="pi pi-times cursor-pointer"></i> | ||
</span> | ||
} @if (isLoading()) { | ||
<span class="p-inputgroup-addon category-field__search-icon-loading"> | ||
<i class="pi pi-spin pi-spinner"></i> | ||
</span> | ||
} | ||
|
||
<span class="p-inputgroup-addon category-field__search--icon-search"> | ||
<i class="pi pi-search"></i> | ||
</span> | ||
</div> |
14 changes: 14 additions & 0 deletions
14
...egory-field/components/dot-category-field-search/dot-category-field-search.component.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
@use "variables" as *; | ||
|
||
.category-field__search-input.p-inputtext.p-element, | ||
.category-field__search-icon-clear, | ||
.category-field__search-icon-loading { | ||
border-right: none; | ||
} | ||
|
||
.category-field__search--icon-search, | ||
.category-field__search-icon-clear, | ||
.category-field__search-icon-loading { | ||
color: $color-palette-primary; | ||
padding: 0; | ||
} |
22 changes: 22 additions & 0 deletions
22
...ry-field/components/dot-category-field-search/dot-category-field-search.component.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { ComponentFixture, TestBed } from '@angular/core/testing'; | ||
|
||
import { DotCategoryFieldSearchComponent } from './dot-category-field-search.component'; | ||
|
||
describe('DotCategoryFieldSearchComponent', () => { | ||
let component: DotCategoryFieldSearchComponent; | ||
let fixture: ComponentFixture<DotCategoryFieldSearchComponent>; | ||
|
||
beforeEach(async () => { | ||
await TestBed.configureTestingModule({ | ||
imports: [DotCategoryFieldSearchComponent] | ||
}).compileComponents(); | ||
|
||
fixture = TestBed.createComponent(DotCategoryFieldSearchComponent); | ||
component = fixture.componentInstance; | ||
fixture.detectChanges(); | ||
}); | ||
|
||
it('should create', () => { | ||
expect(component).toBeTruthy(); | ||
}); | ||
}); |
84 changes: 84 additions & 0 deletions
84
...ategory-field/components/dot-category-field-search/dot-category-field-search.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
import { fromEvent } from 'rxjs'; | ||
|
||
import { CommonModule } from '@angular/common'; | ||
import { | ||
AfterViewInit, | ||
ChangeDetectionStrategy, | ||
Component, | ||
DestroyRef, | ||
ElementRef, | ||
EventEmitter, | ||
inject, | ||
input, | ||
Output, | ||
ViewChild | ||
} from '@angular/core'; | ||
import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; | ||
|
||
import { InputTextModule } from 'primeng/inputtext'; | ||
|
||
import { debounceTime, filter, map } from 'rxjs/operators'; | ||
|
||
import { DotMessagePipe } from '@dotcms/ui'; | ||
|
||
const DEBOUNCE_TIME = 300; | ||
const MINIMUM_CHARACTERS = 3; | ||
|
||
@Component({ | ||
selector: 'dot-category-field-search', | ||
standalone: true, | ||
imports: [CommonModule, DotMessagePipe, InputTextModule], | ||
templateUrl: './dot-category-field-search.component.html', | ||
styleUrl: './dot-category-field-search.component.scss', | ||
changeDetection: ChangeDetectionStrategy.OnPush | ||
}) | ||
export class DotCategoryFieldSearchComponent implements AfterViewInit { | ||
@ViewChild('searchInput') searchInput!: ElementRef; | ||
|
||
/** | ||
* Represent a EventEmitter for the term the user want to filter | ||
* | ||
*/ | ||
@Output() term = new EventEmitter<string>(); | ||
|
||
/** | ||
* Represent a EventEmitter to notify we want change the mode to `list`. | ||
*/ | ||
@Output() changeMode = new EventEmitter<string>(); | ||
isLoading = input.required<boolean>(); | ||
#destroyRef = inject(DestroyRef); | ||
|
||
ngAfterViewInit(): void { | ||
this.listenInputChanges(); | ||
} | ||
|
||
/** | ||
* Clears the value of the search input field and emits a change mode event. | ||
* | ||
* @return {void} | ||
*/ | ||
clearInput(): void { | ||
this.searchInput.nativeElement.value = ''; | ||
this.changeMode.emit('list'); | ||
} | ||
|
||
/** | ||
* Sets up the search input observable to listen to input events, | ||
* debounce the input, filter by minimum character length, | ||
* and emit the search query value. | ||
* | ||
* @private | ||
*/ | ||
private listenInputChanges(): void { | ||
fromEvent(this.searchInput.nativeElement, 'input') | ||
.pipe( | ||
takeUntilDestroyed(this.#destroyRef), | ||
map((event: Event) => (event.target as HTMLInputElement).value), | ||
debounceTime(DEBOUNCE_TIME), | ||
filter((value: string) => value.length >= MINIMUM_CHARACTERS) | ||
) | ||
.subscribe((value: string) => { | ||
this.term.emit(value); | ||
}); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.