Skip to content

Commit

Permalink
feat(edit-content): Show restrictions based on the relationship. (#30976
Browse files Browse the repository at this point in the history
)

### 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
nicobytes authored Dec 27, 2024
1 parent d1fdfe2 commit cf6f800
Show file tree
Hide file tree
Showing 15 changed files with 589 additions and 310 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
@use "variables" as *;
@import "common";

p-tableradiobutton.p-element,
p-radiobutton.p-element {
gap: $spacing-1;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ export class DotSelectExistingFileComponent implements OnInit {
*/
readonly store = inject(SelectExisingFileStore);

/**
* A readonly property that injects the `DotFileFieldUploadService` service.
* This service is used to manage the state and actions related to selecting existing files.
*/
readonly #uploadService = inject(DotFileFieldUploadService);
/**
* A reference to the dynamic dialog instance.
Expand All @@ -59,6 +63,10 @@ export class DotSelectExistingFileComponent implements OnInit {
*/
$sideBarRef = viewChild.required(DotSideBarComponent);

/**
* A readonly property that injects the `DynamicDialogConfig` service.
* This service is used to get the dialog data.
*/
readonly #dialogConfig = inject(DynamicDialogConfig<DialogData>);

constructor() {
Expand Down
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>
Loading

0 comments on commit cf6f800

Please sign in to comment.