Skip to content

Commit

Permalink
Merge 0b65bda into 49e7b4b
Browse files Browse the repository at this point in the history
  • Loading branch information
atarix83 committed Apr 6, 2020
2 parents 49e7b4b + 0b65bda commit 4a9e764
Show file tree
Hide file tree
Showing 52 changed files with 2,542 additions and 289 deletions.
91 changes: 91 additions & 0 deletions resources/i18n/en.json5
Expand Up @@ -783,6 +783,11 @@



"item.edit.authorizations.heading": "With this editor you can view and alter the policies of an item, plus alter policies of individual item components: bundles and bitstreams. Briefly, an item is a container of bundles, and bundles are containers of bitstreams. Containers usually have ADD/REMOVE/READ/WRITE policies, while bitstreams only have READ/WRITE policies.",

"item.edit.authorizations.title": "Edit item's Policies",



"item.bitstreams.upload.bundle": "Bundle",

Expand Down Expand Up @@ -1791,6 +1796,92 @@



"resource-policies.add.for.": "Add a new policy",

"resource-policies.add.for.bitstream": "Add a new Bitstream policy",

"resource-policies.add.for.bundle": "Add a new Bundle policy",

"resource-policies.add.for.item": "Add a new Item policy",

"resource-policies.create.page.heading": "Create new resource policy for ",

"resource-policies.create.page.failure.content": "An error occurred while creating the resource policy.",

"resource-policies.create.page.success.content": "Operation successful",

"resource-policies.create.page.title": "Create new resource policy",

"resource-policies.delete.btn": "Delete selected resource policies",

"resource-policies.delete.failure.content": "An error occurred while deleting selected resource policies.",

"resource-policies.delete.success.content": "Operation successful",

"resource-policies.edit.page.heading": "Edit resource policy ",

"resource-policies.edit.page.failure.content": "An error occurred while editing the resource policy.",

"resource-policies.edit.page.success.content": "Operation successful",

"resource-policies.edit.page.title": "Edit resource policy",

"resource-policies.form.action-type.label": "Select the action type",

"resource-policies.form.action-type.required": "You must select the resource policy action.",

"resource-policies.form.eperson-group-list.label": "Select the eperson or group that will be grant of the permission",

"resource-policies.form.eperson-group-list.select.btn": "Select",

"resource-policies.form.eperson-group-list.tab.eperson": "Search for a ePerson",

"resource-policies.form.eperson-group-list.tab.group": "Search for a group",

"resource-policies.form.eperson-group-list.table.headers.action": "Action",

"resource-policies.form.eperson-group-list.table.headers.id": "ID",

"resource-policies.form.eperson-group-list.table.headers.name": "Name",

"resource-policies.form.date.end.label": "End Date",

"resource-policies.form.date.start.label": "Start Date",

"resource-policies.form.description.label": "Description",

"resource-policies.form.name.label": "Name",

"resource-policies.form.policy-type.label": "Select the policy type",

"resource-policies.form.policy-type.required": "You must select the resource policy type.",

"resource-policies.table.headers.action": "Action",

"resource-policies.table.headers.date.end": "End Date",

"resource-policies.table.headers.date.start": "Start Date",

"resource-policies.table.headers.edit": "Edit",

"resource-policies.table.headers.eperson": "EPerson",

"resource-policies.table.headers.group": "Group",

"resource-policies.table.headers.id": "ID",

"resource-policies.table.headers.name": "Name",

"resource-policies.table.headers.policyType": "type",

"resource-policies.table.headers.title.for.bitstream": "Policies for Bitstream",

"resource-policies.table.headers.title.for.bundle": "Policies for Bundle",

"resource-policies.table.headers.title.for.item": "Policies for Item",



"search.description": "",

"search.switch-configuration.title": "Show",
Expand Down
6 changes: 6 additions & 0 deletions src/app/+item-page/edit-item-page/edit-item-page.module.ts
Expand Up @@ -30,6 +30,9 @@ import { ItemEditBitstreamDragHandleComponent } from './item-bitstreams/item-edi
import { PaginatedDragAndDropBitstreamListComponent } from './item-bitstreams/item-edit-bitstream-bundle/paginated-drag-and-drop-bitstream-list/paginated-drag-and-drop-bitstream-list.component';
import { VirtualMetadataComponent } from './virtual-metadata/virtual-metadata.component';
import { ItemVersionHistoryComponent } from './item-version-history/item-version-history.component';
import { ItemAuthorizationsComponent } from './item-authorizations/item-authorizations.component';
import { ResourcePolicyEditComponent } from '../../shared/resource-policies/edit/resource-policy-edit.component';
import { ResourcePolicyCreateComponent } from '../../shared/resource-policies/create/resource-policy-create.component';

/**
* Module that contains all components related to the Edit Item page administrator functionality
Expand Down Expand Up @@ -69,6 +72,9 @@ import { ItemVersionHistoryComponent } from './item-version-history/item-version
ItemMoveComponent,
ItemEditBitstreamDragHandleComponent,
VirtualMetadataComponent,
ItemAuthorizationsComponent,
ResourcePolicyEditComponent,
ResourcePolicyCreateComponent,
],
providers: [
BundleDataService
Expand Down
Expand Up @@ -14,13 +14,19 @@ import { ItemMoveComponent } from './item-move/item-move.component';
import { ItemRelationshipsComponent } from './item-relationships/item-relationships.component';
import { I18nBreadcrumbResolver } from '../../core/breadcrumbs/i18n-breadcrumb.resolver';
import { ItemVersionHistoryComponent } from './item-version-history/item-version-history.component';
import { ItemAuthorizationsComponent } from './item-authorizations/item-authorizations.component';
import { ResourcePolicyTargetResolver } from '../../shared/resource-policies/resolvers/resource-policy-target.resolver';
import { ResourcePolicyResolver } from '../../shared/resource-policies/resolvers/resource-policy.resolver';
import { ResourcePolicyCreateComponent } from '../../shared/resource-policies/create/resource-policy-create.component';
import { ResourcePolicyEditComponent } from '../../shared/resource-policies/edit/resource-policy-edit.component';

export const ITEM_EDIT_WITHDRAW_PATH = 'withdraw';
export const ITEM_EDIT_REINSTATE_PATH = 'reinstate';
export const ITEM_EDIT_PRIVATE_PATH = 'private';
export const ITEM_EDIT_PUBLIC_PATH = 'public';
export const ITEM_EDIT_DELETE_PATH = 'delete';
export const ITEM_EDIT_MOVE_PATH = 'move';
export const ITEM_EDIT_AUTHORIZATIONS_PATH = 'authorizations';

/**
* Routing module that handles the routing for the Edit Item page administrator functionality
Expand Down Expand Up @@ -111,12 +117,41 @@ export const ITEM_EDIT_MOVE_PATH = 'move';
path: ITEM_EDIT_MOVE_PATH,
component: ItemMoveComponent,
data: { title: 'item.edit.move.title' },
},
{
path: ITEM_EDIT_AUTHORIZATIONS_PATH,
children: [
{
path: 'create',
resolve: {
resourcePolicyTarget: ResourcePolicyTargetResolver
},
component: ResourcePolicyCreateComponent,
data: { title: 'resource-policies.create.page.title' }
},
{
path: 'edit',
resolve: {
resourcePolicy: ResourcePolicyResolver
},
component: ResourcePolicyEditComponent,
data: { title: 'resource-policies.edit.page.title' }
},
{
path: '',
component: ItemAuthorizationsComponent,
data: { title: 'item.edit.authorizations.title' }
}
]
}
]
}
])
],
providers: []
providers: [
ResourcePolicyResolver,
ResourcePolicyTargetResolver
]
})
export class EditItemPageRoutingModule {

Expand Down
@@ -0,0 +1,13 @@
<div class="container">
<ds-alert [type]="'alert-info'" [content]="'item.edit.authorizations.heading'"></ds-alert>
<ds-resource-policies [resourceType]="'item'" [resourceUUID]="(getItemUUID() | async)"></ds-resource-policies>
<ng-container *ngFor="let bundle of (getItemBundles() | async); trackById">
<ds-resource-policies [resourceType]="'bundle'"
[resourceUUID]="bundle.id"></ds-resource-policies>
<ng-container *ngFor="let bitstream of (bundleBitstreamsMap.get(bundle.id) | async)?.page; trackById">
<ds-resource-policies [resourceType]="'bitstream'"
[resourceUUID]="bitstream.id"></ds-resource-policies>
</ng-container>
</ng-container>
</div>

@@ -0,0 +1,9 @@
import { ComponentFixture } from '@angular/core/testing';

import { ItemAuthorizationsComponent } from './item-authorizations.component';

describe('ItemAuthorizationsComponent', () => {
// let comp: ItemAuthorizationsComponent;
// let fixture: ComponentFixture<ItemAuthorizationsComponent>;

});
@@ -0,0 +1,148 @@
import { Component, OnDestroy, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';

import { BehaviorSubject, Observable, of as observableOf, Subscription } from 'rxjs';
import { catchError, filter, first, flatMap, map, take } from 'rxjs/operators';

import { ResourcePolicyService } from '../../../core/resource-policy/resource-policy.service';
import { PaginatedList } from '../../../core/data/paginated-list';
import {
getFirstSucceededRemoteDataPayload,
getFirstSucceededRemoteDataWithNotEmptyPayload
} from '../../../core/shared/operators';
import { Item } from '../../../core/shared/item.model';
import { followLink } from '../../../shared/utils/follow-link-config.model';
import { LinkService } from '../../../core/cache/builders/link.service';
import { Bundle } from '../../../core/shared/bundle.model';
import { hasValue, isNotEmpty } from '../../../shared/empty.util';
import { Bitstream } from '../../../core/shared/bitstream.model';
import { FindListOptions } from '../../../core/data/request.models';

/**
* Interface for a bundle's bitstream map entry
*/
interface BundleBitstreamsMapEntry {
id: string;
bitstreams: Observable<PaginatedList<Bitstream>>
}

@Component({
selector: 'ds-item-authorizations',
templateUrl: './item-authorizations.component.html'
})
/**
* Component that handles the item Authorizations
*/
export class ItemAuthorizationsComponent implements OnInit, OnDestroy {

public bundleBitstreamsMap: Map<string, Observable<PaginatedList<Bitstream>>> = new Map<string, Observable<PaginatedList<Bitstream>>>();

/**
* The list of bundle for the item
* @type {Observable<PaginatedList<Bundle>>}
*/
private bundles$: BehaviorSubject<Bundle[]> = new BehaviorSubject<Bundle[]>([]);

/**
* The target editing item
* @type {Observable<Item>}
*/
private item$: Observable<Item>;

/**
* Array to track all subscriptions and unsubscribe them onDestroy
* @type {Array}
*/
private subs: Subscription[] = [];

/**
* Initialize instance variables
*
* @param {LinkService} linkService
* @param {ResourcePolicyService} resourcePolicyService
* @param {ActivatedRoute} route
*/
constructor(
private linkService: LinkService,
private resourcePolicyService: ResourcePolicyService,
private route: ActivatedRoute
) {
}

/**
* Initialize the component, setting up the bundle and bitstream within the item
*/
ngOnInit(): void {
this.item$ = this.route.data.pipe(
map((data) => data.item),
getFirstSucceededRemoteDataWithNotEmptyPayload(),
map((item: Item) => this.linkService.resolveLink(
item,
followLink('bundles', new FindListOptions(), true, followLink('bitstreams'))
))
) as Observable<Item>;

const bundles$: Observable<PaginatedList<Bundle>> = this.item$.pipe(
filter((item: Item) => isNotEmpty(item.bundles)),
flatMap((item: Item) => item.bundles),
getFirstSucceededRemoteDataWithNotEmptyPayload(),
catchError(() => observableOf(new PaginatedList(null, [])))
);

this.subs.push(
bundles$.pipe(
take(1),
map((list: PaginatedList<Bundle>) => list.page)
).subscribe((bundles: Bundle[]) => {
this.bundles$.next(bundles);
}),
bundles$.pipe(
take(1),
flatMap((list: PaginatedList<Bundle>) => list.page),
map((bundle: Bundle) => ({ id: bundle.id, bitstreams: this.getBundleBitstreams(bundle) }))
).subscribe((entry: BundleBitstreamsMapEntry) => {
this.bundleBitstreamsMap.set(entry.id, entry.bitstreams)
})
)
}

/**
* Return the item's UUID
*/
getItemUUID(): Observable<string> {
return this.item$.pipe(
map((item: Item) => item.id),
first((UUID: string) => isNotEmpty(UUID))
)
}

/**
* Return all item's bundles
*
* @return an observable that emits all item's bundles
*/
getItemBundles(): Observable<Bundle[]> {
return this.bundles$.asObservable();
}

/**
* Return all bundle's bitstreams
*
* @return an observable that emits all item's bundles
*/
private getBundleBitstreams(bundle: Bundle): Observable<PaginatedList<Bitstream>> {
return bundle.bitstreams.pipe(
getFirstSucceededRemoteDataPayload(),
catchError(() => observableOf(new PaginatedList(null, [])))
)
}

/**
* Unsubscribe from all subscriptions
*/
ngOnDestroy(): void {
this.subs
.filter((subscription) => hasValue(subscription))
.forEach((subscription) => subscription.unsubscribe())
}
}
Expand Up @@ -68,6 +68,7 @@ export class ItemStatusComponent implements OnInit {
The value is supposed to be a href for the button
*/
this.operations = [];
this.operations.push(new ItemOperation('authorizations', this.getCurrentUrl(item) + '/authorizations'));
this.operations.push(new ItemOperation('mappedCollections', this.getCurrentUrl(item) + '/mapper'));
if (item.isWithdrawn) {
this.operations.push(new ItemOperation('reinstate', this.getCurrentUrl(item) + '/reinstate'));
Expand Down
3 changes: 2 additions & 1 deletion src/app/+item-page/item-page.resolver.ts
Expand Up @@ -7,6 +7,7 @@ import { Item } from '../core/shared/item.model';
import { hasValue } from '../shared/empty.util';
import { find } from 'rxjs/operators';
import { followLink } from '../shared/utils/follow-link-config.model';
import { FindListOptions } from '../core/data/request.models';

/**
* This class represents a resolver that requests a specific item before the route is activated
Expand All @@ -26,7 +27,7 @@ export class ItemPageResolver implements Resolve<RemoteData<Item>> {
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<RemoteData<Item>> {
return this.itemService.findById(route.params.id,
followLink('owningCollection'),
followLink('bundles'),
followLink('bundles', new FindListOptions(), true, followLink('bitstreams')),
followLink('relationships'),
followLink('version', undefined, true, followLink('versionhistory')),
).pipe(
Expand Down
3 changes: 2 additions & 1 deletion src/app/core/breadcrumbs/dso-name.service.ts
Expand Up @@ -28,7 +28,8 @@ export class DSONameService {
return dso.firstMetadataValue('organization.legalName');
},
Default: (dso: DSpaceObject): string => {
return dso.firstMetadataValue('dc.title');
// If object doesn't have dc.title metadata use name property
return dso.firstMetadataValue('dc.title') || dso.name;
}
};

Expand Down

0 comments on commit 4a9e764

Please sign in to comment.