Merge pull request #4436 from TexasDigitalLibrary/dspace-8_x-port-config-default-comcol-tab

[Port dspace-8_x] Make the default tab for browsing communities and collections configurable in DSpace 8
This commit is contained in:
Tim Donohue
2025-07-03 15:37:41 -05:00
committed by GitHub
11 changed files with 78 additions and 4 deletions

View File

@@ -367,12 +367,20 @@ item:
# Community Page Config # Community Page Config
community: community:
# Default tab to be shown when browsing a Community. Valid values are: comcols, search, or browse_<field>
# <field> must be any of the configured "browse by" fields, e.g., dateissued, author, title, or subject
# When the default tab is not the 'search' tab, the search tab is moved to the last position
defaultBrowseTab: search
# Search tab config # Search tab config
searchSection: searchSection:
showSidebar: true showSidebar: true
# Collection Page Config # Collection Page Config
collection: collection:
# Default tab to be shown when browsing a Collection. Valid values are: search, or browse_<field>
# <field> must be any of the configured "browse by" fields, e.g., dateissued, author, title, or subject
# When the default tab is not the 'search' tab, the search tab is moved to the last position
defaultBrowseTab: search
# Search tab config # Search tab config
searchSection: searchSection:
showSidebar: true showSidebar: true

View File

@@ -93,6 +93,15 @@ export const ROUTES: Route[] = [
pathMatch: 'full', pathMatch: 'full',
component: ComcolSearchSectionComponent, component: ComcolSearchSectionComponent,
}, },
{
path: 'search',
pathMatch: 'full',
component: ComcolSearchSectionComponent,
resolve: {
breadcrumb: i18nBreadcrumbResolver,
},
data: { breadcrumbKey: 'collection.search' },
},
{ {
path: 'browse/:id', path: 'browse/:id',
pathMatch: 'full', pathMatch: 'full',

View File

@@ -80,6 +80,15 @@ export const ROUTES: Route[] = [
pathMatch: 'full', pathMatch: 'full',
component: ComcolSearchSectionComponent, component: ComcolSearchSectionComponent,
}, },
{
path: 'search',
pathMatch: 'full',
component: ComcolSearchSectionComponent,
resolve: {
breadcrumb: i18nBreadcrumbResolver,
},
data: { breadcrumbKey: 'community.search' },
},
{ {
path: 'subcoms-cols', path: 'subcoms-cols',
pathMatch: 'full', pathMatch: 'full',

View File

@@ -5,6 +5,7 @@ import {
} from '@angular/common'; } from '@angular/common';
import { import {
Component, Component,
Inject,
Input, Input,
OnDestroy, OnDestroy,
OnInit, OnInit,
@@ -33,6 +34,10 @@ import {
take, take,
} from 'rxjs/operators'; } from 'rxjs/operators';
import {
APP_CONFIG,
AppConfig,
} from '../../../../config/app-config.interface';
import { getCollectionPageRoute } from '../../../collection-page/collection-page-routing-paths'; import { getCollectionPageRoute } from '../../../collection-page/collection-page-routing-paths';
import { getCommunityPageRoute } from '../../../community-page/community-page-routing-paths'; import { getCommunityPageRoute } from '../../../community-page/community-page-routing-paths';
import { BrowseService } from '../../../core/browse/browse.service'; import { BrowseService } from '../../../core/browse/browse.service';
@@ -82,6 +87,7 @@ export class ComcolPageBrowseByComponent implements OnDestroy, OnInit {
subs: Subscription[] = []; subs: Subscription[] = [];
constructor( constructor(
@Inject(APP_CONFIG) public appConfig: AppConfig,
public router: Router, public router: Router,
private browseService: BrowseService, private browseService: BrowseService,
) { ) {
@@ -99,14 +105,14 @@ export class ComcolPageBrowseByComponent implements OnDestroy, OnInit {
allOptions.push({ allOptions.push({
id: 'search', id: 'search',
label: 'collection.page.browse.search.head', label: 'collection.page.browse.search.head',
routerLink: comColRoute, routerLink: `${comColRoute}/search`,
}); });
} else if (this.contentType === 'community') { } else if (this.contentType === 'community') {
comColRoute = getCommunityPageRoute(this.id); comColRoute = getCommunityPageRoute(this.id);
allOptions.push({ allOptions.push({
id: 'search', id: 'search',
label: 'collection.page.browse.search.head', label: 'collection.page.browse.search.head',
routerLink: comColRoute, routerLink: `${comColRoute}/search`,
}); });
allOptions.push({ allOptions.push({
id: 'comcols', id: 'comcols',
@@ -120,11 +126,24 @@ export class ComcolPageBrowseByComponent implements OnDestroy, OnInit {
label: `browse.comcol.by.${config.id}`, label: `browse.comcol.by.${config.id}`,
routerLink: `${comColRoute}/browse/${config.id}`, routerLink: `${comColRoute}/browse/${config.id}`,
}))); })));
// When the default tab is not the "search" tab, the "search" tab is moved
// at the end of the tabs ribbon for aesthetics purposes.
if (this.appConfig[this.contentType].defaultBrowseTab !== 'search') {
allOptions.push(allOptions.shift());
}
} }
return allOptions; return allOptions;
}), }),
); );
let comColRoute: string;
if (this.contentType === 'collection') {
comColRoute = getCollectionPageRoute(this.id);
} else if (this.contentType === 'community') {
comColRoute = getCommunityPageRoute(this.id);
}
this.subs.push(combineLatest([ this.subs.push(combineLatest([
this.allOptions$, this.allOptions$,
this.router.events.pipe( this.router.events.pipe(
@@ -135,11 +154,29 @@ export class ComcolPageBrowseByComponent implements OnDestroy, OnInit {
), ),
]).subscribe(([navOptions, url]: [ComColPageNavOption[], string]) => { ]).subscribe(([navOptions, url]: [ComColPageNavOption[], string]) => {
for (const option of navOptions) { for (const option of navOptions) {
if (option.routerLink === url?.split('?')[0]) { if (url?.split('?')[0] === comColRoute && option.id === this.appConfig[this.contentType].defaultBrowseTab) {
void this.router.navigate([option.routerLink], { queryParams: option.params });
break;
} else if (option.routerLink === url?.split('?')[0]) {
this.currentOption$.next(option); this.currentOption$.next(option);
break;
} }
} }
})); }));
if (this.router.url?.split('?')[0] === comColRoute) {
this.allOptions$.pipe(
take(1),
).subscribe((allOptions: ComColPageNavOption[]) => {
for (const option of allOptions) {
if (option.id === this.appConfig[this.contentType].defaultBrowseTab) {
this.currentOption$.next(option[0]);
void this.router.navigate([option.routerLink], { queryParams: option.params });
break;
}
}
});
}
} }
ngOnDestroy(): void { ngOnDestroy(): void {

View File

@@ -18,6 +18,7 @@ describe('ComcolSearchSectionComponent', () => {
beforeEach(async () => { beforeEach(async () => {
route = new ActivatedRouteStub(); route = new ActivatedRouteStub();
route.parent = new ActivatedRouteStub();
await TestBed.configureTestingModule({ await TestBed.configureTestingModule({
imports: [ComcolSearchSectionComponent], imports: [ComcolSearchSectionComponent],

View File

@@ -55,7 +55,7 @@ export class ComcolSearchSectionComponent implements OnInit {
} }
ngOnInit(): void { ngOnInit(): void {
this.comcol$ = this.route.data.pipe( this.comcol$ = this.route.parent.data.pipe(
map((data: Data) => (data.dso as RemoteData<Community | Collection>).payload), map((data: Data) => (data.dso as RemoteData<Community | Collection>).payload),
); );
this.showSidebar$ = this.comcol$.pipe( this.showSidebar$ = this.comcol$.pipe(

View File

@@ -1325,6 +1325,8 @@
"collection.page.news": "News", "collection.page.news": "News",
"collection.search.breadcrumbs": "Search",
"collection.search.results.head": "Search Results", "collection.search.results.head": "Search Results",
"collection.select.confirm": "Confirm selected", "collection.select.confirm": "Confirm selected",
@@ -1563,6 +1565,8 @@
"community.all-lists.head": "Subcommunities and Collections", "community.all-lists.head": "Subcommunities and Collections",
"community.search.breadcrumbs": "Search",
"community.search.results.head": "Search Results", "community.search.results.head": "Search Results",
"community.sub-collection-list.head": "Collections in this Community", "community.sub-collection-list.head": "Collections in this Community",

View File

@@ -4,6 +4,7 @@ import { Config } from './config.interface';
* Collection Page Config * Collection Page Config
*/ */
export interface CollectionPageConfig extends Config { export interface CollectionPageConfig extends Config {
defaultBrowseTab: string;
searchSection: CollectionSearchSectionConfig; searchSection: CollectionSearchSectionConfig;
edit: { edit: {
undoTimeout: number; undoTimeout: number;

View File

@@ -4,6 +4,7 @@ import { Config } from './config.interface';
* Community Page Config * Community Page Config
*/ */
export interface CommunityPageConfig extends Config { export interface CommunityPageConfig extends Config {
defaultBrowseTab: string;
searchSection: CommunitySearchSectionConfig; searchSection: CommunitySearchSectionConfig;
} }

View File

@@ -335,6 +335,7 @@ export class DefaultAppConfig implements AppConfig {
// Community Page Config // Community Page Config
community: CommunityPageConfig = { community: CommunityPageConfig = {
defaultBrowseTab: 'search',
searchSection: { searchSection: {
showSidebar: true, showSidebar: true,
}, },
@@ -342,6 +343,7 @@ export class DefaultAppConfig implements AppConfig {
// Collection Page Config // Collection Page Config
collection: CollectionPageConfig = { collection: CollectionPageConfig = {
defaultBrowseTab: 'search',
searchSection: { searchSection: {
showSidebar: true, showSidebar: true,
}, },

View File

@@ -290,11 +290,13 @@ export const environment: BuildConfig = {
}, },
}, },
community: { community: {
defaultBrowseTab: 'search',
searchSection: { searchSection: {
showSidebar: true, showSidebar: true,
}, },
}, },
collection: { collection: {
defaultBrowseTab: 'search',
searchSection: { searchSection: {
showSidebar: true, showSidebar: true,
}, },