diff --git a/config/config.example.yml b/config/config.example.yml index 500c2c476a..f1e6be76aa 100644 --- a/config/config.example.yml +++ b/config/config.example.yml @@ -369,3 +369,8 @@ vocabularies: - filter: 'subject' vocabulary: 'srsc' enabled: true + +# Default collection/community sorting order at Advanced search, Create/update community and collection when there are not a query. +comcolSelectionSort: + sortField: 'dc.title' + sortDirection: 'ASC' \ No newline at end of file diff --git a/src/app/shared/dso-selector/dso-selector/dso-selector.component.spec.ts b/src/app/shared/dso-selector/dso-selector/dso-selector.component.spec.ts index 7c28859388..e2acd17bc0 100644 --- a/src/app/shared/dso-selector/dso-selector/dso-selector.component.spec.ts +++ b/src/app/shared/dso-selector/dso-selector/dso-selector.component.spec.ts @@ -11,6 +11,7 @@ import { PaginatedSearchOptions } from '../../search/models/paginated-search-opt import { hasValue } from '../../empty.util'; import { createPaginatedList } from '../../testing/utils.test'; import { NotificationsService } from '../../notifications/notifications.service'; +import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model'; describe('DSOSelectorComponent', () => { let component: DSOSelectorComponent; @@ -34,7 +35,7 @@ describe('DSOSelectorComponent', () => { ]; const searchService = { - search: (options: PaginatedSearchOptions) => { + search: (options: PaginatedSearchOptions, responseMsToLive?: number, useCachedVersionIfAvailable = true) => { if (hasValue(options.query) && options.query.startsWith('search.resourceid')) { return createSuccessfulRemoteDataObject$(createPaginatedList([searchResult])); } else if (options.pagination.currentPage === 1) { @@ -120,6 +121,43 @@ describe('DSOSelectorComponent', () => { }); }); + describe('search', () => { + beforeEach(() => { + spyOn(searchService, 'search').and.callThrough(); + }); + + it('should specify how to sort if no query is given', () => { + component.sort = new SortOptions('dc.title', SortDirection.ASC); + component.search(undefined, 0); + + expect(searchService.search).toHaveBeenCalledWith( + jasmine.objectContaining({ + query: undefined, + sort: jasmine.objectContaining({ + field: 'dc.title', + direction: SortDirection.ASC, + }), + }), + null, + true + ); + }); + + it('should not specify how to sort if a query is given', () => { + component.sort = new SortOptions('dc.title', SortDirection.ASC); + component.search('testQuery', 0); + + expect(searchService.search).toHaveBeenCalledWith( + jasmine.objectContaining({ + query: 'testQuery', + sort: null, + }), + null, + true + ); + }); + }); + describe('when search returns an error', () => { beforeEach(() => { spyOn(searchService, 'search').and.returnValue(createFailedRemoteDataObject$()); diff --git a/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts b/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts index c8d11891ba..fe64c0a41e 100644 --- a/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts +++ b/src/app/shared/dso-selector/dso-selector/dso-selector.component.ts @@ -31,6 +31,7 @@ import { getFirstCompletedRemoteData, getFirstSucceededRemoteDataPayload } from import { hasNoValue, hasValue, isEmpty, isNotEmpty } from '../../empty.util'; import { buildPaginatedList, PaginatedList } from '../../../core/data/paginated-list.model'; import { SearchResult } from '../../search/models/search-result.model'; +import { SortOptions } from '../../../core/cache/models/sort-options.model'; import { RemoteData } from '../../../core/data/remote-data'; import { NotificationsService } from '../../notifications/notifications.service'; import { TranslateService } from '@ngx-translate/core'; @@ -69,6 +70,11 @@ export class DSOSelectorComponent implements OnInit, OnDestroy { */ @Input() types: DSpaceObjectType[]; + /** + * The sorting options + */ + @Input() sort: SortOptions; + // list of allowed selectable dsoTypes typesString: string; @@ -221,13 +227,16 @@ export class DSOSelectorComponent implements OnInit, OnDestroy { * @param useCache Whether or not to use the cache */ search(query: string, page: number, useCache: boolean = true): Observable>>> { + // default sort is only used when there is not query + let efectiveSort = query ? null : this.sort; return this.searchService.search( new PaginatedSearchOptions({ query: query, dsoTypes: this.types, pagination: Object.assign({}, this.defaultPagination, { currentPage: page - }) + }), + sort: efectiveSort }), null, useCache, diff --git a/src/app/shared/dso-selector/modal-wrappers/create-collection-parent-selector/create-collection-parent-selector.component.ts b/src/app/shared/dso-selector/modal-wrappers/create-collection-parent-selector/create-collection-parent-selector.component.ts index 8b38b62378..e0b7c1675b 100644 --- a/src/app/shared/dso-selector/modal-wrappers/create-collection-parent-selector/create-collection-parent-selector.component.ts +++ b/src/app/shared/dso-selector/modal-wrappers/create-collection-parent-selector/create-collection-parent-selector.component.ts @@ -8,7 +8,8 @@ import { getCollectionCreateRoute, COLLECTION_PARENT_PARAMETER } from '../../../../collection-page/collection-page-routing-paths'; - +import { SortDirection, SortOptions } from '../../../../core/cache/models/sort-options.model'; +import { environment } from '../../../../../environments/environment'; /** * Component to wrap a list of existing communities inside a modal * Used to choose a community from to create a new collection in @@ -23,6 +24,7 @@ export class CreateCollectionParentSelectorComponent extends DSOSelectorModalWra selectorTypes = [DSpaceObjectType.COMMUNITY]; action = SelectorActionType.CREATE; header = 'dso-selector.create.collection.sub-level'; + defaultSort = new SortOptions(environment.comcolSelectionSort.sortField, environment.comcolSelectionSort.sortDirection as SortDirection); constructor(protected activeModal: NgbActiveModal, protected route: ActivatedRoute, private router: Router) { super(activeModal, route); diff --git a/src/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.html b/src/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.html index 4a22672988..a13be63880 100644 --- a/src/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.html +++ b/src/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.html @@ -14,6 +14,6 @@
{{'dso-selector.create.community.sub-level' | translate}}
- + diff --git a/src/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.ts b/src/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.ts index a7f583df50..77458d9802 100644 --- a/src/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.ts +++ b/src/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.ts @@ -12,6 +12,8 @@ import { getCommunityCreateRoute, COMMUNITY_PARENT_PARAMETER } from '../../../../community-page/community-page-routing-paths'; +import { SortDirection, SortOptions } from '../../../../core/cache/models/sort-options.model'; +import { environment } from '../../../../../environments/environment'; /** * Component to wrap a button - for top communities - @@ -29,6 +31,7 @@ export class CreateCommunityParentSelectorComponent extends DSOSelectorModalWrap objectType = DSpaceObjectType.COMMUNITY; selectorTypes = [DSpaceObjectType.COMMUNITY]; action = SelectorActionType.CREATE; + defaultSort = new SortOptions(environment.comcolSelectionSort.sortField, environment.comcolSelectionSort.sortDirection as SortDirection); constructor(protected activeModal: NgbActiveModal, protected route: ActivatedRoute, private router: Router) { super(activeModal, route); diff --git a/src/app/shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component.ts b/src/app/shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component.ts index b109be0af2..ed8a7b0780 100644 --- a/src/app/shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component.ts +++ b/src/app/shared/dso-selector/modal-wrappers/create-item-parent-selector/create-item-parent-selector.component.ts @@ -4,6 +4,8 @@ import { DSpaceObjectType } from '../../../../core/shared/dspace-object-type.mod import { DSpaceObject } from '../../../../core/shared/dspace-object.model'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { DSOSelectorModalWrapperComponent, SelectorActionType } from '../dso-selector-modal-wrapper.component'; +import { SortDirection, SortOptions } from '../../../../core/cache/models/sort-options.model'; +import { environment } from '../../../../../environments/environment'; /** * Component to wrap a list of existing collections inside a modal @@ -21,6 +23,7 @@ export class CreateItemParentSelectorComponent extends DSOSelectorModalWrapperCo selectorTypes = [DSpaceObjectType.COLLECTION]; action = SelectorActionType.CREATE; header = 'dso-selector.create.item.sub-level'; + defaultSort = new SortOptions(environment.comcolSelectionSort.sortField, environment.comcolSelectionSort.sortDirection as SortDirection); /** * If present this value is used to filter collection list by entity type diff --git a/src/app/shared/dso-selector/modal-wrappers/dso-selector-modal-wrapper.component.html b/src/app/shared/dso-selector/modal-wrappers/dso-selector-modal-wrapper.component.html index 85d8797e66..54044f5d79 100644 --- a/src/app/shared/dso-selector/modal-wrappers/dso-selector-modal-wrapper.component.html +++ b/src/app/shared/dso-selector/modal-wrappers/dso-selector-modal-wrapper.component.html @@ -6,6 +6,6 @@ diff --git a/src/app/shared/dso-selector/modal-wrappers/dso-selector-modal-wrapper.component.ts b/src/app/shared/dso-selector/modal-wrappers/dso-selector-modal-wrapper.component.ts index 113ca518fd..3f81687c9f 100644 --- a/src/app/shared/dso-selector/modal-wrappers/dso-selector-modal-wrapper.component.ts +++ b/src/app/shared/dso-selector/modal-wrappers/dso-selector-modal-wrapper.component.ts @@ -5,6 +5,7 @@ import { RemoteData } from '../../../core/data/remote-data'; import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { DSpaceObjectType } from '../../../core/shared/dspace-object-type.model'; import { hasValue, isNotEmpty } from '../../empty.util'; +import { SortOptions } from '../../../core/cache/models/sort-options.model'; export enum SelectorActionType { CREATE = 'create', @@ -49,6 +50,11 @@ export abstract class DSOSelectorModalWrapperComponent implements OnInit { */ action: SelectorActionType; + /** + * Default DSO ordering + */ + defaultSort: SortOptions; + constructor(protected activeModal: NgbActiveModal, protected route: ActivatedRoute) { } diff --git a/src/app/shared/dso-selector/modal-wrappers/edit-collection-selector/edit-collection-selector.component.ts b/src/app/shared/dso-selector/modal-wrappers/edit-collection-selector/edit-collection-selector.component.ts index cfc2ea282d..fd54cd44ed 100644 --- a/src/app/shared/dso-selector/modal-wrappers/edit-collection-selector/edit-collection-selector.component.ts +++ b/src/app/shared/dso-selector/modal-wrappers/edit-collection-selector/edit-collection-selector.component.ts @@ -8,6 +8,8 @@ import { SelectorActionType } from '../dso-selector-modal-wrapper.component'; import { getCollectionEditRoute } from '../../../../collection-page/collection-page-routing-paths'; +import { SortDirection, SortOptions } from '../../../../core/cache/models/sort-options.model'; +import { environment } from '../../../../../environments/environment'; /** * Component to wrap a list of existing collections inside a modal @@ -22,6 +24,7 @@ export class EditCollectionSelectorComponent extends DSOSelectorModalWrapperComp objectType = DSpaceObjectType.COLLECTION; selectorTypes = [DSpaceObjectType.COLLECTION]; action = SelectorActionType.EDIT; + defaultSort = new SortOptions(environment.comcolSelectionSort.sortField, environment.comcolSelectionSort.sortDirection as SortDirection); constructor(protected activeModal: NgbActiveModal, protected route: ActivatedRoute, private router: Router) { super(activeModal, route); diff --git a/src/app/shared/dso-selector/modal-wrappers/edit-community-selector/edit-community-selector.component.ts b/src/app/shared/dso-selector/modal-wrappers/edit-community-selector/edit-community-selector.component.ts index d73a7b48c5..cf2f97c6d3 100644 --- a/src/app/shared/dso-selector/modal-wrappers/edit-community-selector/edit-community-selector.component.ts +++ b/src/app/shared/dso-selector/modal-wrappers/edit-community-selector/edit-community-selector.component.ts @@ -8,6 +8,8 @@ import { SelectorActionType } from '../dso-selector-modal-wrapper.component'; import { getCommunityEditRoute } from '../../../../community-page/community-page-routing-paths'; +import { SortDirection, SortOptions } from '../../../../core/cache/models/sort-options.model'; +import { environment } from '../../../../../environments/environment'; /** * Component to wrap a list of existing communities inside a modal @@ -23,6 +25,7 @@ export class EditCommunitySelectorComponent extends DSOSelectorModalWrapperCompo objectType = DSpaceObjectType.COMMUNITY; selectorTypes = [DSpaceObjectType.COMMUNITY]; action = SelectorActionType.EDIT; + defaultSort = new SortOptions(environment.comcolSelectionSort.sortField, environment.comcolSelectionSort.sortDirection as SortDirection); constructor(protected activeModal: NgbActiveModal, protected route: ActivatedRoute, private router: Router) { super(activeModal, route); diff --git a/src/app/shared/dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component.html b/src/app/shared/dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component.html new file mode 100644 index 0000000000..85d8797e66 --- /dev/null +++ b/src/app/shared/dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component.html @@ -0,0 +1,11 @@ +
+ + +
diff --git a/src/app/shared/dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component.ts b/src/app/shared/dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component.ts index 4822849e4c..c1ae583908 100644 --- a/src/app/shared/dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component.ts +++ b/src/app/shared/dso-selector/modal-wrappers/edit-item-selector/edit-item-selector.component.ts @@ -14,7 +14,7 @@ import { Item } from '../../../../core/shared/item.model'; @Component({ selector: 'ds-edit-item-selector', - templateUrl: '../dso-selector-modal-wrapper.component.html', + templateUrl: 'edit-item-selector.component.html', }) export class EditItemSelectorComponent extends DSOSelectorModalWrapperComponent implements OnInit { objectType = DSpaceObjectType.ITEM; diff --git a/src/app/shared/search-form/scope-selector-modal/scope-selector-modal.component.html b/src/app/shared/search-form/scope-selector-modal/scope-selector-modal.component.html index e7165a9213..013274320b 100644 --- a/src/app/shared/search-form/scope-selector-modal/scope-selector-modal.component.html +++ b/src/app/shared/search-form/scope-selector-modal/scope-selector-modal.component.html @@ -14,6 +14,6 @@
{{'dso-selector.' + action + '.' + objectType.toString().toLowerCase() + '.input-header' | translate}}
- + diff --git a/src/app/shared/search-form/scope-selector-modal/scope-selector-modal.component.ts b/src/app/shared/search-form/scope-selector-modal/scope-selector-modal.component.ts index 86c3010287..3301435956 100644 --- a/src/app/shared/search-form/scope-selector-modal/scope-selector-modal.component.ts +++ b/src/app/shared/search-form/scope-selector-modal/scope-selector-modal.component.ts @@ -4,6 +4,8 @@ import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; import { DSpaceObjectType } from '../../../core/shared/dspace-object-type.model'; import { DSOSelectorModalWrapperComponent, SelectorActionType } from '../../dso-selector/modal-wrappers/dso-selector-modal-wrapper.component'; import { DSpaceObject } from '../../../core/shared/dspace-object.model'; +import { SortDirection, SortOptions } from '../../../core/cache/models/sort-options.model'; +import { environment } from '../../../../environments/environment'; /** * Component to wrap a button - to select the entire repository - @@ -33,6 +35,11 @@ export class ScopeSelectorModalComponent extends DSOSelectorModalWrapperComponen */ scopeChange = new EventEmitter(); + /** + * Default DSO ordering + */ + defaultSort = new SortOptions(environment.comcolSelectionSort.sortField, environment.comcolSelectionSort.sortDirection as SortDirection); + constructor(protected activeModal: NgbActiveModal, protected route: ActivatedRoute) { super(activeModal, route); } diff --git a/src/config/app-config.interface.ts b/src/config/app-config.interface.ts index d62b9e5bcb..e3f8988744 100644 --- a/src/config/app-config.interface.ts +++ b/src/config/app-config.interface.ts @@ -21,6 +21,7 @@ import { CommunityListConfig } from './community-list-config.interface'; import { HomeConfig } from './homepage-config.interface'; import { MarkdownConfig } from './markdown-config.interface'; import { FilterVocabularyConfig } from './filter-vocabulary-config'; +import { DiscoverySortConfig } from './discovery-sort.config'; interface AppConfig extends Config { ui: UIServerConfig; @@ -46,6 +47,7 @@ interface AppConfig extends Config { info: InfoConfig; markdown: MarkdownConfig; vocabularies: FilterVocabularyConfig[]; + comcolSelectionSort: DiscoverySortConfig; } /** diff --git a/src/config/default-app-config.ts b/src/config/default-app-config.ts index e7851d4b34..67c2feada8 100644 --- a/src/config/default-app-config.ts +++ b/src/config/default-app-config.ts @@ -21,6 +21,7 @@ import { CommunityListConfig } from './community-list-config.interface'; import { HomeConfig } from './homepage-config.interface'; import { MarkdownConfig } from './markdown-config.interface'; import { FilterVocabularyConfig } from './filter-vocabulary-config'; +import { DiscoverySortConfig } from './discovery-sort.config'; export class DefaultAppConfig implements AppConfig { production = false; @@ -421,4 +422,10 @@ export class DefaultAppConfig implements AppConfig { enabled: false } ]; + + // Configuration that determines the metadata sorting of community and collection edition and creation when there are not a search query. + comcolSelectionSort: DiscoverySortConfig = { + sortField:'dc.title', + sortDirection:'ASC', + }; } diff --git a/src/config/discovery-sort.config.ts b/src/config/discovery-sort.config.ts new file mode 100644 index 0000000000..c0d5e5e391 --- /dev/null +++ b/src/config/discovery-sort.config.ts @@ -0,0 +1,14 @@ +import { Config } from './config.interface'; + +/** + * Config that determines a metadata sorting config. + * It's created mainly to sort by metadata community and collection edition and creation + */ +export class DiscoverySortConfig implements Config { + + public sortField: string; + /** + * ASC / DESC values expected + */ + public sortDirection: string; +} diff --git a/src/environments/environment.test.ts b/src/environments/environment.test.ts index 0bb36da61f..08d7739f7d 100644 --- a/src/environments/environment.test.ts +++ b/src/environments/environment.test.ts @@ -297,6 +297,10 @@ export const environment: BuildConfig = { enabled: false, mathjax: false, }, + comcolSelectionSort: { + sortField:'dc.title', + sortDirection:'ASC', + }, vocabularies: [ { diff --git a/src/themes/custom/app/shared/dso-selector/modal-wrappers/create-collection-parent-selector/create-collection-parent-selector.component.html b/src/themes/custom/app/shared/dso-selector/modal-wrappers/create-collection-parent-selector/create-collection-parent-selector.component.html index 85d8797e66..54044f5d79 100644 --- a/src/themes/custom/app/shared/dso-selector/modal-wrappers/create-collection-parent-selector/create-collection-parent-selector.component.html +++ b/src/themes/custom/app/shared/dso-selector/modal-wrappers/create-collection-parent-selector/create-collection-parent-selector.component.html @@ -6,6 +6,6 @@ diff --git a/src/themes/custom/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.html b/src/themes/custom/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.html index 4a22672988..a13be63880 100644 --- a/src/themes/custom/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.html +++ b/src/themes/custom/app/shared/dso-selector/modal-wrappers/create-community-parent-selector/create-community-parent-selector.component.html @@ -14,6 +14,6 @@
{{'dso-selector.create.community.sub-level' | translate}}
- + diff --git a/src/themes/custom/app/shared/dso-selector/modal-wrappers/edit-collection-selector/edit-collection-selector.component.html b/src/themes/custom/app/shared/dso-selector/modal-wrappers/edit-collection-selector/edit-collection-selector.component.html index 85d8797e66..54044f5d79 100644 --- a/src/themes/custom/app/shared/dso-selector/modal-wrappers/edit-collection-selector/edit-collection-selector.component.html +++ b/src/themes/custom/app/shared/dso-selector/modal-wrappers/edit-collection-selector/edit-collection-selector.component.html @@ -6,6 +6,6 @@ diff --git a/src/themes/custom/app/shared/dso-selector/modal-wrappers/edit-community-selector/edit-community-selector.component.html b/src/themes/custom/app/shared/dso-selector/modal-wrappers/edit-community-selector/edit-community-selector.component.html index 85d8797e66..54044f5d79 100644 --- a/src/themes/custom/app/shared/dso-selector/modal-wrappers/edit-community-selector/edit-community-selector.component.html +++ b/src/themes/custom/app/shared/dso-selector/modal-wrappers/edit-community-selector/edit-community-selector.component.html @@ -6,6 +6,6 @@