mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 18:14:17 +00:00
65528: ComCol Tree with full FlatList that gets generated at page-load
This commit is contained in:
@@ -75,6 +75,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "^6.1.4",
|
"@angular/animations": "^6.1.4",
|
||||||
|
"@angular/cdk": "^6.4.7",
|
||||||
"@angular/cli": "^6.1.5",
|
"@angular/cli": "^6.1.5",
|
||||||
"@angular/common": "^6.1.4",
|
"@angular/common": "^6.1.4",
|
||||||
"@angular/core": "^6.1.4",
|
"@angular/core": "^6.1.4",
|
||||||
|
@@ -340,6 +340,12 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
"communityList.tabTitle": "DSpace - Community List",
|
||||||
|
|
||||||
|
"communityList.title": "List of Communities",
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
"community.create.head": "Create a Community",
|
"community.create.head": "Create a Community",
|
||||||
|
|
||||||
"community.create.sub-head": "Create a Sub-Community for Community {{ parent }}",
|
"community.create.sub-head": "Create a Sub-Community for Community {{ parent }}",
|
||||||
|
@@ -27,6 +27,7 @@ export function getAdminModulePath() {
|
|||||||
RouterModule.forRoot([
|
RouterModule.forRoot([
|
||||||
{ path: '', redirectTo: '/home', pathMatch: 'full' },
|
{ path: '', redirectTo: '/home', pathMatch: 'full' },
|
||||||
{ path: 'home', loadChildren: './+home-page/home-page.module#HomePageModule' },
|
{ 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: 'id', loadChildren: './+lookup-by-id/lookup-by-id.module#LookupIdModule' },
|
||||||
{ path: 'handle', 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' },
|
{ path: COMMUNITY_MODULE_PATH, loadChildren: './+community-page/community-page.module#CommunityPageModule' },
|
||||||
|
74
src/app/community-list-page/CommunityListDataSource.ts
Normal file
74
src/app/community-list-page/CommunityListDataSource.ts
Normal file
@@ -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<CommunityFlatNode> {
|
||||||
|
|
||||||
|
private communityListSubject = new BehaviorSubject<CommunityFlatNode[]>([]);
|
||||||
|
private loadingSubject = new BehaviorSubject<boolean>(false);
|
||||||
|
|
||||||
|
public loading$ = this.loadingSubject.asObservable();
|
||||||
|
|
||||||
|
constructor(private communityListService: CommunityListService) {}
|
||||||
|
|
||||||
|
connect(collectionViewer: CollectionViewer): Observable<CommunityFlatNode[]> {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
24
src/app/community-list-page/CommunityListService.ts
Normal file
24
src/app/community-list-page/CommunityListService.ts
Normal file
@@ -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<CommunityForList[]> {
|
||||||
|
return of(this.comList);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -0,0 +1,2 @@
|
|||||||
|
<h2>{{ 'communityList.title' | translate }}</h2>
|
||||||
|
<ds-community-list></ds-community-list>
|
@@ -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<CommunityListPageComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ CommunityListPageComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(CommunityListPageComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
15
src/app/community-list-page/community-list-page.component.ts
Normal file
15
src/app/community-list-page/community-list-page.component.ts
Normal file
@@ -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() {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
23
src/app/community-list-page/community-list-page.module.ts
Normal file
23
src/app/community-list-page/community-list-page.module.ts
Normal file
@@ -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 {
|
||||||
|
|
||||||
|
}
|
@@ -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 { }
|
@@ -0,0 +1,25 @@
|
|||||||
|
<cdk-tree [dataSource]="dataSource" [treeControl]="treeControl">
|
||||||
|
<!-- This is the tree node template for leaf nodes -->
|
||||||
|
<cdk-tree-node *cdkTreeNodeDef="let node" cdkTreeNodePadding
|
||||||
|
[style.display]="shouldRender(node) ? 'flex' : 'none'"
|
||||||
|
class="example-tree-node">
|
||||||
|
<!-- use a disabled button to provide padding for tree leaf -->
|
||||||
|
<button type="button" class="btn btn-default" [style.visibility]="'hidden'"></button>
|
||||||
|
<h5 class="align-middle">{{node.name}}</h5>
|
||||||
|
</cdk-tree-node>
|
||||||
|
<!-- This is the tree node template for expandable nodes -->
|
||||||
|
<cdk-tree-node *cdkTreeNodeDef="let node; when: hasChild" cdkTreeNodePadding
|
||||||
|
[style.display]="shouldRender(node) ? 'flex' : 'none'"
|
||||||
|
class="example-tree-node">
|
||||||
|
<div class="btn-group">
|
||||||
|
<button type="button" class="btn btn-default" cdkTreeNodeToggle
|
||||||
|
[attr.aria-label]="'toggle ' + node.name"
|
||||||
|
(click)="node.isExpanded = !node.isExpanded"
|
||||||
|
[style.visibility]="node.expandable ? 'visible' : 'hidden'">
|
||||||
|
<span class="{{treeControl.isExpanded(node) ? 'fa fa-chevron-down' : 'fa fa-chevron-right'}}" aria-hidden="true">
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
<h5 class="align-middle pt-2">{{node.name}}</h5>
|
||||||
|
</div>
|
||||||
|
</cdk-tree-node>
|
||||||
|
</cdk-tree>
|
@@ -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<CommunityListComponent>;
|
||||||
|
|
||||||
|
beforeEach(async(() => {
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
declarations: [ CommunityListComponent ]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(CommunityListComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
@@ -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<CommunityFlatNode>(
|
||||||
|
(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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
12
yarn.lock
12
yarn.lock
@@ -35,6 +35,13 @@
|
|||||||
dependencies:
|
dependencies:
|
||||||
tslib "^1.9.0"
|
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":
|
"@angular/cli@^6.1.5":
|
||||||
version "6.1.5"
|
version "6.1.5"
|
||||||
resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-6.1.5.tgz#312c062631285ff06fd07ecde8afe22cdef5a0e1"
|
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 "^0.6.0"
|
||||||
source-map-support "^0.5.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:
|
tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0:
|
||||||
version "1.9.3"
|
version "1.9.3"
|
||||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
|
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286"
|
||||||
|
Reference in New Issue
Block a user