refactored lookup

This commit is contained in:
lotte
2019-03-01 16:41:38 +01:00
parent bc305e2aa6
commit 61a5620efe
18 changed files with 223 additions and 189 deletions

View File

@@ -10,10 +10,9 @@ module.exports = {
// The REST API server settings.
rest: {
ssl: true,
host: 'dspace7.4science.it',
host: 'dspace7-internal.atmire.com',
port: 443,
// NOTE: Space is capitalized because 'namespace' is a reserved string in TypeScript
nameSpace: '/dspace-spring-rest/api'
nameSpace: '/rest/api'
},
// Caching settings
cache: {

View File

@@ -13,6 +13,8 @@ import { combineLatest as combineLatestObservable } from 'rxjs';
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import { OnClickMenuItemModel } from '../../shared/menu/menu-item/models/onclick.model';
import { CollectionSelectorModalWrapperComponent } from '../../shared/dso-selector/collection-selector-modal-wrapper/collection-selector-modal-wrapper.component';
import { ItemSelectorModalWrapperComponent } from '../../shared/dso-selector/item-selector-modal-wrapper/item-selector-modal-wrapper.component';
import { CommunitySelectorModalWrapperComponent } from '../../shared/dso-selector/community-selector-modal-wrapper/community-selector-modal-wrapper.component';
/**
* Component representing the admin sidebar
@@ -111,8 +113,7 @@ export class AdminSidebarComponent extends MenuComponent implements OnInit {
type: MenuItemType.ONCLICK,
text: 'menu.section.new_community',
function: () => {
const modal = this.modalService.open(CollectionSelectorModalWrapperComponent);
modal.componentInstance.currentCollectionID = 'c069b0c2-dc6a-40de-92c3-6803cd66023e';
this.modalService.open(CommunitySelectorModalWrapperComponent);
}
} as OnClickMenuItemModel,
},
@@ -122,10 +123,12 @@ export class AdminSidebarComponent extends MenuComponent implements OnInit {
active: false,
visible: true,
model: {
type: MenuItemType.LINK,
type: MenuItemType.ONCLICK,
text: 'menu.section.new_collection',
link: '/collections/submission'
} as LinkMenuItemModel,
function: () => {
this.modalService.open(CollectionSelectorModalWrapperComponent);
}
} as OnClickMenuItemModel,
},
{
id: 'new_item',
@@ -133,10 +136,12 @@ export class AdminSidebarComponent extends MenuComponent implements OnInit {
active: false,
visible: true,
model: {
type: MenuItemType.LINK,
type: MenuItemType.ONCLICK,
text: 'menu.section.new_item',
link: '/items/submission'
} as LinkMenuItemModel,
function: () => {
this.modalService.open(ItemSelectorModalWrapperComponent);
}
} as OnClickMenuItemModel,
},
{
id: 'new_item_version',

View File

@@ -15,7 +15,6 @@ import { DeleteCollectionPageComponent } from './delete-collection-page/delete-c
imports: [
CommonModule,
SharedModule,
SearchPageModule,
CollectionPageRoutingModule
],
declarations: [

View File

@@ -65,7 +65,6 @@ const effects = [
SearchBooleanFilterComponent,
],
providers: [
SearchService,
SearchSidebarService,
SearchFilterService,
SearchConfigurationService

View File

@@ -119,19 +119,8 @@ export class RemoteDataBuildService {
}
const requestEntry$ = href$.pipe(getRequestFromRequestHref(this.requestService));
requestEntry$.subscribe((t) => {
console.log('requestEntry$', t)
});
const tDomainList$ = requestEntry$.pipe(
getResourceLinksFromResponse(),
tap((resourceUUIDs: string[]) => {
const g = (href$ as Observable<string>)
g.subscribe((t) => {
console.log('href', t)
});
console.log(resourceUUIDs);
}),
flatMap((resourceUUIDs: string[]) => {
return this.objectCache.getList(resourceUUIDs).pipe(
map((normList: Array<NormalizedObject<T>>) => {

View File

@@ -69,6 +69,7 @@ import { NormalizedObjectBuildService } from './cache/builders/normalized-object
import { DSOChangeAnalyzer } from './data/dso-change-analyzer.service';
import { ObjectUpdatesService } from './data/object-updates/object-updates.service';
import { DefaultChangeAnalyzer } from './data/default-change-analyzer.service';
import { SearchService } from '../+search-page/search-service/search.service';
const IMPORTS = [
CommonModule,
@@ -138,6 +139,7 @@ const PROVIDERS = [
CSSVariableService,
MenuService,
ObjectUpdatesService,
SearchService,
// register AuthInterceptor as HttpInterceptor
{
provide: HTTP_INTERCEPTORS,

View File

@@ -14,6 +14,7 @@ import { BrowseItemsResponseParsingService } from './browse-items-response-parsi
import { RegistryMetadataschemasResponseParsingService } from './registry-metadataschemas-response-parsing.service';
import { MetadataschemaParsingService } from './metadataschema-parsing.service';
import { MetadatafieldParsingService } from './metadatafield-parsing.service';
import { URLCombiner } from '../url-combiner/url-combiner';
/* tslint:disable:max-classes-per-file */
@@ -146,11 +147,11 @@ export class FindAllRequest extends GetRequest {
export class EndpointMapRequest extends GetRequest {
constructor(
public uuid: string,
public href: string,
public body?: any
uuid: string,
href: string,
body?: any
) {
super(uuid, href, body);
super(uuid, new URLCombiner(href, '?endpointMap').toString(), body);
}
getResponseParser(): GenericConstructor<ResponseParsingService> {

View File

@@ -1,6 +1,6 @@
<div>
<div class="modal-header">New item</div>
<div class="modal-header">New Collection</div>
<div class="modal-body">
<ds-collection-selector [currentCollectionId]="currentCollectionID"></ds-collection-selector>
<ds-dso-selector [currentDSOId]="communityRD?.payload.uuid"></ds-dso-selector>
</div>
</div>

View File

@@ -1,10 +1,20 @@
import { Component, Input } from '@angular/core';
import { Component, Input, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Community } from '../../../core/shared/community.model';
import { RemoteData } from '../../../core/data/remote-data';
@Component({
selector: 'ds-collection-selector-modal-wrapper',
// styleUrls: ['./collection-selector.component.scss'],
templateUrl: './collection-selector-modal-wrapper.component.html',
})
export class CollectionSelectorModalWrapperComponent {
@Input() currentCollectionID: string;
export class CollectionSelectorModalWrapperComponent implements OnInit {
@Input() communityRD: RemoteData<Community>;
constructor(private route: ActivatedRoute) {
}
ngOnInit(): void {
this.communityRD = this.route.root.firstChild.firstChild.snapshot.data.community;
}
}

View File

@@ -1,26 +0,0 @@
<div class="form-group w-100 pr-2 pl-2">
<input *ngIf="searchField"
type="search"
class="form-control w-100"
(click)="$event.stopPropagation();"
placeholder="{{ 'submission.sections.general.search-collection' | translate }}"
[formControl]="searchField">
</div>
<div class="dropdown-divider"></div>
<div class="scrollable-menu" aria-labelledby="dropdownMenuButton">
<button class="dropdown-item disabled" *ngIf="(searchListCollection$ | async)?.length == 0">
{{'submission.sections.general.no-collection' | translate}}
</button>
<button *ngFor="let listItem of (searchListCollection$ | async)"
class="dropdown-item collection-item"
title="{{ listItem.collection.name }}"
(click)="onSelect(listItem)">
<ul class="list-unstyled mb-0">
<li class="list-item text-truncate text-secondary"
*ngFor="let item of listItem.communities">
{{ item.name}} <i class="fa fa-level-down" aria-hidden="true"></i>
</li>
<li class="list-item text-truncate text-primary font-weight-bold">{{ listItem.collection.name}}</li>
</ul>
</button>
</div>

View File

@@ -1,125 +0,0 @@
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core';
import { FormControl } from '@angular/forms';
import { BehaviorSubject, combineLatest, Observable, Subscription } from 'rxjs';
import {
debounceTime,
distinctUntilChanged,
filter,
find,
flatMap,
map,
mergeMap,
reduce,
startWith
} from 'rxjs/operators';
import { Collection } from '../../../core/shared/collection.model';
import { CommunityDataService } from '../../../core/data/community-data.service';
import { Community } from '../../../core/shared/community.model';
import { hasValue, isEmpty, isNotEmpty } from '../../../shared/empty.util';
import { RemoteData } from '../../../core/data/remote-data';
import { PaginatedList } from '../../../core/data/paginated-list';
import { getSucceededRemoteData } from '../../../core/shared/operators';
interface CollectionListEntryItem {
id: string;
name: string;
}
interface CollectionListEntry {
communities: CollectionListEntryItem[],
collection: CollectionListEntryItem
}
@Component({
selector: 'ds-collection-selector',
// styleUrls: ['./collection-selector.component.scss'],
templateUrl: './collection-selector.component.html'
})
export class CollectionSelectorComponent implements OnChanges {
@Input() currentCollectionId: string;
public disabled$ = new BehaviorSubject<boolean>(true);
public model: any;
public searchField: FormControl = new FormControl();
public searchListCollection$: Observable<CollectionListEntry[]>;
public selectedCollectionId: string;
public selectedCollectionName$: Observable<string>;
private subs: Subscription[] = [];
constructor(private communityDataService: CommunityDataService) {
}
ngOnChanges(changes: SimpleChanges) {
if (hasValue(changes.currentCollectionId)
&& hasValue(changes.currentCollectionId.currentValue)) {
this.selectedCollectionId = this.currentCollectionId;
// @TODO replace with search/top browse endpoint
// @TODO implement community/subcommunity hierarchy
const communities$ = this.communityDataService.findAll().pipe(
find((communities: RemoteData<PaginatedList<Community>>) => isNotEmpty(communities.payload)),
mergeMap((communities: RemoteData<PaginatedList<Community>>) => communities.payload.page));
communities$.subscribe((t) => {console.log('communities', t)});
// const listCollection$ = communities$.pipe(
// flatMap((communityData: Community) => {
// return communityData.collections.pipe(
// getSucceededRemoteData(),
// mergeMap((collections: RemoteData<PaginatedList<Collection>>) => collections.payload.page),
// filter((collectionData: Collection) => isNotEmpty(collectionData)),
// map((collectionData: Collection) => ({
// communities: [{ id: communityData.id, name: communityData.name }],
// collection: { id: collectionData.id, name: collectionData.name }
// }))
// );
// }),
// reduce((acc: any, value: any) => [...acc, ...value], []),
// startWith([])
// );
//
// this.selectedCollectionName$ = communities$.pipe(
// flatMap((communityData: Community) => {
// return communityData.collections.pipe(
// getSucceededRemoteData(),
// mergeMap((collections: RemoteData<PaginatedList<Collection>>) => collections.payload.page),
// filter((collectionData: Collection) => isNotEmpty(collectionData)),
// filter((collectionData: Collection) => collectionData.id === this.selectedCollectionId),
// map((collectionData: Collection) => collectionData.name)
// );
// }),
// startWith('')
// );
//
// const searchTerm$ = this.searchField.valueChanges.pipe(
// debounceTime(200),
// distinctUntilChanged(),
// startWith('')
// );
//
// this.searchListCollection$ = combineLatest(searchTerm$, listCollection$).pipe(
// map(([searchTerm, listCollection]) => {
// this.disabled$.next(isEmpty(listCollection));
// if (isEmpty(searchTerm)) {
// return listCollection;
// } else {
// return listCollection.filter((v) => v.collection.name.toLowerCase().indexOf(searchTerm.toLowerCase()) > -1).slice(0, 5)
// }
// }));
}
}
ngOnDestroy(): void {
this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe());
}
onSelect(event) {
this.searchField.reset();
this.disabled$.next(true);
}
onClose() {
this.searchField.reset();
}
}

View File

@@ -0,0 +1,7 @@
<div>
<div class="modal-header">New Community</div>
<div class="modal-body">
<input/>
<ds-currentDSOId-selector [currentDSOId]="communityRD?.payload.uuid"></ds-currentDSOId-selector>
</div>
</div>

View File

@@ -0,0 +1,20 @@
import { Component, Input, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Community } from '../../../core/shared/community.model';
import { RemoteData } from '../../../core/data/remote-data';
@Component({
selector: 'ds-community-selector-modal-wrapper',
// styleUrls: ['./community-selector.component.scss'],
templateUrl: './community-selector-modal-wrapper.component.html',
})
export class CommunitySelectorModalWrapperComponent implements OnInit {
@Input() communityRD: RemoteData<Community>;
constructor(private route: ActivatedRoute) {
}
ngOnInit(): void {
this.communityRD = this.route.root.firstChild.firstChild.snapshot.data.community;
}
}

View File

@@ -0,0 +1,27 @@
<div class="form-group w-100 pr-2 pl-2">
<input type="search"
class="form-control"
(click)="$event.stopPropagation();"
placeholder="{{ 'submission.sections.general.search-collection' | translate }}"
[formControl]="input">
</div>
{{input.value}}
<div class="dropdown-divider"></div>
<div class="scrollable-menu">
<button class="dropdown-item disabled" *ngIf="(listEntries$ | async)?.length == 0">
{{'submission.sections.general.no-collection' | translate}}
</button>
<button *ngFor="let listEntry of (listEntries$ | async)"
class="dropdown-item collection-item"
title="{{ listEntry.dso.name }}"
(click)="onSelect(listEntry.dso)">
<ul class="list-unstyled mb-0">
<li class="list-item text-truncate text-secondary"
*ngFor="let parent of listEntry.parents">
{{ parent.name }} <i class="fa fa-level-down" aria-hidden="true"></i>
</li>
<li class="list-item text-truncate text-primary font-weight-bold">{{ listEntry.dso.name }}</li>
</ul>
</button>
</div>

View File

@@ -0,0 +1,94 @@
import { AfterViewInit, Component, Input, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';
import { Observable } from 'rxjs';
import { map, switchMap } from 'rxjs/operators';
import { SearchService } from '../../../+search-page/search-service/search.service';
import { PaginatedSearchOptions } from '../../../+search-page/paginated-search-options.model';
import { DSpaceObjectType } from '../../../core/shared/dspace-object-type.model';
import { RemoteData } from '../../../core/data/remote-data';
import { PaginatedList } from '../../../core/data/paginated-list';
import { SearchResult } from '../../../+search-page/search-result.model';
import { DSpaceObject } from '../../../core/shared/dspace-object.model';
interface DSOSelectListEntry {
parents: DSpaceObject[],
dso: DSpaceObject
}
@Component({
selector: 'ds-dso-selector',
// styleUrls: ['./dso-selector.component.scss'],
templateUrl: './dso-selector.component.html'
})
export class DSOSelectorComponent implements OnInit, AfterViewInit {
@Input() currentDSOId: string;
@Input() type: DSpaceObjectType;
public input: FormControl = new FormControl();
// private subs: Subscription[] = [];
private defaultPagination = { id: 'dso-selector', currentPage: 1, pageSize: 5 } as any;
listEntries$: Observable<DSOSelectListEntry[]>;
constructor(private searchService: SearchService) {
}
ngOnInit(): void {
this.listEntries$ = this.input.valueChanges
.pipe(
switchMap((query) => {
return this.searchService.search(
new PaginatedSearchOptions({
query: query,
dsoType: this.type,
pagination: this.defaultPagination
})
)
}
),
map((searchResultsRD: RemoteData<PaginatedList<SearchResult<DSpaceObject>>>) => {
return searchResultsRD.payload.page.map(
(searchResult: SearchResult<DSpaceObject>) => {
let dso = searchResult.dspaceObject;
return {
parents: this.retrieveParentList(dso),
dso
} as DSOSelectListEntry
}
)
})
);
}
retrieveParentList(dso: DSpaceObject, parents: DSpaceObject[] = []) {
return [{name: 'Test Community'} as any];
// if (hasValue(dso.owner)) {
// dso.owner.pipe(
// first(),
// ).subscribe((parentRD) => {
// const newDSO: DSpaceObject = parentRD.payload;
// parents = [...this.retrieveParentList(newDSO, parents), newDSO];
// });
// }
// return parents;
}
// ngOnDestroy(): void {
// this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe());
// }
onSelect(event) {
}
onClose() {
}
ngAfterViewInit(): void {
this.input.setValue(this.currentDSOId);
}
}

View File

@@ -0,0 +1,6 @@
<div>
<div class="modal-header">New Item</div>
<div class="modal-body">
<ds-dso-selector [currentDSOId]="collectionRD?.payload.uuid"></ds-dso-selector>
</div>
</div>

View File

@@ -0,0 +1,21 @@
import { Component, Input, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { Community } from '../../../core/shared/community.model';
import { RemoteData } from '../../../core/data/remote-data';
import { Collection } from '../../../core/shared/collection.model';
@Component({
selector: 'ds-item-selector-modal-wrapper',
// styleUrls: ['./item-selector.component.scss'],
templateUrl: './item-selector-modal-wrapper.component.html',
})
export class ItemSelectorModalWrapperComponent implements OnInit {
@Input() collectionRD: RemoteData<Collection>;
constructor(private route: ActivatedRoute) {
}
ngOnInit(): void {
this.collectionRD = this.route.root.firstChild.firstChild.snapshot.data.collection;
}
}

View File

@@ -91,12 +91,14 @@ import { CreateComColPageComponent } from './comcol-forms/create-comcol-page/cre
import { EditComColPageComponent } from './comcol-forms/edit-comcol-page/edit-comcol-page.component';
import { DeleteComColPageComponent } from './comcol-forms/delete-comcol-page/delete-comcol-page.component';
import { LangSwitchComponent } from './lang-switch/lang-switch.component';
import { CollectionSelectorComponent } from './dso-selector/collection-selector/collection-selector.component';
import { CollectionSelectorModalWrapperComponent } from './dso-selector/collection-selector-modal-wrapper/collection-selector-modal-wrapper.component';
import { ObjectValuesPipe } from './utils/object-values-pipe';
import { InListValidator } from './utils/in-list-validator.directive';
import { AutoFocusDirective } from './utils/auto-focus.directive';
import { ComcolPageBrowseByComponent } from './comcol-page-browse-by/comcol-page-browse-by.component';
import { DSOSelectorComponent } from './dso-selector/dso-selector/dso-selector.component';
import { ItemSelectorModalWrapperComponent } from './dso-selector/item-selector-modal-wrapper/item-selector-modal-wrapper.component';
import { CommunitySelectorModalWrapperComponent } from './dso-selector/community-selector-modal-wrapper/community-selector-modal-wrapper.component';
const MODULES = [
// Do NOT include UniversalModule, HttpModule, or JsonpModule here
@@ -179,8 +181,10 @@ const COMPONENTS = [
TruncatablePartComponent,
BrowseByComponent,
InputSuggestionsComponent,
CollectionSelectorComponent,
CollectionSelectorModalWrapperComponent
DSOSelectorComponent,
CommunitySelectorModalWrapperComponent,
CollectionSelectorModalWrapperComponent,
ItemSelectorModalWrapperComponent
];
const ENTRY_COMPONENTS = [
@@ -194,8 +198,10 @@ const ENTRY_COMPONENTS = [
CommunityGridElementComponent,
SearchResultGridElementComponent,
BrowseEntryListElementComponent,
CollectionSelectorComponent,
CollectionSelectorModalWrapperComponent
DSOSelectorComponent,
CommunitySelectorModalWrapperComponent,
CollectionSelectorModalWrapperComponent,
ItemSelectorModalWrapperComponent
];
const PROVIDERS = [