Skip to content

Commit

Permalink
feat(edit-content) show files according to host/folder (#30612)
Browse files Browse the repository at this point in the history
### Parent Issue

#30216 

### Proposed Changes

This pull request includes several changes across multiple files to
enhance the functionality and organization of the `dot-site` and
`dot-edit-content-file-field` components. The key changes involve adding
a new method to fetch content by folder, refactoring imports for better
modularity, and updating UI components for improved user interaction.

### Enhancements to `dot-site.service.ts`:

* Added a new interface `ContentByFolderParams` to define parameters for
fetching content by folder.
* Introduced a new method `getContentByFolder` in `DotSiteService` to
fetch content based on the provided parameters.

### Refactoring imports in `dot-edit-content-file-field` components:

* Updated import paths to use more specific model files for better
modularity in various components, including
`dot-file-field-preview.component.ts`,
`dot-file-field-ui-message.component.ts`,
`dot-form-file-editor.component.ts`, `form-file-editor.store.ts`,
`dot-form-import-url.component.spec.ts`, and `form-import-url.store.ts`.
[[1]](diffhunk://#diff-9d3250303440cce67e959a59ed17f44ad49d690c04e36cbf4fadc011f206001eL29-R32)
[[2]](diffhunk://#diff-fbc6f3568490a6db73eb7a1d91fb7d56c6195f18637a179b3e2e0a9a8971e65bL6-R6)
[[3]](diffhunk://#diff-4e07289537a18f138b8657c2505e3416523ee356c698aeb38f3d519a2257dadaL24-R24)
[[4]](diffhunk://#diff-5184979843abf3baa538afc8613a1fa040a7907c9614bfb64ddc472c31b4cfa7L13-R13)
[[5]](diffhunk://#diff-0d18173fe874af517af41ad1e4422ff7681ba1c2ad4daf75c9806a07fa37e7b2L17-R17)
[[6]](diffhunk://#diff-2e100516ca0ff5570c84b4cf072dd03ae77565e92c8c5de65d77505745955651L12-R12)

### UI Improvements in `dot-select-existing-file` components:

* Enhanced `dot-dataview.component.html` to include better data binding
and UI elements such as loading indicators, search functionality, and
improved table structure.
[[1]](diffhunk://#diff-f3ba4db0d4c81db7982bda57d151d7f05bbb2151eb78f5ce460ccd71184b4c7dR1-R41)
[[2]](diffhunk://#diff-f3ba4db0d4c81db7982bda57d151d7f05bbb2151eb78f5ce460ccd71184b4c7dL27-R66)
* Updated `dot-dataview.component.scss` to include styles for new UI
elements like truncation and thumbnail display.
* Refactored `dot-dataview.component.ts` to use new Angular features
like signals and models for state management.
* Improved `dot-sidebar.component.html` and `dot-sidebar.component.ts`
to handle node selection and state management more effectively.
[[1]](diffhunk://#diff-c3ff3590364bc12ded7173d7374838dfab13f67598f80daa198dfd96c935d459L5-R13)
[[2]](diffhunk://#diff-b6e7f5a1ad7c221178b3ddf3f3dfc06021ba87b4e18ef9d7f6c6c9a6eab016d3R8-R11)
[[3]](diffhunk://#diff-b6e7f5a1ad7c221178b3ddf3f3dfc06021ba87b4e18ef9d7f6c6c9a6eab016d3R22-R23)
[[4]](diffhunk://#diff-b6e7f5a1ad7c221178b3ddf3f3dfc06021ba87b4e18ef9d7f6c6c9a6eab016d3R61-R62)
[[5]](diffhunk://#diff-b6e7f5a1ad7c221178b3ddf3f3dfc06021ba87b4e18ef9d7f6c6c9a6eab016d3R71-R89)
* Updated `dot-select-existing-file.component.html` and
`dot-select-existing-file.component.ts` to handle folder loading and
content selection more efficiently.
[[1]](diffhunk://#diff-485fc35db79ca9cdecc82b1dde0499e2e25f88f07f9ce43a4624fac358ac7848R1-R16)
[[2]](diffhunk://#diff-485fc35db79ca9cdecc82b1dde0499e2e25f88f07f9ce43a4624fac358ac7848L20-R27)
[[3]](diffhunk://#diff-18bf6e06cc08560259db33d84f324194172c43e47220f07b1de0990cf71077acR13)
[[4]](diffhunk://#diff-18bf6e06cc08560259db33d84f324194172c43e47220f07b1de0990cf71077acR41-R42)
[[5]](diffhunk://#diff-18bf6e06cc08560259db33d84f324194172c43e47220f07b1de0990cf71077acL66-R70)

These changes collectively enhance the functionality, modularity, and
user experience of the `dot-site` and `dot-edit-content-file-field`
components.

### Checklist
- [x] Tests
- [x] Translations
- [x] Security Implications Contemplated (add notes if applicable)

### Additional Info



https://github.com/user-attachments/assets/5f9ed27e-1b74-41f8-aa37-612d96c043fa
  • Loading branch information
nicobytes authored Nov 9, 2024
1 parent e44f9cc commit 20899cc
Show file tree
Hide file tree
Showing 36 changed files with 370 additions and 207 deletions.
27 changes: 27 additions & 0 deletions core-web/libs/data-access/src/lib/dot-site/dot-site.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,28 @@ import { Injectable, inject } from '@angular/core';
import { pluck } from 'rxjs/operators';

import { Site } from '@dotcms/dotcms-js';
import { DotCMSContentlet } from '@dotcms/dotcms-models';

export interface SiteParams {
archived: boolean;
live: boolean;
system: boolean;
}

export interface ContentByFolderParams {
hostFolderId: string;
showLinks?: boolean;
showDotAssets?: boolean;
showArchived?: boolean;
sortByDesc?: boolean;
showPages?: boolean;
showFiles?: boolean;
showFolders?: boolean;
showWorking?: boolean;
extensions?: string[];
mimeTypes?: string[];
}

export const BASE_SITE_URL = '/api/v1/site';

export const DEFAULT_PER_PAGE = 10;
Expand Down Expand Up @@ -73,4 +88,16 @@ export class DotSiteService {
.get<{ entity: Site }>(`${BASE_SITE_URL}/currentSite`)
.pipe(pluck('entity'));
}

/**
* Retrieves contentlets from a specified folder.
*
* @param params - Parameters defining the folder and retrieval options.
* @returns An observable emitting an array of `DotCMSContentlet` items.
*/
getContentByFolder(params: ContentByFolderParams) {
return this.#http
.post<{ entity: { list: DotCMSContentlet[] } }>('/api/v1/browser', params)
.pipe(pluck('entity', 'list'));
}
}
6 changes: 6 additions & 0 deletions core-web/libs/dotcms-scss/angular/dotcms-theme/_misc.scss
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,9 @@ a.p-button {
width: $icon-lg-box;
font-size: $icon-lg;
}

.truncate-text {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,17 @@ import { catchError } from 'rxjs/operators';

import { DotResourceLinksService } from '@dotcms/data-access';
import { DotCMSBaseTypesContentTypes, DotCMSContentlet } from '@dotcms/dotcms-models';
import {
DotPreviewResourceLink,
UploadedFile
} from '@dotcms/edit-content/models/dot-edit-content-file.model';
import {
DotTempFileThumbnailComponent,
DotFileSizeFormatPipe,
DotMessagePipe,
DotCopyButtonComponent
} from '@dotcms/ui';

import { DotPreviewResourceLink, UploadedFile } from '../../models';
import { getFileMetadata } from '../../utils';

@Component({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { NgClass } from '@angular/common';
import { ChangeDetectionStrategy, Component, input } from '@angular/core';

import { UIMessage } from '@dotcms/edit-content/models/dot-edit-content-file.model';
import { DotMessagePipe } from '@dotcms/ui';

import { UIMessage } from '../../models';

@Component({
selector: 'dot-file-field-ui-message',
standalone: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,11 @@ import { InputTextModule } from 'primeng/inputtext';

import { debounceTime, distinctUntilChanged, filter } from 'rxjs/operators';

import { UploadedFile } from '@dotcms/edit-content/models/dot-edit-content-file.model';
import { DotMessagePipe, DotFieldValidationMessageComponent } from '@dotcms/ui';

import { FormFileEditorStore } from './store/form-file-editor.store';

import { UploadedFile } from '../../models';

type DialogProps = {
allowFileNameEdit: boolean;
userMonacoOptions: Partial<MonacoEditorConstructionOptions>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { switchMap, tap } from 'rxjs/operators';

import { ComponentStatus, DotHttpErrorResponse } from '@dotcms/dotcms-models';

import { UPLOAD_TYPE, UploadedFile } from '../../../models';
import { UPLOAD_TYPE, UploadedFile } from '../../../../../models/dot-edit-content-file.model';
import { DotFileFieldUploadService } from '../../../services/upload-file/upload-file.service';
import { extractFileExtension, getInfoByLang } from '../../../utils/editor';
import { DEFAULT_MONACO_CONFIG } from '../dot-form-file-editor.conts';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ import { DialogService, DynamicDialogConfig, DynamicDialogRef } from 'primeng/dy

import { DotMessageService } from '@dotcms/data-access';
import { ComponentStatus } from '@dotcms/dotcms-models';
import { UploadedFile } from '@dotcms/edit-content/models/dot-edit-content-file.model';

import { DotFormImportUrlComponent } from './dot-form-import-url.component';
import { FormImportUrlStore } from './store/form-import-url.store';

import { NEW_FILE_MOCK } from '../../../../utils/mocks';
import { UploadedFile } from '../../models';
import { DotFileFieldUploadService } from '../../services/upload-file/upload-file.service';

describe('DotFormImportUrlComponent', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,11 @@ import { ButtonModule } from 'primeng/button';
import { DynamicDialogRef, DynamicDialogConfig } from 'primeng/dynamicdialog';
import { InputTextModule } from 'primeng/inputtext';

import { INPUT_TYPES } from '@dotcms/edit-content/models/dot-edit-content-file.model';
import { DotMessagePipe, DotFieldValidationMessageComponent, DotValidators } from '@dotcms/ui';

import { FormImportUrlStore } from './store/form-import-url.store';

import { INPUT_TYPE } from '../../../dot-edit-content-text-field/utils';

@Component({
selector: 'dot-form-import-url',
standalone: true,
Expand All @@ -38,7 +37,7 @@ export class DotFormImportUrlComponent implements OnInit {
readonly #formBuilder = inject(FormBuilder);
readonly #dialogRef = inject(DynamicDialogRef);
readonly #dialogConfig = inject(
DynamicDialogConfig<{ inputType: INPUT_TYPE; acceptedFiles: string[] }>
DynamicDialogConfig<{ inputType: INPUT_TYPES; acceptedFiles: string[] }>
);
#abortController: AbortController | null = null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { switchMap, tap } from 'rxjs/operators';

import { ComponentStatus, DotHttpErrorResponse } from '@dotcms/dotcms-models';

import { UploadedFile, UPLOAD_TYPE } from '../../../models';
import { UploadedFile, UPLOAD_TYPE } from '../../../../../models/dot-edit-content-file.model';
import { DotFileFieldUploadService } from '../../../services/upload-file/upload-file.service';

export interface FormImportUrlState {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,44 @@
@let loading = $loading();
@let data = $data();
@let rowsPerPage = $rowsPerPage();

<p-table
[value]="$data()"
[loading]="$loading()"
[paginator]="true"
[rows]="7"
styleClass="p-datatable-lg flex flex-column h-full justify-content-between">
#datatable
[value]="data"
[loading]="loading"
[paginator]="data.length >= rowsPerPage"
[rows]="rowsPerPage"
selectionMode="single"
dataKey="identifier"
[(selection)]="$selectedProduct"
(onRowSelect)="onRowSelect.emit($event.data)"
[globalFilterFields]="['title', 'modUserName']"
styleClass="flex flex-column h-full justify-content-between">
<ng-template pTemplate="emptymessage">
<tr>
<td colspan="4">
{{ 'dot.file.field.dialog.select.existing.file.table.emptymessage' | dm }}
</td>
</tr>
</ng-template>
<ng-template pTemplate="caption">
<div class="flex">
<p-iconField iconPosition="left">
<p-inputIcon styleClass="pi pi-search" />
<input pInputText type="text" placeholder="Search keyword" />
<input
#searchInput
pInputText
type="search"
[placeholder]="'dot.file.field.dialog.select.existing.file.table.search' | dm"
(input)="datatable.filterGlobal(searchInput.value, 'contains')" />
</p-iconField>
</div>
</ng-template>
<ng-template pTemplate="header">
<tr class="file-selector__table_header">
<th scope="col">
{{ 'dot.file.field.dialog.select.existing.file.table.thumbnail' | dm }}
</th>
<th scope="col">{{ 'dot.file.field.dialog.select.existing.file.table.title' | dm }}</th>
<th scope="col">
{{ 'dot.file.field.dialog.select.existing.file.table.modified.by' | dm }}
Expand All @@ -24,31 +49,21 @@
</tr>
</ng-template>
<ng-template pTemplate="body" let-content>
<tr class="h-4rem">
<td>
<div class="flex gap-1 align-items-center">
<p-image
loading="lazy"
[preview]="true"
styleClass="image"
[src]="content.image"
[alt]="content.title"
width="40" />

<p class="m-0">{{ content.title }}</p>
<tr class="h-3rem" [pSelectableRow]="content">
<td class="max-w-2rem">
<div class="dataview-thumbnail">
<dot-contentlet-thumbnail
[iconSize]="'48px'"
[contentlet]="content"
[playableVideo]="false"
data-testId="contentlet-thumbnail" />
</div>
</td>
<td>{{ content.modifiedBy }}</td>
<td>{{ content.lastModified | date }}</td>
</tr>
</ng-template>
<ng-template pTemplate="loadingbody" let-columns="columns">
<tr class="h-4rem">
@for (col of columns; track $index) {
<td>
<p-skeleton />
</td>
}
<td class="max-w-12rem">
<p class="truncate-text">{{ content.title }}</p>
</td>
<td>{{ content.modUserName }}</td>
<td>{{ content.modDate | date }}</td>
</tr>
</ng-template>
</p-table>
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,24 @@
}
::ng-deep {
p-table {
.p-datatable .p-datatable-header {
background-color: $color-palette-gray-100;
.p-datatable {
.p-datatable-header {
background-color: $color-palette-gray-100;
}
.p-datatable-wrapper {
height: 100%;
}
}
}
}

.dataview-thumbnail {
width: 100%;
max-height: 3rem;
overflow: hidden;
position: relative;
}

.file-selector__table_header {
th {
font-weight: $font-weight-bold;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,55 +1,74 @@
import { DatePipe, NgOptimizedImage } from '@angular/common';
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
import { DatePipe } from '@angular/common';
import {
ChangeDetectionStrategy,
Component,
CUSTOM_ELEMENTS_SCHEMA,
input,
model,
output,
signal
} from '@angular/core';

import { ButtonModule } from 'primeng/button';
import { DataViewModule } from 'primeng/dataview';
import { IconFieldModule } from 'primeng/iconfield';
import { ImageModule } from 'primeng/image';
import { InputIconModule } from 'primeng/inputicon';
import { InputTextModule } from 'primeng/inputtext';
import { SkeletonModule } from 'primeng/skeleton';
import { TableModule } from 'primeng/table';
import { TagModule } from 'primeng/tag';

import { DotCMSContentlet } from '@dotcms/dotcms-models';
import { DotMessagePipe } from '@dotcms/ui';

import { Content } from '../../store/select-existing-file.store';

@Component({
selector: 'dot-dataview',
standalone: true,
imports: [
DataViewModule,
TagModule,
ButtonModule,
TableModule,
IconFieldModule,
InputIconModule,
InputTextModule,
SkeletonModule,
ImageModule,
NgOptimizedImage,
DatePipe,
DotMessagePipe
],
templateUrl: './dot-dataview.component.html',
styleUrls: ['./dot-dataview.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush
changeDetection: ChangeDetectionStrategy.OnPush,
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class DotDataViewComponent {
/**
* Represents an observable stream of content data.
*
* @type {Observable<Content[]>}
* @type {Observable<DotCMSContentlet[]>}
* @alias data
* @required
*/
$data = input.required<Content[]>({ alias: 'data' });
$data = input.required<DotCMSContentlet[]>({ alias: 'data' });
/**
* A boolean observable that indicates the loading state.
* This is typically used to show or hide a loading indicator in the UI.
*
* @type {boolean}
*/
$loading = input.required<boolean>({ alias: 'loading' });

/**
* Signal representing the number of rows per page in the data view.
*
* @type {number}
*/
$rowsPerPage = signal<number>(9);

/**
* Reactive model holding the currently selected product.
* Can be a `DotCMSContentlet` or `null`.
*/
$selectedProduct = model<DotCMSContentlet | null>(null);

/**
* Emits the selected `DotCMSContentlet` when a row is selected.
*/
onRowSelect = output<DotCMSContentlet>();
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@

@if (!loading) {
<p-tree
[value]="$folders()"
[value]="$state().folders"
[loading]="loading"
selectionMode="single"
[(selection)]="$state().selectedFile"
loadingMode="icon"
class="w-full h-full"
styleClass="flex h-full"
styleClass="w-full h-full"
loadingMode="icon"
(onNodeSelect)="onNodeSelect.emit($event)"
(onNodeExpand)="onNodeExpand.emit($event)">
<ng-template let-node pTemplate="default">
<span>{{ node.label | truncatePath | slice: 0 : 18 }}</span>
<span>{{ node.label | truncatePath }}</span>
</ng-template>
</p-tree>
} @else {
Expand Down
Loading

0 comments on commit 20899cc

Please sign in to comment.