diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 241f9da835..f359c7be71 100755 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -21,6 +21,8 @@ import { ItemPageModule } from './item-page/item-page.module'; import { CollectionPageModule } from './collection-page/collection-page.module'; import { CommunityPageModule } from './community-page/community-page.module'; +import { SearchPageModule } from './search-page/search-page.module'; + import { AppComponent } from './app.component'; import { HeaderComponent } from './header/header.component'; import { PageNotFoundComponent } from './pagenotfound/pagenotfound.component'; @@ -42,6 +44,7 @@ export function getConfig() { ItemPageModule, CollectionPageModule, CommunityPageModule, + SearchPageModule, AppRoutingModule, StoreModule.provideStore(rootReducer), RouterStoreModule.connectRouter(), diff --git a/src/app/core/shared/dspace-object.model.ts b/src/app/core/shared/dspace-object.model.ts index ad3c2dac8c..8584c179dc 100644 --- a/src/app/core/shared/dspace-object.model.ts +++ b/src/app/core/shared/dspace-object.model.ts @@ -3,11 +3,12 @@ import { isEmpty, isNotEmpty } from '../../shared/empty.util'; import { CacheableObject } from '../cache/object-cache.reducer'; import { RemoteData } from '../data/remote-data'; import { ResourceType } from './resource-type'; +import { ListableObject } from '../../object-list/listable-object/listable-object.model'; /** * An abstract model class for a DSpaceObject. */ -export abstract class DSpaceObject implements CacheableObject { +export abstract class DSpaceObject implements CacheableObject, ListableObject { self: string; diff --git a/src/app/object-list/collection-list-element/collection-list-element.component.html b/src/app/object-list/collection-list-element/collection-list-element.component.html index c680743716..8fb498d474 100644 --- a/src/app/object-list/collection-list-element/collection-list-element.component.html +++ b/src/app/object-list/collection-list-element/collection-list-element.component.html @@ -1,6 +1,6 @@ - - {{collection.name}} + + {{object.name}} -
- {{collection.shortDescription}} +
+ {{object.shortDescription}}
diff --git a/src/app/object-list/collection-list-element/collection-list-element.component.ts b/src/app/object-list/collection-list-element/collection-list-element.component.ts index 45f285a60b..a1a76f3a97 100644 --- a/src/app/object-list/collection-list-element/collection-list-element.component.ts +++ b/src/app/object-list/collection-list-element/collection-list-element.component.ts @@ -1,16 +1,14 @@ -import { Component, Input } from '@angular/core'; +import { Component } from '@angular/core'; import { Collection } from '../../core/shared/collection.model'; +import { ObjectListElementComponent } from '../object-list-element/object-list-element.component'; +import { listElementFor } from '../list-element-decorator'; @Component({ selector: 'ds-collection-list-element', styleUrls: ['./collection-list-element.component.scss'], templateUrl: './collection-list-element.component.html' }) -export class CollectionListElementComponent { - @Input() collection: Collection; - - data: any = {}; - -} +@listElementFor(Collection) +export class CollectionListElementComponent extends ObjectListElementComponent {} diff --git a/src/app/object-list/community-list-element/community-list-element.component.html b/src/app/object-list/community-list-element/community-list-element.component.html index 2c2f4fc35f..d39995de40 100644 --- a/src/app/object-list/community-list-element/community-list-element.component.html +++ b/src/app/object-list/community-list-element/community-list-element.component.html @@ -1,6 +1,6 @@ - - {{community.name}} + + {{object.name}} -
- {{community.shortDescription}} +
+ {{object.shortDescription}}
diff --git a/src/app/object-list/community-list-element/community-list-element.component.ts b/src/app/object-list/community-list-element/community-list-element.component.ts index 634e573e92..2c193e7488 100644 --- a/src/app/object-list/community-list-element/community-list-element.component.ts +++ b/src/app/object-list/community-list-element/community-list-element.component.ts @@ -1,16 +1,14 @@ import { Component, Input } from '@angular/core'; import { Community } from '../../core/shared/community.model'; +import { ObjectListElementComponent } from '../object-list-element/object-list-element.component'; +import { listElementFor } from '../list-element-decorator'; @Component({ selector: 'ds-community-list-element', styleUrls: ['./community-list-element.component.scss'], templateUrl: './community-list-element.component.html' }) -export class CommunityListElementComponent { - @Input() community: Community; - - data: any = {}; - -} +@listElementFor(Community) +export class CommunityListElementComponent extends ObjectListElementComponent {} diff --git a/src/app/object-list/item-list-element/item-list-element.component.html b/src/app/object-list/item-list-element/item-list-element.component.html index 517cae480f..cc24ba76b8 100644 --- a/src/app/object-list/item-list-element/item-list-element.component.html +++ b/src/app/object-list/item-list-element/item-list-element.component.html @@ -1,14 +1,14 @@ - - {{item.findMetadata("dc.title")}} + + {{object.findMetadata("dc.title")}}
- - {{authorMd.value}} + + {{authorMd.value}} ; - ({{item.findMetadata("dc.publisher")}}, {{item.findMetadata("dc.date.issued")}}) + ({{object.findMetadata("dc.publisher")}}, {{object.findMetadata("dc.date.issued")}}) -
{{item.findMetadata("dc.description.abstract") | dsTruncate:[200] }}
+
{{object.findMetadata("dc.description.abstract") | dsTruncate:[200] }}
diff --git a/src/app/object-list/item-list-element/item-list-element.component.ts b/src/app/object-list/item-list-element/item-list-element.component.ts index 880f3d9fdc..14e4ea8b77 100644 --- a/src/app/object-list/item-list-element/item-list-element.component.ts +++ b/src/app/object-list/item-list-element/item-list-element.component.ts @@ -1,15 +1,14 @@ import { Component, Input } from '@angular/core'; import { Item } from '../../core/shared/item.model'; +import { ObjectListElementComponent } from '../object-list-element/object-list-element.component'; +import { listElementFor } from '../list-element-decorator'; @Component({ selector: 'ds-item-list-element', styleUrls: ['./item-list-element.component.scss'], templateUrl: './item-list-element.component.html' }) -export class ItemListElementComponent { - @Input() item: Item; - data: any = {}; - -} +@listElementFor(Item) +export class ItemListElementComponent extends ObjectListElementComponent {} diff --git a/src/app/object-list/list-element-decorator.ts b/src/app/object-list/list-element-decorator.ts new file mode 100644 index 0000000000..37f820d77c --- /dev/null +++ b/src/app/object-list/list-element-decorator.ts @@ -0,0 +1,12 @@ +import { ListableObject } from './listable-object/listable-object.model'; +import { GenericConstructor } from '../core/shared/generic-constructor'; + +const listElementForMetadataKey = Symbol('listElementFor'); + +export function listElementFor(value: GenericConstructor) { + return Reflect.metadata(listElementForMetadataKey, value); +} + +export function getListElementFor(target: any) { + return Reflect.getOwnMetadata(listElementForMetadataKey, target); +} diff --git a/src/app/object-list/listable-object/listable-object.model.ts b/src/app/object-list/listable-object/listable-object.model.ts new file mode 100644 index 0000000000..85cea9fb36 --- /dev/null +++ b/src/app/object-list/listable-object/listable-object.model.ts @@ -0,0 +1,3 @@ +export interface ListableObject { + +} \ No newline at end of file diff --git a/src/app/object-list/object-list-element/object-list-element.component.html b/src/app/object-list/object-list-element/object-list-element.component.html index 5feb69b3a6..e69de29bb2 100644 --- a/src/app/object-list/object-list-element/object-list-element.component.html +++ b/src/app/object-list/object-list-element/object-list-element.component.html @@ -1,5 +0,0 @@ -
- - - -
\ No newline at end of file diff --git a/src/app/object-list/object-list-element/object-list-element.component.ts b/src/app/object-list/object-list-element/object-list-element.component.ts index 4b5f56e1e1..1b7ce2701e 100644 --- a/src/app/object-list/object-list-element/object-list-element.component.ts +++ b/src/app/object-list/object-list-element/object-list-element.component.ts @@ -1,6 +1,5 @@ -import { Component, Input, OnInit } from '@angular/core'; -import { DSpaceObject } from '../../core/shared/dspace-object.model'; -import { ResourceType } from '../../core/shared/resource-type'; +import { Component, Inject } from '@angular/core'; +import { ListableObject } from '../listable-object/listable-object.model'; @Component({ selector: 'ds-object-list-element', @@ -9,10 +8,6 @@ import { ResourceType } from '../../core/shared/resource-type'; }) export class ObjectListElementComponent { - public type = ResourceType; - - @Input() object: DSpaceObject; - - data: any = {}; - + // In the current version of Angular4, @Input is not supported by the NgComponentOutlet - instead we're using DI + constructor(@Inject('objectElementProvider') public object: ListableObject) { } } diff --git a/src/app/object-list/object-list.component.html b/src/app/object-list/object-list.component.html index da25195e27..8489b24d2b 100644 --- a/src/app/object-list/object-list.component.html +++ b/src/app/object-list/object-list.component.html @@ -10,7 +10,7 @@ (sortFieldChange)="onSortDirectionChange($event)">
  • - +
diff --git a/src/app/object-list/wrapper-list-element/wrapper-list-element.component.html b/src/app/object-list/wrapper-list-element/wrapper-list-element.component.html new file mode 100644 index 0000000000..d5cfebdfa5 --- /dev/null +++ b/src/app/object-list/wrapper-list-element/wrapper-list-element.component.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/app/object-list/wrapper-list-element/wrapper-list-element.component.scss b/src/app/object-list/wrapper-list-element/wrapper-list-element.component.scss new file mode 100644 index 0000000000..6b953dd833 --- /dev/null +++ b/src/app/object-list/wrapper-list-element/wrapper-list-element.component.scss @@ -0,0 +1,3 @@ +@import '../../../styles/variables.scss'; +@import '../../../../node_modules/bootstrap/scss/variables'; + diff --git a/src/app/object-list/wrapper-list-element/wrapper-list-element.component.ts b/src/app/object-list/wrapper-list-element/wrapper-list-element.component.ts new file mode 100644 index 0000000000..148d4fd986 --- /dev/null +++ b/src/app/object-list/wrapper-list-element/wrapper-list-element.component.ts @@ -0,0 +1,25 @@ +import { Component, Input, Injector, ReflectiveInjector, OnInit } from '@angular/core'; +import { ListableObject } from '../listable-object/listable-object.model'; +import { getListElementFor } from '../list-element-decorator' + +@Component({ + selector: 'ds-wrapper-list-element', + styleUrls: ['./wrapper-list-element.component.scss'], + templateUrl: './wrapper-list-element.component.html' +}) +export class WrapperListElementComponent implements OnInit { + @Input() object: ListableObject; + objectInjector: Injector; + + constructor(private injector: Injector) {} + + ngOnInit(): void { + this.objectInjector = ReflectiveInjector.resolveAndCreate( + [{provide: 'objectElementProvider', useFactory: () => ({ providedObject: this.object }) }], this.injector); + + } + + private getListElement(): string { + return getListElementFor(this.object.constructor).constructor.name; + } +} diff --git a/src/app/search-page/search-page-routing.module.ts b/src/app/search-page/search-page-routing.module.ts new file mode 100644 index 0000000000..76b7d9ad0c --- /dev/null +++ b/src/app/search-page/search-page-routing.module.ts @@ -0,0 +1,13 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; + +import { SearchPageComponent } from './search-page.component'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: 'search', component: SearchPageComponent } + ]) + ] +}) +export class SearchPageRoutingModule { } diff --git a/src/app/search-page/search-page.component.html b/src/app/search-page/search-page.component.html new file mode 100644 index 0000000000..6c56d339b2 --- /dev/null +++ b/src/app/search-page/search-page.component.html @@ -0,0 +1,4 @@ +
+ + +
diff --git a/src/app/search-page/search-page.component.scss b/src/app/search-page/search-page.component.scss new file mode 100644 index 0000000000..da97dd7a62 --- /dev/null +++ b/src/app/search-page/search-page.component.scss @@ -0,0 +1 @@ +@import '../../styles/variables.scss'; diff --git a/src/app/search-page/search-page.component.ts b/src/app/search-page/search-page.component.ts new file mode 100644 index 0000000000..a533817a37 --- /dev/null +++ b/src/app/search-page/search-page.component.ts @@ -0,0 +1,42 @@ +import { Component, OnInit } from '@angular/core'; +import { SearchService } from '../search/search.service'; +import { ActivatedRoute } from '@angular/router'; +import { SortOptions } from '../core/cache/models/sort-options.model'; +import { RemoteData } from '../core/data/remote-data'; +import { SearchResult } from '../search/search-result.model'; +import { DSpaceObject } from '../core/shared/dspace-object.model'; + +/** + * This component renders a simple item page. + * The route parameter 'id' is used to request the item it represents. + * All fields of the item that should be displayed, are defined in its template. + */ + +@Component({ + selector: 'ds-search-page', + styleUrls: ['./search-page.component.scss'], + templateUrl: './search-page.component.html', +}) +export class SearchPageComponent implements OnInit { + private sub; + private results: RemoteData>>; + + constructor( + private service: SearchService, + private route: ActivatedRoute, + ) { } + + ngOnInit(): void { + this.sub = this.route + .queryParams + .subscribe((params) => { + const query: string = params.query || ''; + const scope: string = params.scope; + const page: number = +params.page || 0; + this.results = this.service.search(query, scope, {elementsPerPage: 10, currentPage: page, sort: new SortOptions()}); + }); + } + ngOnDestroy() { + this.sub.unsubscribe(); + } +} diff --git a/src/app/search-page/search-page.module.ts b/src/app/search-page/search-page.module.ts new file mode 100644 index 0000000000..f641c8b16a --- /dev/null +++ b/src/app/search-page/search-page.module.ts @@ -0,0 +1,27 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { RouterModule } from '@angular/router'; + +import { TranslateModule } from '@ngx-translate/core'; + +import { SharedModule } from '../shared/shared.module'; +import { SearchPageRoutingModule } from './search-page-routing.module'; +import { SearchPageComponent } from './search-page.component'; +import { SearchFormComponent } from '../shared/search-form/search-form.component'; +import { SearchResultsComponent } from './search-results/search-results.compontent'; + +@NgModule({ + imports: [ + SearchPageRoutingModule, + CommonModule, + TranslateModule, + RouterModule, + SharedModule, + ], + declarations: [ + SearchPageComponent, + SearchFormComponent, + SearchResultsComponent + ] +}) +export class SearchPageModule { } diff --git a/src/app/search-page/search-results/search-results.component.html b/src/app/search-page/search-results/search-results.component.html new file mode 100644 index 0000000000..9c75ea43e4 --- /dev/null +++ b/src/app/search-page/search-results/search-results.component.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/app/search-page/search-results/search-results.compontent.ts b/src/app/search-page/search-results/search-results.compontent.ts new file mode 100644 index 0000000000..daf5ad6c27 --- /dev/null +++ b/src/app/search-page/search-results/search-results.compontent.ts @@ -0,0 +1,23 @@ +import { Component, OnInit, Input } from '@angular/core'; +import { RemoteData } from '../../core/data/remote-data'; +import { DSpaceObject } from '../../core/shared/dspace-object.model'; + +/** + * This component renders a simple item page. + * The route parameter 'id' is used to request the item it represents. + * All fields of the item that should be displayed, are defined in its template. + */ + +@Component({ + selector: 'ds-search-results', + templateUrl: './search-results.component.html', +}) + +export class SearchResultsComponent implements OnInit { + @Input() searchResults: RemoteData; + + ngOnInit(): void { + // onInit + + } +} diff --git a/src/app/search/search-result.model.ts b/src/app/search/search-result.model.ts index 9901aa212e..2dd9130ee8 100644 --- a/src/app/search/search-result.model.ts +++ b/src/app/search/search-result.model.ts @@ -1,7 +1,8 @@ import { DSpaceObject } from '../core/shared/dspace-object.model'; import { Metadatum } from '../core/shared/metadatum.model'; +import { ListableObject } from '../object-list/listable-object/listable-object.model'; -export class SearchResult{ +export class SearchResult implements ListableObject { dspaceObject: T; hitHighlights: Metadatum[]; diff --git a/src/app/shared/object-list/object-list.component.ts b/src/app/shared/object-list/object-list.component.ts index fd42e640fa..20b6ec0873 100644 --- a/src/app/shared/object-list/object-list.component.ts +++ b/src/app/shared/object-list/object-list.component.ts @@ -11,12 +11,12 @@ import { import { Observable } from 'rxjs/Observable'; import { RemoteData } from '../../core/data/remote-data'; -import { DSpaceObject } from '../../core/shared/dspace-object.model'; import { PageInfo } from '../../core/shared/page-info.model'; import { PaginationComponentOptions } from '../pagination/pagination-component-options.model'; import { SortOptions, SortDirection } from '../../core/cache/models/sort-options.model'; +import { ListableObject } from '../../object-list/listable-object/listable-object.model'; @Component({ changeDetection: ChangeDetectionStrategy.Default, @@ -27,7 +27,7 @@ import { SortOptions, SortDirection } from '../../core/cache/models/sort-options }) export class ObjectListComponent implements OnChanges, OnInit { - @Input() objects: RemoteData; + @Input() objects: RemoteData; @Input() config: PaginationComponentOptions; @Input() sortConfig: SortOptions; @Input() hideGear = false; diff --git a/src/app/shared/search-form/search-form.component.html b/src/app/shared/search-form/search-form.component.html new file mode 100644 index 0000000000..3ab94ca338 --- /dev/null +++ b/src/app/shared/search-form/search-form.component.html @@ -0,0 +1,15 @@ +
+
+ +
+ + + +
+
+
diff --git a/src/app/shared/search-form/search-form.component.scss b/src/app/shared/search-form/search-form.component.scss new file mode 100644 index 0000000000..50be6f5ad0 --- /dev/null +++ b/src/app/shared/search-form/search-form.component.scss @@ -0,0 +1 @@ +@import '../../../styles/variables.scss'; diff --git a/src/app/shared/search-form/search-form.component.ts b/src/app/shared/search-form/search-form.component.ts new file mode 100644 index 0000000000..3681a2898e --- /dev/null +++ b/src/app/shared/search-form/search-form.component.ts @@ -0,0 +1,28 @@ +import { Component, OnInit } from '@angular/core'; +import { FormGroup, FormControl } from '@angular/forms'; + +/** + * This component renders a simple item page. + * The route parameter 'id' is used to request the item it represents. + * All fields of the item that should be displayed, are defined in its template. + */ + +@Component({ + selector: 'ds-search-form', + styleUrls: ['./search-form.component.scss'], + templateUrl: './search-form.component.html', +}) +export class SearchFormComponent implements OnInit { + searchFormGroup: FormGroup; + // + // constructor() { + // + // } + // + ngOnInit(): void { + this.searchFormGroup = new FormGroup({ + firstName: new FormControl() + }); + } + +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index d1699537b6..552ea7e3bc 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -24,6 +24,7 @@ import { ItemListElementComponent } from '../object-list/item-list-element/item- import { CommunityListElementComponent } from '../object-list/community-list-element/community-list-element.component'; import { CollectionListElementComponent } from '../object-list/collection-list-element/collection-list-element.component'; import { TruncatePipe } from './utils/truncate.pipe'; +import { WrapperListElementComponent } from '../object-list/wrapper-list-element/wrapper-list-element.component'; const MODULES = [ // Do NOT include UniversalModule, HttpModule, or JsonpModule here @@ -53,6 +54,7 @@ const COMPONENTS = [ ComcolPageLogoComponent, ObjectListComponent, ObjectListElementComponent, + WrapperListElementComponent, ItemListElementComponent, CollectionListElementComponent, CommunityListElementComponent diff --git a/src/routes.ts b/src/routes.ts index bbb4b72ec1..f051b16198 100644 --- a/src/routes.ts +++ b/src/routes.ts @@ -3,5 +3,6 @@ export const ROUTES: string[] = [ 'items/:id', 'collections/:id', 'communities/:id', + 'search', '**' ];