-
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): Show restrictions based on the relationship. (#30976
) ### Parent Issue #30928 ### Proposed Changes This pull request includes several changes to improve the functionality and maintainability of the `dot-select-existing-content` component and its associated files. The most important changes include enhancements to the selection mode, updates to the dialog behavior, and improvements to the component's initialization and testing. ### Enhancements to selection mode: * Added support for dynamic selection mode in the `dot-select-existing-content.component.html` file, allowing for both multiple and single selection modes. [[1]](diffhunk://#diff-ba794904cc95635d9efca07b7e2bfeb948b5b0bb0c8e1e97c777c615398ba011R4-R7) [[2]](diffhunk://#diff-ba794904cc95635d9efca07b7e2bfeb948b5b0bb0c8e1e97c777c615398ba011L41-R24) [[3]](diffhunk://#diff-ba794904cc95635d9efca07b7e2bfeb948b5b0bb0c8e1e97c777c615398ba011L54-R37) [[4]](diffhunk://#diff-ba794904cc95635d9efca07b7e2bfeb948b5b0bb0c8e1e97c777c615398ba011R66-R71) [[5]](diffhunk://#diff-ba794904cc95635d9efca07b7e2bfeb948b5b0bb0c8e1e97c777c615398ba011R84-R88) [[6]](diffhunk://#diff-ba794904cc95635d9efca07b7e2bfeb948b5b0bb0c8e1e97c777c615398ba011L117-R121) ### Updates to dialog behavior: * Modified the `dot-select-existing-content.component.ts` to include the `DynamicDialogConfig` and `DynamicDialogRef` services for better dialog management. [[1]](diffhunk://#diff-14d3d666b0a074fe26436013ebf4abe96e518e28e9799b85b393d14b82ac528bL1-R13) [[2]](diffhunk://#diff-14d3d666b0a074fe26436013ebf4abe96e518e28e9799b85b393d14b82ac528bL28-R35) [[3]](diffhunk://#diff-14d3d666b0a074fe26436013ebf4abe96e518e28e9799b85b393d14b82ac528bL43) [[4]](diffhunk://#diff-14d3d666b0a074fe26436013ebf4abe96e518e28e9799b85b393d14b82ac528bL54-R58) * Updated the `dot-select-existing-content.component.spec.ts` to include tests for dialog initialization, closing behavior, and selection mode validation. [[1]](diffhunk://#diff-c67ee6b7f401324d58934e1bbad99e6b1d0c2e462d5471caa5a9df58eac71767L4-R4) [[2]](diffhunk://#diff-c67ee6b7f401324d58934e1bbad99e6b1d0c2e462d5471caa5a9df58eac71767R18) [[3]](diffhunk://#diff-c67ee6b7f401324d58934e1bbad99e6b1d0c2e462d5471caa5a9df58eac71767R34-R58) [[4]](diffhunk://#diff-c67ee6b7f401324d58934e1bbad99e6b1d0c2e462d5471caa5a9df58eac71767L58-R143) [[5]](diffhunk://#diff-c67ee6b7f401324d58934e1bbad99e6b1d0c2e462d5471caa5a9df58eac71767R163-R207) ### Improvements to initialization and testing: * Added initialization logic in the `dot-select-existing-content.component.ts` to ensure the component starts with the correct configuration. * Enhanced the test suite in `dot-select-existing-content.component.spec.ts` to cover various scenarios, including initialization, dialog behavior, and item selection. [[1]](diffhunk://#diff-c67ee6b7f401324d58934e1bbad99e6b1d0c2e462d5471caa5a9df58eac71767L4-R4) [[2]](diffhunk://#diff-c67ee6b7f401324d58934e1bbad99e6b1d0c2e462d5471caa5a9df58eac71767R18) [[3]](diffhunk://#diff-c67ee6b7f401324d58934e1bbad99e6b1d0c2e462d5471caa5a9df58eac71767R34-R58) [[4]](diffhunk://#diff-c67ee6b7f401324d58934e1bbad99e6b1d0c2e462d5471caa5a9df58eac71767L58-R143) [[5]](diffhunk://#diff-c67ee6b7f401324d58934e1bbad99e6b1d0c2e462d5471caa5a9df58eac71767R163-R207) ### Minor adjustments: * Updated the SCSS file `_radiobutton.scss` to include a new class for styling radio buttons. * Added readonly properties for injected services in the `dot-select-existing-file.component.ts` to improve code readability and maintainability. [[1]](diffhunk://#diff-18bf6e06cc08560259db33d84f324194172c43e47220f07b1de0990cf71077acR46-R49) [[2]](diffhunk://#diff-18bf6e06cc08560259db33d84f324194172c43e47220f07b1de0990cf71077acR66-R69) ### Checklist - [x] Tests - [x] Translations - [x] Security Implications Contemplated (add notes if applicable)
- Loading branch information
Showing
15 changed files
with
589 additions
and
310 deletions.
There are no files selected for viewing
1 change: 1 addition & 0 deletions
1
core-web/libs/dotcms-scss/angular/dotcms-theme/components/form/_radiobutton.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
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
240 changes: 106 additions & 134 deletions
240
...p-field/components/dot-select-existing-content/dot-select-existing-content.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 |
---|---|---|
@@ -1,143 +1,115 @@ | ||
@let data = store.data(); | ||
@let columns = store.columns(); | ||
@let pagination = store.pagination(); | ||
@let selectionMode = store.selectionMode(); | ||
@let totalItems = $items().length; | ||
|
||
@if ($visible()) { | ||
@defer { | ||
<p-dialog | ||
[modal]="true" | ||
[(visible)]="$visible" | ||
(onShow)="onShowDialog()" | ||
(onHide)="emitSelectedItems()" | ||
[draggable]="false" | ||
dataKey="id" | ||
appendTo="body" | ||
width="90%" | ||
[style]="{ width: '90%', 'max-width': '1040px', height: '90vh' }"> | ||
<ng-template pTemplate="header"> | ||
<div class="flex items-center justify-center gap-2"> | ||
<i class="pi pi-search"></i> | ||
<span class="p-dialog-title"> | ||
{{ 'dot.file.relationship.dialog.search' | dm }} | ||
</span> | ||
</div> | ||
</ng-template> | ||
@if (store.errorMessage()) { | ||
<div | ||
class="flex justify-content-center border-1 border-solid border-gray-400 p-6 border-round text-base"> | ||
<p>{{ store.errorMessage() | dm }}</p> | ||
</div> | ||
} @else if (data.length === 0) { | ||
<div | ||
class="flex justify-content-center border-1 border-solid border-gray-400 p-6 border-round text-base gap-2"> | ||
<i class="pi pi-folder-open"></i> | ||
<p>{{ 'dot.file.relationship.dialog.search.empty.content' | dm }}</p> | ||
</div> | ||
} @else { | ||
<p-table | ||
#datatable | ||
[columns]="columns" | ||
[value]="data" | ||
selectionMode="multiple" | ||
[(selection)]="$selectedItems" | ||
[loading]="store.isLoading()" | ||
[paginator]="data.length > pagination.rowsPerPage" | ||
[first]="pagination.offset" | ||
[rows]="pagination.rowsPerPage" | ||
[scrollable]="true" | ||
[globalFilterFields]="['title', 'step', 'description']" | ||
styleClass="dotTable p-datatable-existing-content w-full"> | ||
<ng-template pTemplate="caption"> | ||
<div class="flex justify-content-between align-items-center w-full"> | ||
<div class="flex align-items-center gap-2"> | ||
<div class="flex-none"> | ||
<dot-search | ||
(onSearch)="datatable.filterGlobal($event, 'contains')" /> | ||
</div> | ||
<div class="flex-grow-1"> | ||
<p class="text-primary-500"> | ||
{{ | ||
'dot.file.relationship.dialog.per.page' | ||
| dm: [pagination.rowsPerPage.toString()] | ||
}} | ||
</p> | ||
</div> | ||
</div> | ||
@if (data.length > pagination.rowsPerPage) { | ||
<dot-pagination | ||
[currentPageReportLayout]="'left'" | ||
(nextPage)="store.nextPage()" | ||
(previousPage)="store.previousPage()" | ||
[totalPages]="store.totalPages()" | ||
[currentPage]="pagination.currentPage" /> | ||
} | ||
<div class="flex flex-column gap-2 h-full justify-content-between"> | ||
@if (store.errorMessage()) { | ||
<div | ||
class="flex justify-content-center border-1 border-solid border-gray-400 p-6 border-round text-base"> | ||
<p>{{ store.errorMessage() | dm }}</p> | ||
</div> | ||
} @else if (data.length === 0) { | ||
<div | ||
class="flex justify-content-center border-1 border-solid border-gray-400 p-6 border-round text-base gap-2"> | ||
<i class="pi pi-folder-open"></i> | ||
<p>{{ 'dot.file.relationship.dialog.search.empty.content' | dm }}</p> | ||
</div> | ||
} @else { | ||
<p-table | ||
#datatable | ||
[columns]="columns" | ||
[value]="data" | ||
[selectionMode]="selectionMode" | ||
[(selection)]="$selectedItems" | ||
[loading]="store.isLoading()" | ||
[paginator]="data.length > pagination.rowsPerPage" | ||
[first]="pagination.offset" | ||
[rows]="pagination.rowsPerPage" | ||
[scrollable]="true" | ||
[globalFilterFields]="['title', 'step', 'description']" | ||
styleClass="dotTable p-datatable-existing-content w-full"> | ||
<ng-template pTemplate="caption"> | ||
<div class="flex justify-content-between align-items-center w-full"> | ||
<div class="flex align-items-center gap-2"> | ||
<div class="flex-none"> | ||
<dot-search (onSearch)="datatable.filterGlobal($event, 'contains')" /> | ||
</div> | ||
<div class="flex-grow-1"> | ||
<p class="text-primary-500"> | ||
{{ | ||
'dot.file.relationship.dialog.per.page' | ||
| dm: [pagination.rowsPerPage.toString()] | ||
}} | ||
</p> | ||
</div> | ||
</ng-template> | ||
<ng-template pTemplate="header" styleClass="relative" let-columns> | ||
<tr> | ||
<th | ||
scope="col" | ||
style="width: 4rem" | ||
pFrozenColumn | ||
alignFrozen="left" | ||
[frozen]="true"> | ||
<p-tableHeaderCheckbox /> | ||
</th> | ||
@for (column of columns; track $index) { | ||
<th | ||
class="max-w-12rem" | ||
scope="col" | ||
[pSortableColumn]="column.field"> | ||
<span class="capitalize">{{ column.header }}</span> | ||
<p-sortIcon [field]="column.field" /> | ||
</th> | ||
} | ||
<th scope="col" pFrozenColumn alignFrozen="right" [frozen]="true"> | ||
{{ 'dot.file.relationship.dialog.menu.column' | dm }} | ||
</th> | ||
</tr> | ||
</ng-template> | ||
<ng-template pTemplate="body" let-item let-columns="columns"> | ||
<tr [class.p-highlight]="checkIfSelected(item)"> | ||
<td pFrozenColumn alignFrozen="left" [frozen]="true"> | ||
<p-tableCheckbox [value]="item" /> | ||
</td> | ||
@for (column of columns; track $index) { | ||
<td class="max-w-12rem"> | ||
<p class="truncate-text">{{ item[column.field] }}</p> | ||
</td> | ||
} | ||
<td pFrozenColumn alignFrozen="right" [frozen]="true"> | ||
<i class="pi pi-pencil"></i> | ||
</td> | ||
</tr> | ||
</ng-template> | ||
</p-table> | ||
} | ||
<ng-template pTemplate="footer"> | ||
<div class="flex justify-content-between"> | ||
<div> | ||
<p class="text-primary-500"> | ||
{{ | ||
'dot.file.relationship.dialog.selected.items' | ||
| dm: [$selectedItems().length.toString()] | ||
}} | ||
</p> | ||
</div> | ||
<div> | ||
<p-button | ||
[label]="'Cancel' | dm" | ||
[outlined]="true" | ||
(onClick)="closeDialog()" | ||
[text]="true" | ||
severity="primary" /> | ||
<p-button | ||
[disabled]="$isApplyDisabled()" | ||
(onClick)="closeDialog()" | ||
[label]="$applyLabel()" /> | ||
</div> | ||
@if (data.length > pagination.rowsPerPage) { | ||
<dot-pagination | ||
[currentPageReportLayout]="'left'" | ||
(nextPage)="store.nextPage()" | ||
(previousPage)="store.previousPage()" | ||
[totalPages]="store.totalPages()" | ||
[currentPage]="pagination.currentPage" /> | ||
} | ||
</div> | ||
</ng-template> | ||
</p-dialog> | ||
<ng-template pTemplate="header" styleClass="relative" let-columns> | ||
<tr> | ||
<th | ||
scope="col" | ||
class="max-w-5rem" | ||
pFrozenColumn | ||
alignFrozen="left" | ||
[frozen]="true"> | ||
@if (selectionMode === 'multiple') { | ||
<p-tableHeaderCheckbox /> | ||
} | ||
</th> | ||
@for (column of columns; track $index) { | ||
<th class="max-w-12rem" scope="col" [pSortableColumn]="column.field"> | ||
<span class="capitalize">{{ column.header }}</span> | ||
<p-sortIcon [field]="column.field" /> | ||
</th> | ||
} | ||
</tr> | ||
</ng-template> | ||
<ng-template pTemplate="body" let-item let-columns="columns"> | ||
<tr [class.p-highlight]="checkIfSelected(item)"> | ||
<td class="max-w-5rem" pFrozenColumn alignFrozen="left" [frozen]="true"> | ||
@if (selectionMode === 'multiple') { | ||
<p-tableCheckbox [value]="item" /> | ||
} @else { | ||
<p-tableRadioButton [value]="item" /> | ||
} | ||
</td> | ||
@for (column of columns; track $index) { | ||
<td class="max-w-12rem"> | ||
<p class="truncate-text">{{ item[column.field] }}</p> | ||
</td> | ||
} | ||
</tr> | ||
</ng-template> | ||
</p-table> | ||
} | ||
} | ||
<div class="flex justify-content-between"> | ||
<div> | ||
<p class="text-primary-500"> | ||
{{ 'dot.file.relationship.dialog.selected.items' | dm: [totalItems.toString()] }} | ||
</p> | ||
</div> | ||
<div class="flex gap-2"> | ||
<p-button | ||
[label]="'Cancel' | dm" | ||
[outlined]="true" | ||
(onClick)="closeDialog()" | ||
[text]="true" | ||
severity="primary" /> | ||
<p-button | ||
[disabled]="totalItems === 0" | ||
(onClick)="closeDialog()" | ||
[label]="$applyLabel()" /> | ||
</div> | ||
</div> | ||
</div> |
Oops, something went wrong.