AAE-25571 Add title to file name (#11027)

This commit is contained in:
Tomasz Nastaly
2025-07-25 10:47:41 +02:00
committed by GitHub
parent fbacd5c51e
commit dcd15debf0
5 changed files with 110 additions and 49 deletions

View File

@@ -60,37 +60,38 @@ See the [Custom layout](#custom-layout) section for full details of all availabl
### Properties
| Name | Type | Default value | Description |
| ---- | ---- | ------------- | ----------- |
| allowFullScreen | `boolean` | true | Toggles the 'Full Screen' feature. |
| allowGoBack | `boolean` | true | Allows `back` navigation. |
| closeButtonPosition | `CloseButtonPosition` | `left` | Set close button position right/left. |
| hideInfoButton | `boolean` | false | Toggles Info button. |
| allowLeftSidebar | `boolean` | false | Allow the left the sidebar. |
| allowNavigate | `boolean` | false | Toggles before/next navigation. You can use the arrow buttons to navigate between documents in the collection. |
| allowRightSidebar | `boolean` | false | Allow the right sidebar. |
| blobFile | [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) | | Loads a [Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob) File |
| canNavigateBefore | `boolean` | true | Toggles the "before" ("<") button. Requires `allowNavigate` to be enabled. |
| canNavigateNext | `boolean` | true | Toggles the next (">") button. Requires `allowNavigate` to be enabled. |
| fileName | `string` | | Override Content filename. |
| mimeType | `string` | | Overload mimeType |
| overlayMode | `boolean` | false | If `true` then show the Viewer as a full page over the current content. Otherwise fit inside the parent div. |
| readOnly | `boolean` | true | Enable when where is possible the editing functionalities |
| allowedEditActions | `{ [key: string]: boolean }` | `{ rotate: true, crop: true }` | Controls which editing actions are enabled when not in read-only mode. Allows granular control over actions like rotation and cropping. |
| showLeftSidebar | `boolean` | false | Toggles left sidebar visibility. Requires `allowLeftSidebar` to be set to `true`. |
| showRightSidebar | `boolean` | false | Toggles right sidebar visibility. Requires `allowRightSidebar` to be set to `true`. |
| showToolbar | `boolean` | true | Hide or show the toolbar |
| showViewer | `boolean` | true | Hide or show the viewer |
| sidebarLeftTemplate | [`TemplateRef`](https://angular.io/api/core/TemplateRef)`<any>` | null | The template for the left sidebar. The template context contains the loaded node data. |
| sidebarLeftTemplateContext | | null | Context object available for binding by the local sidebarLeftTemplate with let declarations. |
| sidebarRightTemplate | [`TemplateRef`](https://angular.io/api/core/TemplateRef)`<any>` | null | The template for the right sidebar. The template context contains the loaded node data. |
| sidebarRightTemplateContext | | null | Context object available for binding by the local sidebarRightTemplate with let declarations. |
| tracks | [`Track`](../../../lib/core/src/lib/viewer/models/viewer.model.ts)`[]` | \[] | media subtitles for the media player |
| urlFile | `string` | "" | If you want to load an external file that does not come from ACS you can use this URL to specify where to load the file from. |
| viewerExtensions | [`TemplateRef`](https://angular.io/api/core/TemplateRef)`<any>` | null | Template containing ViewerExtensionDirective instances providing different viewer extensions based on supported file extension. |
| nodeId | `string` | null | Identifier of a node opened by a viewer. |
| nodeMimeType | `string` | undefined | Original node mime type, should be provided when renditiona mime type is different. |
| customError | `string` | undefined | Custom error message to be displayed in the viewer. |
| Name | Type | Default value | Description |
|-----------------------------| ---- | ------------- |-----------------------------------------------------------------------------------------------------------------------------------------|
| allowFullScreen | `boolean` | true | Toggles the 'Full Screen' feature. |
| allowGoBack | `boolean` | true | Allows `back` navigation. |
| closeButtonPosition | `CloseButtonPosition` | `left` | Set close button position right/left. |
| hideInfoButton | `boolean` | false | Toggles Info button. |
| allowLeftSidebar | `boolean` | false | Allow the left the sidebar. |
| allowNavigate | `boolean` | false | Toggles before/next navigation. You can use the arrow buttons to navigate between documents in the collection. |
| allowRightSidebar | `boolean` | false | Allow the right sidebar. |
| blobFile | [`Blob`](https://developer.mozilla.org/en-US/docs/Web/API/Blob) | | Loads a [Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob) File |
| canNavigateBefore | `boolean` | true | Toggles the "before" ("&lt;") button. Requires `allowNavigate` to be enabled. |
| canNavigateNext | `boolean` | true | Toggles the next (">") button. Requires `allowNavigate` to be enabled. |
| fileName | `string` | | Override Content filename. |
| title | `string` | | Override Content title. |
| mimeType | `string` | | Overload mimeType |
| overlayMode | `boolean` | false | If `true` then show the Viewer as a full page over the current content. Otherwise fit inside the parent div. |
| readOnly | `boolean` | true | Enable when where is possible the editing functionalities |
| allowedEditActions | `{ [key: string]: boolean }` | `{ rotate: true, crop: true }` | Controls which editing actions are enabled when not in read-only mode. Allows granular control over actions like rotation and cropping. |
| showLeftSidebar | `boolean` | false | Toggles left sidebar visibility. Requires `allowLeftSidebar` to be set to `true`. |
| showRightSidebar | `boolean` | false | Toggles right sidebar visibility. Requires `allowRightSidebar` to be set to `true`. |
| showToolbar | `boolean` | true | Hide or show the toolbar |
| showViewer | `boolean` | true | Hide or show the viewer |
| sidebarLeftTemplate | [`TemplateRef`](https://angular.io/api/core/TemplateRef)`<any>` | null | The template for the left sidebar. The template context contains the loaded node data. |
| sidebarLeftTemplateContext | | null | Context object available for binding by the local sidebarLeftTemplate with let declarations. |
| sidebarRightTemplate | [`TemplateRef`](https://angular.io/api/core/TemplateRef)`<any>` | null | The template for the right sidebar. The template context contains the loaded node data. |
| sidebarRightTemplateContext | | null | Context object available for binding by the local sidebarRightTemplate with let declarations. |
| tracks | [`Track`](../../../lib/core/src/lib/viewer/models/viewer.model.ts)`[]` | \[] | media subtitles for the media player |
| urlFile | `string` | "" | If you want to load an external file that does not come from ACS you can use this URL to specify where to load the file from. |
| viewerExtensions | [`TemplateRef`](https://angular.io/api/core/TemplateRef)`<any>` | null | Template containing ViewerExtensionDirective instances providing different viewer extensions based on supported file extension. |
| nodeId | `string` | null | Identifier of a node opened by a viewer. |
| nodeMimeType | `string` | undefined | Original node mime type, should be provided when renditiona mime type is different. |
| customError | `string` | undefined | Custom error message to be displayed in the viewer. |
### Events

View File

@@ -46,11 +46,20 @@
[alt]="'ADF_VIEWER.ARIA.MIME_TYPE_ICON' | translate"
[src]="mimeTypeIconUrl"
data-automation-id="adf-file-thumbnail">
<div class="adf-viewer__display-name"
id="adf-viewer-display-name"
[title]="fileName">
<span>{{ displayName }}</span>
</div>
@if (displayTitle) {
<div class="adf-viewer__title-display-name-container"
id="adf-viewer-title-display-name"
[title]="displayTitle">
<p class="adf-viewer__title-value">{{ displayTitle }}</p>
<p class="adf-viewer__display-name-value">{{ displayName }}</p>
</div>
} @else {
<div class="adf-viewer__display-name"
id="adf-viewer-display-name"
[title]="fileName">
<span>{{ displayName }}</span>
</div>
}
<button *ngIf="allowNavigate && canNavigateNext"
data-automation-id="adf-toolbar-next-file"
mat-icon-button

View File

@@ -53,6 +53,7 @@
}
}
&__title-display-name-container,
&__display-name {
font-size: var(--theme-subheading-2-font-size);
line-height: 1.5;
@@ -61,6 +62,17 @@
white-space: nowrap;
}
&__display-name-value,
&__title-value {
margin-top: 0;
margin-bottom: 0;
text-align: left;
}
&__display-name-value {
font-size: var(--theme-body-1-font-size);
}
&-container {
.adf-viewer-layout-content {
@extend .adf-full-screen;

View File

@@ -51,6 +51,7 @@ describe('ViewerComponent', () => {
let testingUtils: UnitTestingUtils;
const getFileName = (): string => testingUtils.getByCSS('#adf-viewer-display-name').nativeElement.textContent;
const getTitle = (): string => testingUtils.getByCSS('.adf-viewer__title-value')?.nativeElement?.textContent;
const getDividers = (): DebugElement[] => testingUtils.getAllByCSS('.adf-toolbar-divider');
beforeEach(() => {
@@ -140,25 +141,25 @@ describe('ViewerComponent', () => {
});
});
describe('File Name Display Tests', () => {
describe('displayFileName method', () => {
describe('Display values Tests', () => {
describe('getDisplayTruncatedValue method', () => {
it('should return full filename when total length is 80 characters or less', () => {
const fileShortName = 'shortname.txt';
component.fileName = fileShortName;
fixture.detectChanges();
expect(component.getDisplayFileName()).toBe(fileShortName);
expect(component.getDisplayTruncatedValue(fileShortName)).toBe(fileShortName);
expect(getFileName()).toBe(fileShortName);
});
it('should truncate filename when total length exceeds 80 characters', () => {
it('should truncate filename when total length exceeds 50 characters', () => {
const longName =
'verylongfilenamethatexceedsmaximumlengthallowedverylongfilenamethatexceedsmaximumlengthallowed.verylongextensionnamethatistoolongverylongextensionnamethatistoolong';
component.fileName = longName;
fixture.detectChanges();
const result = component.getDisplayFileName();
const result = component.getDisplayTruncatedValue(longName);
expect(result).toContain('.....');
expect(result.length).toBe(50);
@@ -168,7 +169,7 @@ describe('ViewerComponent', () => {
component.fileName = '';
fixture.detectChanges();
expect(component.getDisplayFileName()).toBe('');
expect(component.getDisplayTruncatedValue('')).toBe('');
expect(getFileName()).toBe('');
});
});
@@ -198,6 +199,37 @@ describe('ViewerComponent', () => {
});
});
describe('displayTitle', () => {
it('should return full title when total length is 50 characters or less', () => {
const titleShortName = 'Custom mock title';
component.title = titleShortName;
fixture.detectChanges();
expect(component.getDisplayTruncatedValue(titleShortName)).toBe(titleShortName);
expect(getTitle()).toBe(titleShortName);
});
it('should truncate title when total length exceeds 50 characters', () => {
const longTitle =
'verylongTitlethatexceedsmaximumlengthallowedverylongTitlethatexceedsmaximumlengthallowedverylongTitlethatexceedsmaximumlengthallowed';
component.title = longTitle;
fixture.detectChanges();
const result = component.getDisplayTruncatedValue(longTitle);
expect(result).toContain('.....');
expect(result.length).toBe(50);
});
it('should handle empty title', () => {
component.title = undefined;
fixture.detectChanges();
expect(getTitle()).toBeFalsy();
});
});
describe('Viewer Example Component Rendering', () => {
it('should use custom toolbar', (done) => {
const customFixture = TestBed.createComponent(ViewerWithCustomToolbarComponent);

View File

@@ -307,19 +307,27 @@ export class ViewerComponent<T> implements OnDestroy, OnInit, OnChanges {
private _fileExtension: string;
public displayName: string;
public displayTitle: string;
public downloadPromptTimer: number;
public downloadPromptReminderTimer: number;
public mimeTypeIconUrl: string;
private readonly destroyRef = inject(DestroyRef);
/** Override Content title. */
@Input()
set title(title: string) {
this.displayTitle = title ? this.getDisplayTruncatedValue(title) : '';
}
/** Override Content filename. */
@Input()
set fileName(fileName: string) {
this._fileName = fileName;
this._fileExtension = this.viewUtilsService.getFileExtension(this.fileName);
this._fileNameWithoutExtension = this.fileName?.replace(new RegExp(`${this.fileExtension}$`), '') || '';
this.displayName = this.getDisplayFileName();
const value = (this.fileNameWithoutExtension || '') + (this.fileExtension || '');
this.displayName = this.getDisplayTruncatedValue(value);
}
get fileName(): string {
@@ -473,12 +481,11 @@ export class ViewerComponent<T> implements OnDestroy, OnInit, OnChanges {
this.clearDownloadPromptTimeouts();
}
getDisplayFileName(): string {
const fullName = (this.fileNameWithoutExtension || '') + (this.fileExtension || '');
getDisplayTruncatedValue(value: string): string {
const maxLength = 50;
if (fullName.length <= maxLength) {
return fullName;
if (value.length <= maxLength) {
return value;
}
const amountOfTruncateDots = 5;
@@ -486,8 +493,8 @@ export class ViewerComponent<T> implements OnDestroy, OnInit, OnChanges {
const endLength = 8;
const startLength = availableSpace - endLength;
const start = fullName.substring(0, startLength);
const end = fullName.substring(fullName.length - endLength);
const start = value.substring(0, startLength);
const end = value.substring(value.length - endLength);
return start + '.....' + end;
}