diff --git a/package.json b/package.json index 3a54b941dd..80df678e38 100644 --- a/package.json +++ b/package.json @@ -75,6 +75,7 @@ }, "dependencies": { "@angular/animations": "^6.1.4", + "@angular/cdk": "^6.4.7", "@angular/cli": "^6.1.5", "@angular/common": "^6.1.4", "@angular/core": "^6.1.4", diff --git a/resources/i18n/en.json5 b/resources/i18n/en.json5 index 53db8e98c0..144b3128c7 100644 --- a/resources/i18n/en.json5 +++ b/resources/i18n/en.json5 @@ -340,6 +340,12 @@ + "communityList.tabTitle": "DSpace - Community List", + + "communityList.title": "List of Communities", + + + "community.create.head": "Create a Community", "community.create.sub-head": "Create a Sub-Community for Community {{ parent }}", diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 5085633a5b..bd29db4ab8 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -27,6 +27,7 @@ export function getAdminModulePath() { RouterModule.forRoot([ { path: '', redirectTo: '/home', pathMatch: 'full' }, { path: 'home', loadChildren: './+home-page/home-page.module#HomePageModule' }, + { path: 'community-list', loadChildren: './community-list-page/community-list-page.module#CommunityListPageModule' }, { path: 'id', loadChildren: './+lookup-by-id/lookup-by-id.module#LookupIdModule' }, { path: 'handle', loadChildren: './+lookup-by-id/lookup-by-id.module#LookupIdModule' }, { path: COMMUNITY_MODULE_PATH, loadChildren: './+community-page/community-page.module#CommunityPageModule' }, diff --git a/src/app/community-list-page/CommunityListDataSource.ts b/src/app/community-list-page/CommunityListDataSource.ts new file mode 100644 index 0000000000..4325d8b6cb --- /dev/null +++ b/src/app/community-list-page/CommunityListDataSource.ts @@ -0,0 +1,74 @@ +import {CommunityForList, CommunityListService} from './CommunityListService'; +import {CollectionViewer, DataSource} from '@angular/cdk/typings/collections'; +import {BehaviorSubject, Observable, of} from 'rxjs'; +import {catchError, finalize, map} from 'rxjs/operators'; + +export interface CommunityFlatNode { + expandable: boolean; + name: string; + level: number; + isExpanded?: boolean; + parent?: CommunityFlatNode; + community: CommunityForList; +} + +export class CommunityListDataSource implements DataSource { + + private communityListSubject = new BehaviorSubject([]); + private loadingSubject = new BehaviorSubject(false); + + public loading$ = this.loadingSubject.asObservable(); + + constructor(private communityListService: CommunityListService) {} + + connect(collectionViewer: CollectionViewer): Observable { + return this.communityListSubject.asObservable(); + } + + disconnect(collectionViewer: CollectionViewer): void { + this.communityListSubject.complete(); + this.loadingSubject.complete(); + } + + loadCommunities() { + this.loadingSubject.next(true); + + this.communityListService.getCommunityList() + .pipe( + catchError(() => of([])), + finalize(() => this.loadingSubject.next(false)), + map((result: CommunityForList[]) => { + const communityFlatNodes: CommunityFlatNode[] = []; + const level = 0; + return this.transformListOfCommunities(result, level, communityFlatNodes, null); + }) + ) + .subscribe((communityFlatNode) => { + this.communityListSubject.next(communityFlatNode) + }); + }; + + transformListOfCommunities(listOfCommunities: CommunityForList[], + level: number, + communityFlatNodes: CommunityFlatNode[], + parent: CommunityFlatNode): CommunityFlatNode[] { + level++; + for (const community of listOfCommunities) { + const hasSubComs = ((!!community.subcoms && community.subcoms.length > 0)); + const communityFlatNode: CommunityFlatNode = { + expandable: hasSubComs, + name: community.name, + level: level, + isExpanded: false, + community: community, + parent: parent + } + communityFlatNodes.push(communityFlatNode); + if (hasSubComs) { + this.transformListOfCommunities(community.subcoms, level, communityFlatNodes, communityFlatNode); + } + } + return communityFlatNodes; + } + +} diff --git a/src/app/community-list-page/CommunityListService.ts b/src/app/community-list-page/CommunityListService.ts new file mode 100644 index 0000000000..940a79ec50 --- /dev/null +++ b/src/app/community-list-page/CommunityListService.ts @@ -0,0 +1,24 @@ +import {Injectable} from '@angular/core'; +import {Observable, of} from 'rxjs'; + +export interface CommunityForList { + name: string; + subcoms?: CommunityForList[]; + collections?: string[]; + parent?: string; +} + +@Injectable() +export class CommunityListService { + + private comList: CommunityForList[] = [ + {name: 'com1', subcoms: [{name: 'subcom1', subcoms: [{name: 'subsubcom1'}], collections: null, parent: 'com1'}], collections: ['col1', 'col2'], parent: null}, + {name: 'com2', subcoms: [{name: 'subcom2', subcoms: null, collections: null, parent: 'com2'}, {name: 'subcom3', subcoms: null, collections: null, parent: 'com2'}], collections: ['col3', 'col4'], parent: null}, + {name: 'com3', subcoms: [{name: 'subcom4', subcoms: null, collections: null, parent: 'com3'}], collections: ['col5'], parent: null}, + ]; + + public getCommunityList(): Observable { + return of(this.comList); + } + +} diff --git a/src/app/community-list-page/community-list-page.component.html b/src/app/community-list-page/community-list-page.component.html new file mode 100644 index 0000000000..21e1b496a9 --- /dev/null +++ b/src/app/community-list-page/community-list-page.component.html @@ -0,0 +1,2 @@ +

{{ 'communityList.title' | translate }}

+ diff --git a/src/app/community-list-page/community-list-page.component.spec.ts b/src/app/community-list-page/community-list-page.component.spec.ts new file mode 100644 index 0000000000..68a98276a2 --- /dev/null +++ b/src/app/community-list-page/community-list-page.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CommunityListPageComponent } from './community-list-page.component'; + +describe('CommunityListPageComponent', () => { + let component: CommunityListPageComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ CommunityListPageComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CommunityListPageComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/community-list-page/community-list-page.component.ts b/src/app/community-list-page/community-list-page.component.ts new file mode 100644 index 0000000000..ea1dda1bab --- /dev/null +++ b/src/app/community-list-page/community-list-page.component.ts @@ -0,0 +1,15 @@ +import { Component, OnInit } from '@angular/core'; + +@Component({ + selector: 'ds-community-list-page', + templateUrl: './community-list-page.component.html', + styleUrls: ['./community-list-page.component.css'] +}) +export class CommunityListPageComponent implements OnInit { + + constructor() { } + + ngOnInit() { + } + +} diff --git a/src/app/community-list-page/community-list-page.module.ts b/src/app/community-list-page/community-list-page.module.ts new file mode 100644 index 0000000000..31a7c4e51a --- /dev/null +++ b/src/app/community-list-page/community-list-page.module.ts @@ -0,0 +1,23 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { SharedModule } from '../shared/shared.module'; +import {CommunityListPageComponent} from './community-list-page.component'; +import {CommunityListPageRoutingModule} from './community-list-page.routing.module'; +import { CommunityListComponent } from './community-list/community-list.component'; +import {CdkTreeModule} from '@angular/cdk/tree'; + +@NgModule({ + imports: [ + CommonModule, + SharedModule, + CommunityListPageRoutingModule, + CdkTreeModule, + ], + declarations: [ + CommunityListPageComponent, + CommunityListComponent + ] +}) +export class CommunityListPageModule { + +} diff --git a/src/app/community-list-page/community-list-page.routing.module.ts b/src/app/community-list-page/community-list-page.routing.module.ts new file mode 100644 index 0000000000..b3b254800b --- /dev/null +++ b/src/app/community-list-page/community-list-page.routing.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { RouterModule } from '@angular/router'; +import {CdkTreeModule} from '@angular/cdk/tree'; + +import {CommunityListPageComponent} from './community-list-page.component'; +import {CommunityListService} from './CommunityListService'; + +@NgModule({ + imports: [ + RouterModule.forChild([ + { path: '', component: CommunityListPageComponent, pathMatch: 'full', data: { title: 'communityList.tabTitle' } } + ]), + CdkTreeModule, + ], + providers: [CommunityListService] +}) +export class CommunityListPageRoutingModule { } diff --git a/src/app/community-list-page/community-list/community-list.component.html b/src/app/community-list-page/community-list/community-list.component.html new file mode 100644 index 0000000000..1bbca95b74 --- /dev/null +++ b/src/app/community-list-page/community-list/community-list.component.html @@ -0,0 +1,25 @@ + + + + + +
{{node.name}}
+
+ + +
+ +
{{node.name}}
+
+
+
diff --git a/src/app/community-list-page/community-list/community-list.component.spec.ts b/src/app/community-list-page/community-list/community-list.component.spec.ts new file mode 100644 index 0000000000..dadcc11251 --- /dev/null +++ b/src/app/community-list-page/community-list/community-list.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { CommunityListComponent } from './community-list.component'; + +describe('CommunityListComponent', () => { + let component: CommunityListComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ CommunityListComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(CommunityListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/community-list-page/community-list/community-list.component.ts b/src/app/community-list-page/community-list/community-list.component.ts new file mode 100644 index 0000000000..009af5f0fb --- /dev/null +++ b/src/app/community-list-page/community-list/community-list.component.ts @@ -0,0 +1,37 @@ +import {Component, OnInit} from '@angular/core'; +import {CommunityListService} from '../CommunityListService'; +import {CommunityFlatNode, CommunityListDataSource} from '../CommunityListDataSource'; +import {FlatTreeControl} from '@angular/cdk/tree'; + +@Component({ + selector: 'ds-community-list', + templateUrl: './community-list.component.html', + styleUrls: ['./community-list.component.css'] +}) +export class CommunityListComponent implements OnInit { + + treeControl = new FlatTreeControl( + (node) => node.level, (node) => node.expandable + ); + + dataSource: CommunityListDataSource; + + constructor(private communityListService: CommunityListService) { } + + ngOnInit() { + this.dataSource = new CommunityListDataSource(this.communityListService); + this.dataSource.loadCommunities(); + } + + hasChild = (_: number, node: CommunityFlatNode) => node.expandable; + + shouldRender(node: CommunityFlatNode) { + const parent = node.parent; + return !parent || parent.isExpanded; + } + + numberReturn(length){ + return new Array(length); + } + +} diff --git a/yarn.lock b/yarn.lock index 69f4a072ae..d5c8d144de 100644 --- a/yarn.lock +++ b/yarn.lock @@ -35,6 +35,13 @@ dependencies: tslib "^1.9.0" +"@angular/cdk@^6.4.7": + version "6.4.7" + resolved "https://registry.yarnpkg.com/@angular/cdk/-/cdk-6.4.7.tgz#1549b304dd412e82bd854cc55a7d5c6772ee0411" + integrity sha512-18x0U66fLD5kGQWZ9n3nb75xQouXlWs7kUDaTd8HTrHpT1s2QIAqlLd1KxfrYiVhsEC2jPQaoiae7VnBlcvkBg== + dependencies: + tslib "^1.7.1" + "@angular/cli@^6.1.5": version "6.1.5" resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-6.1.5.tgz#312c062631285ff06fd07ecde8afe22cdef5a0e1" @@ -10833,6 +10840,11 @@ tsickle@^0.32.1: source-map "^0.6.0" source-map-support "^0.5.0" +tslib@^1.7.1: + version "1.10.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.10.0.tgz#c3c19f95973fb0a62973fb09d90d961ee43e5c8a" + integrity sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ== + tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: version "1.9.3" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"