Skip to content

Commit

Permalink
[ACS-6813] ACA configurable layout for search result list (#3656)
Browse files Browse the repository at this point in the history
* [ACS-6813] Make search results list column configurable

* [ACS-6813] Documentation update

* [ACS-6813] Typo fix
  • Loading branch information
MichalKinas authored Feb 21, 2024
1 parent 1141b81 commit 930e4b1
Show file tree
Hide file tree
Showing 8 changed files with 151 additions and 97 deletions.
27 changes: 27 additions & 0 deletions docs/extending/application-features.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,33 @@ All the customizations are stored in the `features` section of the configuration
Other applications or external plugins can utilise different subsets of the configuration above.
Also, extra entries can be added to the configuration schema.

## Customizing list columns

To modify default columns layout for lists in personal files, libraries, favorite libraries, shared, recent files, favorites and search results you can update the `app.extensions.json` file by modifying/inserting new entry to the corresponding section of `features.documentList`. For example modifying `search-results` section:

```json
{
"features": {
"documentList": {
"search-results": [
{
"id": "app.search.type",
"key": "nodeType",
"title": "APP.DOCUMENT_LIST.COLUMNS.TYPE",
"type": "text",
"class": "adf-ellipsis-cell",
"sortable": true,
"desktopOnly": false,
"order": 102
}
]
}
}
}
```

will result in new column being displayed in search results list. Any number of columns can be added, modified or removed from any section.

## Content Actions

Most of the UI elements that operate with content, like toolbar buttons or menus,
Expand Down
6 changes: 6 additions & 0 deletions extension.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -924,6 +924,12 @@
"type": "array",
"items": { "$ref": "#/definitions/documentListPresetRef" },
"minItems": 1
},
"search-results": {
"description": "Search results list preset",
"type": "array",
"items": { "$ref": "#/definitions/documentListPresetRef" },
"minItems": 1
}
}
},
Expand Down
63 changes: 63 additions & 0 deletions projects/aca-content/assets/app.extensions.json
Original file line number Diff line number Diff line change
Expand Up @@ -2754,6 +2754,69 @@
"order": 50,
"draggable": true
}
],
"search-results": [
{
"id": "app.search.name",
"key": "name",
"title": "APP.DOCUMENT_LIST.COLUMNS.NAME",
"type": "text",
"class": "adf-ellipsis-cell adf-expand-cell-5",
"sortable": false,
"template": "app.search.columns.name",
"desktopOnly": false,
"order": 20,
"draggable": true
},
{
"id": "app.search.size",
"key": "content.sizeInBytes",
"title": "APP.DOCUMENT_LIST.COLUMNS.SIZE",
"type": "fileSize",
"class": "adf-no-grow-cell adf-ellipsis-cell",
"sortable": false,
"desktopOnly": true,
"order": 30,
"draggable": true
},
{
"id": "app.search.modifiedOn",
"key": "modifiedAt",
"title": "APP.DOCUMENT_LIST.COLUMNS.MODIFIED_ON",
"type": "date",
"format": "timeAgo",
"class": "adf-ellipsis-cell adf-no-grow-cell",
"sortable": false,
"desktopOnly": true,
"order": 40,
"draggable": true
},
{
"id": "app.search.modifiedBy",
"key": "modifiedByUser.displayName",
"title": "APP.DOCUMENT_LIST.COLUMNS.MODIFIED_BY",
"type": "text",
"class": "adf-ellipsis-cell adf-expand-cell-2 adf-min-width-cell",
"sortable": false,
"desktopOnly": true,
"order": 50,
"draggable": true
},
{
"id": "app.search.tags",
"template": "app.columns.tags",
"key": "tags",
"title": "APP.DOCUMENT_LIST.COLUMNS.TAGS",
"class": "adf-full-width adf-expand-cell-4",
"type": "text",
"sortable": false,
"desktopOnly": true,
"order": 60,
"draggable": true,
"rules": {
"visible": "app.areTagsEnabled"
}
}
]
}
}
Expand Down
4 changes: 3 additions & 1 deletion projects/aca-content/src/lib/aca-content.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ import { ViewProfileComponent } from './components/view-profile/view-profile.com
import { TrashcanComponent } from './components/trashcan/trashcan.component';
import { SharedLinkViewComponent } from './components/shared-link-view/shared-link-view.component';
import { MAT_DIALOG_DEFAULT_OPTIONS } from '@angular/material/dialog';
import { SearchResultsRowComponent } from './components/search/search-results-row/search-results-row.component';

@NgModule({
imports: [
Expand Down Expand Up @@ -174,7 +175,8 @@ export class ContentServiceExtensionModule {
'app.logout': LogoutComponent,
'app.user': UserInfoComponent,
'app.notification-center': NotificationHistoryComponent,
'app.user.menu': UserMenuComponent
'app.user.menu': UserMenuComponent,
'app.search.columns.name': SearchResultsRowComponent
});

extensions.setEvaluators({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,20 +58,44 @@
</adf-data-column-header>
</data-column>

<data-column id="app.search.name" key type="text" class="adf-ellipsis-cell adf-expand-cell-5" title="APP.DOCUMENT_LIST.COLUMNS.NAME" [sortable]="false" [draggable]="true">
<ng-template let-context>
<aca-search-results-row [context]="context"></aca-search-results-row>
</ng-template>
</data-column>
<ng-container *ngFor="let column of columns; trackBy: trackByColumnId">
<ng-container *ngIf="column.template && !(column.desktopOnly && isSmallScreen)">
<data-column
[id]="column.id"
[key]="column.key"
[title]="column.title"
[type]="column.type"
[format]="column.format"
[class]="column.class"
[sortable]="column.sortable"
[sortingKey]="column.sortingKey || column.key"
[isHidden]="column.isHidden"
[draggable]="column.draggable"
[resizable]="column.resizable"
>
<ng-template let-context>
<adf-dynamic-column [id]="column.template" [context]="context"> </adf-dynamic-column>
</ng-template>
</data-column>
</ng-container>

<data-column id="app.search.size" key="content.sizeInBytes" type="fileSize" title="APP.DOCUMENT_LIST.COLUMNS.SIZE" class="adf-no-grow-cell adf-ellipsis-cell" [sortable]="false" *ngIf="!isSmallScreen" [draggable]="true"></data-column>
<data-column id="app.search.modifiedOn" key="modifiedAt" type="date" title="APP.DOCUMENT_LIST.COLUMNS.MODIFIED_ON" class="adf-no-grow-cell adf-ellipsis-cell" format="timeAgo" [sortable]="false" *ngIf="!isSmallScreen" [draggable]="true"></data-column>
<data-column id="app.search.modifiedBy" key="modifiedByUser.displayName" title="APP.DOCUMENT_LIST.COLUMNS.MODIFIED_BY" class="adf-no-grow-cell adf-ellipsis-cell" [sortable]="false" *ngIf="!isSmallScreen" [draggable]="true"></data-column>
<data-column id="app.search.tags" key="$tags" type="text" title="APP.DOCUMENT_LIST.COLUMNS.TAGS" class="adf-full-width adf-expand-cell-4" [sortable]="false" [draggable]="true" *ngIf="isTagsEnabled">
<ng-template let-context>
<aca-tags-column [context]="context"></aca-tags-column>
</ng-template>
</data-column>
<ng-container *ngIf="!column.template && !(column.desktopOnly && isSmallScreen)">
<data-column
[id]="column.id"
[key]="column.key"
[title]="column.title"
[type]="column.type"
[format]="column.format"
[class]="column.class"
[sortable]="column.sortable"
[sortingKey]="column.sortingKey || column.key"
[isHidden]="column.isHidden"
[draggable]="column.draggable"
[resizable]="column.resizable"
>
</data-column>
</ng-container>
</ng-container>
</data-columns>

<adf-custom-empty-content-template>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@
* from Hyland Software. If not, see <http://www.gnu.org/licenses/>.
*/

import { ComponentFixture, fakeAsync, flush, TestBed, tick } from '@angular/core/testing';
import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { SearchResultsComponent } from './search-results.component';
import { AppConfigService, TranslationService } from '@alfresco/adf-core';
import { Store } from '@ngrx/store';
import { NavigateToFolder, SnackbarErrorAction } from '@alfresco/aca-shared/store';
import { Pagination, ResultSetPaging, SearchRequest } from '@alfresco/js-api';
import { SearchQueryBuilderService, TagService } from '@alfresco/adf-content-services';
import { Pagination, SearchRequest } from '@alfresco/js-api';
import { SearchQueryBuilderService } from '@alfresco/adf-content-services';
import { ActivatedRoute, Router } from '@angular/router';
import { BehaviorSubject, of, Subject } from 'rxjs';
import { BehaviorSubject, Subject } from 'rxjs';
import { AppTestingModule } from '../../../testing/app-testing.module';
import { AppService } from '@alfresco/aca-shared';

Expand Down Expand Up @@ -274,80 +274,4 @@ describe('SearchComponent', () => {
expect(queryBuilder.userQuery).toBe(`((=cm:tag:"orange"))`);
expect(queryBuilder.update).toHaveBeenCalled();
});

describe('Dynamic Columns', () => {
let tagsService: TagService;

beforeEach(() => {
tagsService = TestBed.inject(TagService);

spyOn(queryBuilder['searchApi'], 'search').and.returnValue(
Promise.resolve({
list: {
pagination: {
count: 1,
hasMoreItems: false,
totalItems: 1,
skipCount: 0,
maxItems: 25
},
entries: [
{
entry: {
isFile: true,
nodeType: 'cm:content',
isFolder: false,
name: 'test-file.txt',
id: '8dd4d319-ec9f-4ea0-8276-f3b195918477'
}
}
]
}
} as ResultSetPaging)
);

spyOn(queryBuilder, 'buildQuery').and.returnValue(searchRequest);
});

it('should not show tags column if tags are disabled', fakeAsync(() => {
spyOn(tagsService, 'areTagsEnabled').and.returnValue(false);
fixture = TestBed.createComponent(SearchResultsComponent);
fixture.detectChanges();
queryBuilder.execute();
tick();
fixture.detectChanges();
const tagsColumnHeader = fixture.nativeElement.querySelector(`[data-automation-id='auto_id_$tags']`);
expect(tagsColumnHeader).toBeNull();
}));

it('should show tags column if tags are enabled', fakeAsync(() => {
spyOn(tagsService, 'areTagsEnabled').and.returnValue(true);
spyOn(tagsService, 'getTagsByNodeId').and.returnValue(
of({
list: {
pagination: {
count: 0,
hasMoreItems: false,
totalItems: 0,
skipCount: 0,
maxItems: 100
},
entries: []
}
})
);
fixture = TestBed.createComponent(SearchResultsComponent);
fixture.detectChanges();
queryBuilder.execute();
tick();
fixture.detectChanges();
const tagsColumnHeader = fixture.nativeElement.querySelector(`[data-automation-id='auto_id_$tags']`);
expect(tagsColumnHeader).not.toBeNull();
flush();
}));

afterEach(() => {
fixture.destroy();
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ import { SearchActionMenuComponent } from '../search-action-menu/search-action-m
import { TagsColumnComponent } from '../../dl-custom-components/tags-column/tags-column.component';
import { MatIconModule } from '@angular/material/icon';
import { SearchResultsRowComponent } from '../search-results-row/search-results-row.component';
import { DocumentListPresetRef, ExtensionsModule } from '@alfresco/adf-extensions';

@Component({
standalone: true,
Expand All @@ -85,7 +86,8 @@ import { SearchResultsRowComponent } from '../search-results-row/search-results-
PaginationDirective,
ViewerModule,
PageLayoutComponent,
ToolbarComponent
ToolbarComponent,
ExtensionsModule
],
selector: 'aca-search-results',
templateUrl: './search-results.component.html',
Expand All @@ -103,6 +105,7 @@ export class SearchResultsComponent extends PageComponent implements OnInit {
isLoading = false;
totalResults: number;
isTagsEnabled = false;
columns: DocumentListPresetRef[] = [];

constructor(
tagsService: TagService,
Expand Down Expand Up @@ -157,6 +160,8 @@ export class SearchResultsComponent extends PageComponent implements OnInit {
})
);

this.columns = this.extensions.documentListPresets.searchResults || [];

if (this.route) {
this.route.params.forEach((params: Params) => {
// eslint-disable-next-line no-prototype-builtins
Expand Down
7 changes: 5 additions & 2 deletions projects/aca-shared/src/lib/services/app.extension.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,16 @@ export class AppExtensionService implements RuleContext {
favorites: Array<DocumentListPresetRef>;
trashcan: Array<DocumentListPresetRef>;
searchLibraries: Array<DocumentListPresetRef>;
searchResults: Array<DocumentListPresetRef>;
} = {
libraries: [],
favoriteLibraries: [],
shared: [],
recent: [],
favorites: [],
trashcan: [],
searchLibraries: []
searchLibraries: [],
searchResults: []
};

selection: SelectionState;
Expand Down Expand Up @@ -179,7 +181,8 @@ export class AppExtensionService implements RuleContext {
recent: this.getDocumentListPreset(config, 'recent'),
favorites: this.getDocumentListPreset(config, 'favorites'),
trashcan: this.getDocumentListPreset(config, 'trashcan'),
searchLibraries: this.getDocumentListPreset(config, 'search-libraries')
searchLibraries: this.getDocumentListPreset(config, 'search-libraries'),
searchResults: this.getDocumentListPreset(config, 'search-results')
};

this.withCredentials = this.appConfig.get<boolean>('auth.withCredentials', false);
Expand Down

0 comments on commit 930e4b1

Please sign in to comment.