forked from hazza/dspace-angular
Merge branch 'main' into iiif-mirador
This commit is contained in:
6
.vscode/settings.json
vendored
6
.vscode/settings.json
vendored
@@ -1,3 +1,7 @@
|
|||||||
{
|
{
|
||||||
"typescript.check.workspaceVersion": false
|
"typescript.check.workspaceVersion": false,
|
||||||
|
"i18n-ally.localesPaths": [
|
||||||
|
"src/assets/i18n",
|
||||||
|
"src/app/core/locale"
|
||||||
|
]
|
||||||
}
|
}
|
@@ -14,22 +14,22 @@ export class ProtractorPage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getCurrentQuery(): promise.Promise<string> {
|
getCurrentQuery(): promise.Promise<string> {
|
||||||
return element(by.css('#search-navbar-container form input')).getAttribute('value');
|
return element(by.css('.navbar-container #search-navbar-container form input')).getAttribute('value');
|
||||||
}
|
}
|
||||||
|
|
||||||
expandAndFocusSearchBox() {
|
expandAndFocusSearchBox() {
|
||||||
element(by.css('#search-navbar-container form a')).click();
|
element(by.css('.navbar-container #search-navbar-container form a')).click();
|
||||||
}
|
}
|
||||||
|
|
||||||
setCurrentQuery(query: string) {
|
setCurrentQuery(query: string) {
|
||||||
element(by.css('#search-navbar-container form input[name="query"]')).sendKeys(query);
|
element(by.css('.navbar-container #search-navbar-container form input[name="query"]')).sendKeys(query);
|
||||||
}
|
}
|
||||||
|
|
||||||
submitNavbarSearchForm() {
|
submitNavbarSearchForm() {
|
||||||
element(by.css('#search-navbar-container form .submit-icon')).click();
|
element(by.css('.navbar-container #search-navbar-container form .submit-icon')).click();
|
||||||
}
|
}
|
||||||
|
|
||||||
submitByPressingEnter() {
|
submitByPressingEnter() {
|
||||||
element(by.css('#search-navbar-container form input[name="query"]')).sendKeys(protractor.Key.ENTER);
|
element(by.css('.navbar-container #search-navbar-container form input[name="query"]')).sendKeys(protractor.Key.ENTER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -129,7 +129,7 @@
|
|||||||
"rxjs": "^6.6.3",
|
"rxjs": "^6.6.3",
|
||||||
"rxjs-spy": "^7.5.3",
|
"rxjs-spy": "^7.5.3",
|
||||||
"sass-resources-loader": "^2.1.1",
|
"sass-resources-loader": "^2.1.1",
|
||||||
"sortablejs": "1.10.1",
|
"sortablejs": "1.13.0",
|
||||||
"tslib": "^2.0.0",
|
"tslib": "^2.0.0",
|
||||||
"webfontloader": "1.6.28",
|
"webfontloader": "1.6.28",
|
||||||
"zone.js": "^0.10.3",
|
"zone.js": "^0.10.3",
|
||||||
|
@@ -61,7 +61,7 @@ export class ItemAdminSearchResultGridElementComponent extends SearchResultGridE
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch the component depending on the item's relationship type, view mode and context
|
* Fetch the component depending on the item's entity type, view mode and context
|
||||||
* @returns {GenericConstructor<Component>}
|
* @returns {GenericConstructor<Component>}
|
||||||
*/
|
*/
|
||||||
private getComponent(): GenericConstructor<Component> {
|
private getComponent(): GenericConstructor<Component> {
|
||||||
|
@@ -1,27 +1,28 @@
|
|||||||
<a [ngClass]="{'btn-sm': small}" class="btn btn-light my-1 edit-link" [routerLink]="[getEditRoute()]" [title]="'admin.search.item.edit' | translate">
|
<a [ngClass]="{'btn-sm': small}" class="btn btn-secondary my-1 move-link" [routerLink]="[getMoveRoute()]" [title]="'admin.search.item.move' | translate">
|
||||||
<i class="fa fa-edit"></i><span *ngIf="!small" class="d-none d-sm-inline"> {{"admin.search.item.edit" | translate}}</span>
|
<i class="fa fa-arrow-circle-right"></i><span *ngIf="!small" class="d-none d-sm-inline"> {{"admin.search.item.move" | translate}}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a [ngClass]="{'btn-sm': small}" *ngIf="item && !item.isWithdrawn" class="btn btn-light my-1 withdraw-link" [routerLink]="[getWithdrawRoute()]" [title]="'admin.search.item.withdraw' | translate">
|
<a [ngClass]="{'btn-sm': small}" *ngIf="item && item.isDiscoverable" class="btn btn-secondary my-1 private-link" [routerLink]="[getPrivateRoute()]" [title]="'admin.search.item.make-private' | translate">
|
||||||
<i class="fa fa-ban"></i><span *ngIf="!small" class="d-none d-sm-inline"> {{"admin.search.item.withdraw" | translate}}</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a [ngClass]="{'btn-sm': small}" *ngIf="item && item.isWithdrawn" class="btn btn-light my-1 reinstate-link" [routerLink]="[getReinstateRoute()]" [title]="'admin.search.item.reinstate' | translate">
|
|
||||||
<i class="fa fa-undo"></i><span *ngIf="!small" class="d-none d-sm-inline"> {{"admin.search.item.reinstate" | translate}}</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
<a [ngClass]="{'btn-sm': small}" *ngIf="item && item.isDiscoverable" class="btn btn-light my-1 private-link" [routerLink]="[getPrivateRoute()]" [title]="'admin.search.item.make-private' | translate">
|
|
||||||
<i class="fa fa-eye-slash"></i><span *ngIf="!small" class="d-none d-sm-inline"> {{"admin.search.item.make-private" | translate}}</span>
|
<i class="fa fa-eye-slash"></i><span *ngIf="!small" class="d-none d-sm-inline"> {{"admin.search.item.make-private" | translate}}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a [ngClass]="{'btn-sm': small}" *ngIf="item && !item.isDiscoverable" class="btn btn-light my-1 public-link" [routerLink]="[getPublicRoute()]" [title]="'admin.search.item.make-public' | translate">
|
<a [ngClass]="{'btn-sm': small}" *ngIf="item && !item.isDiscoverable" class="btn btn-secondary my-1 public-link" [routerLink]="[getPublicRoute()]" [title]="'admin.search.item.make-public' | translate">
|
||||||
<i class="fa fa-eye"></i><span *ngIf="!small" class="d-none d-sm-inline"> {{"admin.search.item.make-public" | translate}}</span>
|
<i class="fa fa-eye"></i><span *ngIf="!small" class="d-none d-sm-inline"> {{"admin.search.item.make-public" | translate}}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a [ngClass]="{'btn-sm': small}" class="btn btn-light my-1 delete-link" [routerLink]="[getDeleteRoute()]" [title]="'admin.search.item.delete' | translate">
|
<a [ngClass]="{'btn-sm': small}" class="btn btn-secondary my-1 edit-link" [routerLink]="[getEditRoute()]" [title]="'admin.search.item.edit' | translate">
|
||||||
|
<i class="fa fa-edit"></i><span *ngIf="!small" class="d-none d-sm-inline"> {{"admin.search.item.edit" | translate}}</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a [ngClass]="{'btn-sm': small}" *ngIf="item && !item.isWithdrawn" class="btn btn-warning t my-1 withdraw-link" [routerLink]="[getWithdrawRoute()]" [title]="'admin.search.item.withdraw' | translate">
|
||||||
|
<i class="fa fa-ban"></i><span *ngIf="!small" class="d-none d-sm-inline"> {{"admin.search.item.withdraw" | translate}}</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a [ngClass]="{'btn-sm': small}" *ngIf="item && item.isWithdrawn" class="btn btn-warning my-1 reinstate-link" [routerLink]="[getReinstateRoute()]" [title]="'admin.search.item.reinstate' | translate">
|
||||||
|
<i class="fa fa-undo"></i><span *ngIf="!small" class="d-none d-sm-inline"> {{"admin.search.item.reinstate" | translate}}</span>
|
||||||
|
</a>
|
||||||
|
|
||||||
|
<a [ngClass]="{'btn-sm': small}" class="btn btn-danger my-1 delete-link" [routerLink]="[getDeleteRoute()]" [title]="'admin.search.item.delete' | translate">
|
||||||
<i class="fa fa-trash"></i><span *ngIf="!small" class="d-none d-sm-inline"> {{"admin.search.item.delete" | translate}}</span>
|
<i class="fa fa-trash"></i><span *ngIf="!small" class="d-none d-sm-inline"> {{"admin.search.item.delete" | translate}}</span>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<a [ngClass]="{'btn-sm': small}" class="btn btn-light my-1 move-link" [routerLink]="[getMoveRoute()]" [title]="'admin.search.item.move' | translate">
|
|
||||||
<i class="fa fa-arrow-circle-right"></i><span *ngIf="!small" class="d-none d-sm-inline"> {{"admin.search.item.move" | translate}}</span>
|
|
||||||
</a>
|
|
||||||
|
@@ -1,11 +1,11 @@
|
|||||||
<li class="sidebar-section">
|
<li class="sidebar-section">
|
||||||
<a class="nav-item nav-link shortcut-icon" [routerLink]="itemModel.link">
|
<a class="nav-item nav-link shortcut-icon" attr.aria-labelledby="sidebarName-{{section.id}}" [title]="('menu.section.icon.' + section.id) | translate" [routerLink]="itemModel.link">
|
||||||
<i class="fas fa-{{section.icon}} fa-fw" [title]="('menu.section.icon.' + section.id) | translate"></i>
|
<i class="fas fa-{{section.icon}} fa-fw"></i>
|
||||||
</a>
|
</a>
|
||||||
<div class="sidebar-collapsible">
|
<div class="sidebar-collapsible">
|
||||||
<span class="section-header-text">
|
<span id="sidebarName-{{section.id}}" class="section-header-text">
|
||||||
<ng-container
|
<ng-container
|
||||||
*ngComponentOutlet="(sectionMap$ | async).get(section.id).component; injector: (sectionMap$ | async).get(section.id).injector;"></ng-container>
|
*ngComponentOutlet="(sectionMap$ | async).get(section.id).component; injector: (sectionMap$ | async).get(section.id).injector;"></ng-container>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
@@ -1,11 +1,12 @@
|
|||||||
<nav @slideHorizontal class="navbar navbar-dark p-0"
|
<nav @slideHorizontal class="navbar navbar-dark p-0"
|
||||||
[ngClass]="{'active': sidebarOpen, 'inactive': sidebarClosed}"
|
[ngClass]="{'active': sidebarOpen, 'inactive': sidebarClosed}"
|
||||||
[@slideSidebar]="{
|
[@slideSidebar]="{
|
||||||
value: (!(sidebarExpanded | async) ? 'collapsed' : 'expanded'),
|
value: (!(sidebarExpanded | async) ? 'collapsed' : 'expanded'),
|
||||||
params: {sidebarWidth: (sidebarWidth | async)}
|
params: {sidebarWidth: (sidebarWidth | async)}
|
||||||
}" (@slideSidebar.done)="finishSlide($event)" (@slideSidebar.start)="startSlide($event)"
|
}" (@slideSidebar.done)="finishSlide($event)" (@slideSidebar.start)="startSlide($event)"
|
||||||
*ngIf="menuVisible | async" (mouseenter)="expandPreview($event)"
|
*ngIf="menuVisible | async" (mouseenter)="expandPreview($event)"
|
||||||
(mouseleave)="collapsePreview($event)">
|
(mouseleave)="collapsePreview($event)"
|
||||||
|
role="navigation" [attr.aria-label]="'menu.header.admin.description' |translate">
|
||||||
<div class="sidebar-top-level-items">
|
<div class="sidebar-top-level-items">
|
||||||
<ul class="navbar-nav">
|
<ul class="navbar-nav">
|
||||||
<li class="admin-menu-header sidebar-section">
|
<li class="admin-menu-header sidebar-section">
|
||||||
|
@@ -126,7 +126,7 @@ export class AdminSidebarComponent extends MenuComponent implements OnInit {
|
|||||||
type: MenuItemType.TEXT,
|
type: MenuItemType.TEXT,
|
||||||
text: 'menu.section.new'
|
text: 'menu.section.new'
|
||||||
} as TextMenuItemModel,
|
} as TextMenuItemModel,
|
||||||
icon: 'plus-circle',
|
icon: 'plus',
|
||||||
index: 0
|
index: 0
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -320,7 +320,7 @@ export class AdminSidebarComponent extends MenuComponent implements OnInit {
|
|||||||
type: MenuItemType.TEXT,
|
type: MenuItemType.TEXT,
|
||||||
text: 'menu.section.export'
|
text: 'menu.section.export'
|
||||||
} as TextMenuItemModel,
|
} as TextMenuItemModel,
|
||||||
icon: 'sign-out-alt',
|
icon: 'file-export',
|
||||||
index: 3,
|
index: 3,
|
||||||
shouldPersistOnRouteChange: true
|
shouldPersistOnRouteChange: true
|
||||||
},
|
},
|
||||||
@@ -403,7 +403,7 @@ export class AdminSidebarComponent extends MenuComponent implements OnInit {
|
|||||||
type: MenuItemType.TEXT,
|
type: MenuItemType.TEXT,
|
||||||
text: 'menu.section.import'
|
text: 'menu.section.import'
|
||||||
} as TextMenuItemModel,
|
} as TextMenuItemModel,
|
||||||
icon: 'sign-in-alt',
|
icon: 'file-import',
|
||||||
index: 2
|
index: 2
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@@ -3,14 +3,14 @@
|
|||||||
value: ((expanded | async) ? 'endBackground' : 'startBackground'),
|
value: ((expanded | async) ? 'endBackground' : 'startBackground'),
|
||||||
params: {endColor: (sidebarActiveBg | async)}}">
|
params: {endColor: (sidebarActiveBg | async)}}">
|
||||||
<div class="icon-wrapper">
|
<div class="icon-wrapper">
|
||||||
<a class="nav-item nav-link shortcut-icon" (click)="toggleSection($event)" href="#">
|
<a class="nav-item nav-link shortcut-icon" attr.aria.labelledby="sidebarName-{{section.id}}" [title]="('menu.section.icon.' + section.id) | translate" (click)="toggleSection($event)" href="#">
|
||||||
<i class="fas fa-{{section.icon}} fa-fw" [title]="('menu.section.icon.' + section.id) | translate"></i>
|
<i class="fas fa-{{section.icon}} fa-fw"></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="sidebar-collapsible">
|
<div class="sidebar-collapsible">
|
||||||
<a class="nav-item nav-link" href="#"
|
<a class="nav-item nav-link" href="#"
|
||||||
(click)="toggleSection($event)">
|
(click)="toggleSection($event)">
|
||||||
<span class="section-header-text">
|
<span id="sidebarName-{{section.id}}" class="section-header-text">
|
||||||
<ng-container
|
<ng-container
|
||||||
*ngComponentOutlet="(sectionMap$ | async).get(section.id).component; injector: (sectionMap$ | async).get(section.id).injector;"></ng-container>
|
*ngComponentOutlet="(sectionMap$ | async).get(section.id).component; injector: (sectionMap$ | async).get(section.id).injector;"></ng-container>
|
||||||
</span>
|
</span>
|
||||||
|
@@ -16,4 +16,8 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
li.sidebar-section.expanded {
|
||||||
|
background-color: var(--ds-admin-sidebar-active-bg) !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -96,7 +96,7 @@ export class WorkflowItemSearchResultAdminWorkflowGridElementComponent extends S
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch the component depending on the item's relationship type, view mode and context
|
* Fetch the component depending on the item's entity type, view mode and context
|
||||||
* @returns {GenericConstructor<Component>}
|
* @returns {GenericConstructor<Component>}
|
||||||
*/
|
*/
|
||||||
private getComponent(item: Item): GenericConstructor<Component> {
|
private getComponent(item: Item): GenericConstructor<Component> {
|
||||||
|
@@ -7,7 +7,6 @@ import {
|
|||||||
} from '@ng-dynamic-forms/core';
|
} from '@ng-dynamic-forms/core';
|
||||||
import { Collection } from '../../core/shared/collection.model';
|
import { Collection } from '../../core/shared/collection.model';
|
||||||
import { ComColFormComponent } from '../../shared/comcol-forms/comcol-form/comcol-form.component';
|
import { ComColFormComponent } from '../../shared/comcol-forms/comcol-form/comcol-form.component';
|
||||||
import { Location } from '@angular/common';
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { CommunityDataService } from '../../core/data/community-data.service';
|
import { CommunityDataService } from '../../core/data/community-data.service';
|
||||||
@@ -76,14 +75,13 @@ export class CollectionFormComponent extends ComColFormComponent<Collection> {
|
|||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
public constructor(protected location: Location,
|
public constructor(protected formService: DynamicFormService,
|
||||||
protected formService: DynamicFormService,
|
|
||||||
protected translate: TranslateService,
|
protected translate: TranslateService,
|
||||||
protected notificationsService: NotificationsService,
|
protected notificationsService: NotificationsService,
|
||||||
protected authService: AuthService,
|
protected authService: AuthService,
|
||||||
protected dsoService: CommunityDataService,
|
protected dsoService: CommunityDataService,
|
||||||
protected requestService: RequestService,
|
protected requestService: RequestService,
|
||||||
protected objectCache: ObjectCacheService) {
|
protected objectCache: ObjectCacheService) {
|
||||||
super(location, formService, translate, notificationsService, authService, requestService, objectCache);
|
super(formService, translate, notificationsService, authService, requestService, objectCache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -31,6 +31,7 @@
|
|||||||
[scope]="(searchOptions$ | async)?.scope"
|
[scope]="(searchOptions$ | async)?.scope"
|
||||||
[currentUrl]="'./'"
|
[currentUrl]="'./'"
|
||||||
[inPlaceSearch]="true"
|
[inPlaceSearch]="true"
|
||||||
|
[searchPlaceholder]="'collection.edit.item-mapper.search-form.placeholder' | translate"
|
||||||
(submitSearch)="performedSearch = true">
|
(submitSearch)="performedSearch = true">
|
||||||
</ds-search-form>
|
</ds-search-form>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -4,5 +4,7 @@
|
|||||||
<h2 id="sub-header" class="border-bottom pb-2">{{'collection.create.sub-head' | translate:{ parent: (parentRD$| async)?.payload.name } }}</h2>
|
<h2 id="sub-header" class="border-bottom pb-2">{{'collection.create.sub-head' | translate:{ parent: (parentRD$| async)?.payload.name } }}</h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ds-collection-form (submitForm)="onSubmit($event)" (finish)="navigateToNewPage()"></ds-collection-form>
|
<ds-collection-form (submitForm)="onSubmit($event)"
|
||||||
|
(back)="navigateToHome()"
|
||||||
|
(finish)="navigateToNewPage()"></ds-collection-form>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -2,15 +2,18 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<ng-container *ngVar="(dsoRD$ | async)?.payload as dso">
|
<ng-container *ngVar="(dsoRD$ | async)?.payload as dso">
|
||||||
<div class="col-12 pb-4">
|
<div class="col-12 pb-4">
|
||||||
<h2 id="header" class="border-bottom pb-2">{{ 'community.delete.head' | translate
|
<h2 id="header" class="border-bottom pb-2">{{ 'community.delete.head' | translate}}</h2>
|
||||||
}}</h2>
|
|
||||||
<p class="pb-2">{{ 'community.delete.text' | translate:{ dso: dso.name } }}</p>
|
<p class="pb-2">{{ 'community.delete.text' | translate:{ dso: dso.name } }}</p>
|
||||||
<button class="btn btn-primary mr-2" (click)="onConfirm(dso)">
|
<div class="form-group row">
|
||||||
{{'community.delete.confirm' |
|
<div class="col text-right">
|
||||||
translate}}
|
<button class="btn btn-outline-secondary" (click)="onCancel(dso)">
|
||||||
</button>
|
<i class="fas fa-times"></i> {{'community.delete.cancel' | translate}}
|
||||||
<button class="btn btn-primary" (click)="onCancel(dso)">{{'community.delete.cancel' | translate}}
|
</button>
|
||||||
</button>
|
<button class="btn btn-danger mr-2" (click)="onConfirm(dso)">
|
||||||
|
<i class="fas fa-trash"></i> {{'community.delete.confirm' | translate}}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
|
@@ -16,9 +16,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ds-collection-form (submitForm)="onSubmit($event)"
|
<ds-collection-form [dso]="(dsoRD$ | async)?.payload"
|
||||||
[dso]="(dsoRD$ | async)?.payload"
|
(submitForm)="onSubmit($event)"
|
||||||
|
(back)="navigateToHomePage()"
|
||||||
(finish)="navigateToHomePage()"></ds-collection-form>
|
(finish)="navigateToHomePage()"></ds-collection-form>
|
||||||
<a class="btn btn-danger"
|
|
||||||
[routerLink]="'/collections/' + (dsoRD$ | async)?.payload.uuid + '/delete'">{{'collection.edit.delete'
|
|
||||||
| translate}}</a>
|
|
||||||
|
@@ -11,6 +11,7 @@ import { GroupDataService } from '../../../core/eperson/group-data.service';
|
|||||||
import { RequestService } from '../../../core/data/request.service';
|
import { RequestService } from '../../../core/data/request.service';
|
||||||
import { RouterTestingModule } from '@angular/router/testing';
|
import { RouterTestingModule } from '@angular/router/testing';
|
||||||
import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
|
import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
|
||||||
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
|
||||||
describe('CollectionRolesComponent', () => {
|
describe('CollectionRolesComponent', () => {
|
||||||
|
|
||||||
@@ -67,6 +68,7 @@ describe('CollectionRolesComponent', () => {
|
|||||||
SharedModule,
|
SharedModule,
|
||||||
RouterTestingModule.withRoutes([]),
|
RouterTestingModule.withRoutes([]),
|
||||||
TranslateModule.forRoot(),
|
TranslateModule.forRoot(),
|
||||||
|
NoopAnimationsModule
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
CollectionRolesComponent,
|
CollectionRolesComponent,
|
||||||
|
@@ -31,6 +31,7 @@
|
|||||||
[formModel]="formModel"
|
[formModel]="formModel"
|
||||||
[formLayout]="formLayout"
|
[formLayout]="formLayout"
|
||||||
[displaySubmit]="false"
|
[displaySubmit]="false"
|
||||||
|
[displayCancel]="false"
|
||||||
(dfChange)="onChange($event)"
|
(dfChange)="onChange($event)"
|
||||||
(submitForm)="onSubmit()"
|
(submitForm)="onSubmit()"
|
||||||
(cancel)="onCancel()"></ds-form>
|
(cancel)="onCancel()"></ds-form>
|
||||||
|
@@ -18,7 +18,14 @@ describe('EditCollectionPageComponent', () => {
|
|||||||
dso: { payload: {} }
|
dso: { payload: {} }
|
||||||
}),
|
}),
|
||||||
routeConfig: {
|
routeConfig: {
|
||||||
children: []
|
children: [
|
||||||
|
{
|
||||||
|
path: 'mockUrl',
|
||||||
|
data: {
|
||||||
|
hideReturnButton: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
snapshot: {
|
snapshot: {
|
||||||
firstChild: {
|
firstChild: {
|
||||||
|
@@ -93,7 +93,7 @@ import { CollectionAdministratorGuard } from '../../core/data/feature-authorizat
|
|||||||
{
|
{
|
||||||
path: 'mapper',
|
path: 'mapper',
|
||||||
component: CollectionItemMapperComponent,
|
component: CollectionItemMapperComponent,
|
||||||
data: { title: 'collection.edit.tabs.item-mapper.title', showBreadcrumbs: true }
|
data: { title: 'collection.edit.tabs.item-mapper.title', hideReturnButton: true, showBreadcrumbs: true }
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@@ -7,7 +7,6 @@ import {
|
|||||||
} from '@ng-dynamic-forms/core';
|
} from '@ng-dynamic-forms/core';
|
||||||
import { Community } from '../../core/shared/community.model';
|
import { Community } from '../../core/shared/community.model';
|
||||||
import { ComColFormComponent } from '../../shared/comcol-forms/comcol-form/comcol-form.component';
|
import { ComColFormComponent } from '../../shared/comcol-forms/comcol-form/comcol-form.component';
|
||||||
import { Location } from '@angular/common';
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
import { NotificationsService } from '../../shared/notifications/notifications.service';
|
||||||
import { CommunityDataService } from '../../core/data/community-data.service';
|
import { CommunityDataService } from '../../core/data/community-data.service';
|
||||||
@@ -68,14 +67,13 @@ export class CommunityFormComponent extends ComColFormComponent<Community> {
|
|||||||
}),
|
}),
|
||||||
];
|
];
|
||||||
|
|
||||||
public constructor(protected location: Location,
|
public constructor(protected formService: DynamicFormService,
|
||||||
protected formService: DynamicFormService,
|
|
||||||
protected translate: TranslateService,
|
protected translate: TranslateService,
|
||||||
protected notificationsService: NotificationsService,
|
protected notificationsService: NotificationsService,
|
||||||
protected authService: AuthService,
|
protected authService: AuthService,
|
||||||
protected dsoService: CommunityDataService,
|
protected dsoService: CommunityDataService,
|
||||||
protected requestService: RequestService,
|
protected requestService: RequestService,
|
||||||
protected objectCache: ObjectCacheService) {
|
protected objectCache: ObjectCacheService) {
|
||||||
super(location, formService, translate, notificationsService, authService, requestService, objectCache);
|
super(formService, translate, notificationsService, authService, requestService, objectCache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,5 +7,7 @@
|
|||||||
</ng-container>
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ds-community-form (submitForm)="onSubmit($event)" (finish)="navigateToNewPage()"></ds-community-form>
|
<ds-community-form (submitForm)="onSubmit($event)"
|
||||||
|
(back)="navigateToHome()"
|
||||||
|
(finish)="navigateToNewPage()"></ds-community-form>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -2,18 +2,20 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<ng-container *ngVar="(dsoRD$ | async)?.payload as dso">
|
<ng-container *ngVar="(dsoRD$ | async)?.payload as dso">
|
||||||
<div class="col-12 pb-4">
|
<div class="col-12 pb-4">
|
||||||
<h2 id="header" class="border-bottom pb-2">{{ 'community.delete.head' | translate
|
<h2 id="header" class="border-bottom pb-2">{{ 'community.delete.head' | translate}}</h2>
|
||||||
}}</h2>
|
|
||||||
<p class="pb-2">{{ 'community.delete.text' | translate:{ dso: dso.name } }}</p>
|
<p class="pb-2">{{ 'community.delete.text' | translate:{ dso: dso.name } }}</p>
|
||||||
<button class="btn btn-primary mr-2" (click)="onConfirm(dso)">
|
<div class="form-group row">
|
||||||
{{'community.delete.confirm' |
|
<div class="col text-right">
|
||||||
translate}}
|
<button class="btn btn-outline-secondary" (click)="onCancel(dso)">
|
||||||
</button>
|
<i class="fas fa-times"></i> {{'community.delete.cancel' | translate}}
|
||||||
<button class="btn btn-primary" (click)="onCancel(dso)">{{'community.delete.cancel' | translate}}
|
</button>
|
||||||
</button>
|
<button class="btn btn-danger mr-2" (click)="onConfirm(dso)">
|
||||||
|
<i class="fas fa-trash"></i> {{'community.delete.confirm' | translate}}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,6 +1,5 @@
|
|||||||
<ds-community-form (submitForm)="onSubmit($event)"
|
<ds-community-form [dso]="(dsoRD$ | async)?.payload"
|
||||||
[dso]="(dsoRD$ | async)?.payload"
|
(submitForm)="onSubmit($event)"
|
||||||
|
(back)="navigateToHomePage()"
|
||||||
(finish)="navigateToHomePage()"></ds-community-form>
|
(finish)="navigateToHomePage()"></ds-community-form>
|
||||||
<a class="btn btn-danger"
|
|
||||||
[routerLink]="'/communities/' + (dsoRD$ | async)?.payload.uuid + '/delete'">{{'community.edit.delete'
|
|
||||||
| translate}}</a>
|
|
||||||
|
@@ -11,6 +11,7 @@ import { GroupDataService } from '../../../core/eperson/group-data.service';
|
|||||||
import { SharedModule } from '../../../shared/shared.module';
|
import { SharedModule } from '../../../shared/shared.module';
|
||||||
import { RouterTestingModule } from '@angular/router/testing';
|
import { RouterTestingModule } from '@angular/router/testing';
|
||||||
import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
|
import { createSuccessfulRemoteDataObject, createSuccessfulRemoteDataObject$ } from '../../../shared/remote-data.utils';
|
||||||
|
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||||
|
|
||||||
describe('CommunityRolesComponent', () => {
|
describe('CommunityRolesComponent', () => {
|
||||||
|
|
||||||
@@ -52,6 +53,7 @@ describe('CommunityRolesComponent', () => {
|
|||||||
SharedModule,
|
SharedModule,
|
||||||
RouterTestingModule.withRoutes([]),
|
RouterTestingModule.withRoutes([]),
|
||||||
TranslateModule.forRoot(),
|
TranslateModule.forRoot(),
|
||||||
|
NoopAnimationsModule
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
CommunityRolesComponent,
|
CommunityRolesComponent,
|
||||||
|
@@ -18,7 +18,14 @@ describe('EditCommunityPageComponent', () => {
|
|||||||
dso: { payload: {} }
|
dso: { payload: {} }
|
||||||
}),
|
}),
|
||||||
routeConfig: {
|
routeConfig: {
|
||||||
children: []
|
children: [
|
||||||
|
{
|
||||||
|
path: 'mockUrl',
|
||||||
|
data: {
|
||||||
|
hideReturnButton: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
snapshot: {
|
snapshot: {
|
||||||
firstChild: {
|
firstChild: {
|
||||||
|
@@ -1,7 +1,6 @@
|
|||||||
<div class="jumbotron jumbotron-fluid">
|
<div class="jumbotron jumbotron-fluid">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="d-flex flex-wrap">
|
<div class="d-flex flex-wrap">
|
||||||
<img class="mr-4 dspace-logo" src="assets/images/dspace-logo.svg" alt="" />
|
|
||||||
<div>
|
<div>
|
||||||
<h1 class="display-3">Welcome to the DSpace 7 Preview</h1>
|
<h1 class="display-3">Welcome to the DSpace 7 Preview</h1>
|
||||||
<p class="lead">DSpace is the world leading open source repository platform that enables organisations to:</p>
|
<p class="lead">DSpace is the world leading open source repository platform that enables organisations to:</p>
|
||||||
|
@@ -8,7 +8,14 @@
|
|||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dspace-logo {
|
.jumbotron {
|
||||||
height: 110px;
|
background-color: var(--ds-home-news-background-color);
|
||||||
width: 110px;
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--ds-home-news-link-color);
|
||||||
|
|
||||||
|
@include hover {
|
||||||
|
color: var(--ds-home-news-link-hover-color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -3,6 +3,6 @@
|
|||||||
<ng-container *ngIf="(site$ | async) as site">
|
<ng-container *ngIf="(site$ | async) as site">
|
||||||
<ds-view-tracker [object]="site"></ds-view-tracker>
|
<ds-view-tracker [object]="site"></ds-view-tracker>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ds-search-form [inPlaceSearch]="false"></ds-search-form>
|
<ds-search-form [inPlaceSearch]="false" [searchPlaceholder]="'home.search-form.placeholder' | translate"></ds-search-form>
|
||||||
<ds-top-level-community-list></ds-top-level-community-list>
|
<ds-top-level-community-list></ds-top-level-community-list>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -23,7 +23,11 @@
|
|||||||
<div class="mb-4">
|
<div class="mb-4">
|
||||||
<router-outlet></router-outlet>
|
<router-outlet></router-outlet>
|
||||||
</div>
|
</div>
|
||||||
<a [routerLink]="getItemPage((itemRD$ | async)?.payload)" class="btn btn-outline-secondary">Cancel</a>
|
<div class="button-row bottom">
|
||||||
|
<div class="text-right">
|
||||||
|
<a [routerLink]="getItemPage((itemRD$ | async)?.payload)" role="button" class="btn btn-outline-secondary mr-1"><i class="fas fa-arrow-left"></i> {{'item.edit.return' | translate}}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -39,12 +39,11 @@ export class EditItemPageComponent implements OnInit {
|
|||||||
pages: { page: string, enabled: Observable<boolean> }[];
|
pages: { page: string, enabled: Observable<boolean> }[];
|
||||||
|
|
||||||
constructor(private route: ActivatedRoute, private router: Router, private injector: Injector) {
|
constructor(private route: ActivatedRoute, private router: Router, private injector: Injector) {
|
||||||
this.router.events.subscribe(() => {
|
this.router.events.subscribe(() => this.initPageParamsByRoute());
|
||||||
this.currentPage = this.route.snapshot.firstChild.routeConfig.path;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
|
this.initPageParamsByRoute();
|
||||||
this.pages = this.route.routeConfig.children
|
this.pages = this.route.routeConfig.children
|
||||||
.filter((child: Route) => isNotEmpty(child.path))
|
.filter((child: Route) => isNotEmpty(child.path))
|
||||||
.map((child: Route) => {
|
.map((child: Route) => {
|
||||||
@@ -70,4 +69,11 @@ export class EditItemPageComponent implements OnInit {
|
|||||||
getItemPage(item: Item): string {
|
getItemPage(item: Item): string {
|
||||||
return getItemPageRoute(item);
|
return getItemPageRoute(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set page params depending on the route
|
||||||
|
*/
|
||||||
|
initPageParamsByRoute() {
|
||||||
|
this.currentPage = this.route.snapshot.firstChild.routeConfig.path;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -5,22 +5,22 @@
|
|||||||
class="fas fa-upload"></i>
|
class="fas fa-upload"></i>
|
||||||
<span class="d-none d-sm-inline"> {{"item.edit.bitstreams.upload-button" | translate}}</span>
|
<span class="d-none d-sm-inline"> {{"item.edit.bitstreams.upload-button" | translate}}</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-danger mr-1" *ngIf="!(isReinstatable() | async)"
|
|
||||||
[disabled]="!(hasChanges() | async) || submitting"
|
|
||||||
(click)="discard()"><i
|
|
||||||
class="fas fa-times"></i>
|
|
||||||
<span class="d-none d-sm-inline"> {{"item.edit.bitstreams.discard-button" | translate}}</span>
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-warning mr-1" *ngIf="isReinstatable() | async"
|
<button class="btn btn-warning mr-1" *ngIf="isReinstatable() | async"
|
||||||
(click)="reinstate()"><i
|
(click)="reinstate()"><i
|
||||||
class="fas fa-undo-alt"></i>
|
class="fas fa-undo-alt"></i>
|
||||||
<span class="d-none d-sm-inline"> {{"item.edit.bitstreams.reinstate-button" | translate}}</span>
|
<span class="d-none d-sm-inline"> {{"item.edit.bitstreams.reinstate-button" | translate}}</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-primary" [disabled]="!(hasChanges() | async) || submitting"
|
<button class="btn btn-primary mr-1" [disabled]="!(hasChanges() | async) || submitting"
|
||||||
(click)="submit()"><i
|
(click)="submit()"><i
|
||||||
class="fas fa-save"></i>
|
class="fas fa-save"></i>
|
||||||
<span class="d-none d-sm-inline"> {{"item.edit.bitstreams.save-button" | translate}}</span>
|
<span class="d-none d-sm-inline"> {{"item.edit.bitstreams.save-button" | translate}}</span>
|
||||||
</button>
|
</button>
|
||||||
|
<button class="btn btn-danger" *ngIf="!(isReinstatable() | async)"
|
||||||
|
[disabled]="!(hasChanges() | async) || submitting"
|
||||||
|
(click)="discard()"><i
|
||||||
|
class="fas fa-times"></i>
|
||||||
|
<span class="d-none d-sm-inline"> {{"item.edit.bitstreams.discard-button" | translate}}</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div *ngIf="item && bundles?.length > 0" class="container table-bordered mt-4">
|
<div *ngIf="item && bundles?.length > 0" class="container table-bordered mt-4">
|
||||||
@@ -48,12 +48,6 @@
|
|||||||
|
|
||||||
<div class="button-row bottom">
|
<div class="button-row bottom">
|
||||||
<div class="mt-4 float-right">
|
<div class="mt-4 float-right">
|
||||||
<button class="btn btn-danger" *ngIf="!(isReinstatable() | async)"
|
|
||||||
[disabled]="!(hasChanges() | async) || submitting"
|
|
||||||
(click)="discard()"><i
|
|
||||||
class="fas fa-times"></i>
|
|
||||||
<span class="d-none d-sm-inline"> {{"item.edit.bitstreams.discard-button" | translate}}</span>
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-warning" *ngIf="isReinstatable() | async"
|
<button class="btn btn-warning" *ngIf="isReinstatable() | async"
|
||||||
(click)="reinstate()"><i
|
(click)="reinstate()"><i
|
||||||
class="fas fa-undo-alt"></i>
|
class="fas fa-undo-alt"></i>
|
||||||
@@ -64,6 +58,12 @@
|
|||||||
class="fas fa-save"></i>
|
class="fas fa-save"></i>
|
||||||
<span class="d-none d-sm-inline"> {{"item.edit.bitstreams.save-button" | translate}}</span>
|
<span class="d-none d-sm-inline"> {{"item.edit.bitstreams.save-button" | translate}}</span>
|
||||||
</button>
|
</button>
|
||||||
|
<button class="btn btn-danger" *ngIf="!(isReinstatable() | async)"
|
||||||
|
[disabled]="!(hasChanges() | async) || submitting"
|
||||||
|
(click)="discard()"><i
|
||||||
|
class="fas fa-times"></i>
|
||||||
|
<span class="d-none d-sm-inline"> {{"item.edit.bitstreams.discard-button" | translate}}</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -29,6 +29,7 @@
|
|||||||
[query]="(searchOptions$ | async)?.query"
|
[query]="(searchOptions$ | async)?.query"
|
||||||
[currentUrl]="'./'"
|
[currentUrl]="'./'"
|
||||||
[inPlaceSearch]="true"
|
[inPlaceSearch]="true"
|
||||||
|
[searchPlaceholder]="'item.edit.item-mapper.search-form.placeholder' | translate"
|
||||||
(submitSearch)="performedSearch = true">
|
(submitSearch)="performedSearch = true">
|
||||||
</ds-search-form>
|
</ds-search-form>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -112,7 +112,7 @@ export class ItemDeleteComponent
|
|||||||
super.ngOnInit();
|
super.ngOnInit();
|
||||||
this.url = this.router.url;
|
this.url = this.router.url;
|
||||||
|
|
||||||
const label = this.item.firstMetadataValue('relationship.type');
|
const label = this.item.firstMetadataValue('dspace.entity.type');
|
||||||
if (label !== undefined) {
|
if (label !== undefined) {
|
||||||
this.types$ = this.entityTypeService.getEntityTypeByLabel(label).pipe(
|
this.types$ = this.entityTypeService.getEntityTypeByLabel(label).pipe(
|
||||||
getFirstSucceededRemoteData(),
|
getFirstSucceededRemoteData(),
|
||||||
|
@@ -5,12 +5,6 @@
|
|||||||
class="fas fa-plus"></i>
|
class="fas fa-plus"></i>
|
||||||
<span class="d-none d-sm-inline"> {{"item.edit.metadata.add-button" | translate}}</span>
|
<span class="d-none d-sm-inline"> {{"item.edit.metadata.add-button" | translate}}</span>
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-danger" *ngIf="!(isReinstatable() | async)"
|
|
||||||
[disabled]="!(hasChanges() | async)"
|
|
||||||
(click)="discard()"><i
|
|
||||||
class="fas fa-times"></i>
|
|
||||||
<span class="d-none d-sm-inline"> {{"item.edit.metadata.discard-button" | translate}}</span>
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-warning" *ngIf="isReinstatable() | async"
|
<button class="btn btn-warning" *ngIf="isReinstatable() | async"
|
||||||
(click)="reinstate()"><i
|
(click)="reinstate()"><i
|
||||||
class="fas fa-undo-alt"></i>
|
class="fas fa-undo-alt"></i>
|
||||||
@@ -21,6 +15,12 @@
|
|||||||
class="fas fa-save"></i>
|
class="fas fa-save"></i>
|
||||||
<span class="d-none d-sm-inline"> {{"item.edit.metadata.save-button" | translate}}</span>
|
<span class="d-none d-sm-inline"> {{"item.edit.metadata.save-button" | translate}}</span>
|
||||||
</button>
|
</button>
|
||||||
|
<button class="btn btn-danger" *ngIf="!(isReinstatable() | async)"
|
||||||
|
[disabled]="!(hasChanges() | async)"
|
||||||
|
(click)="discard()"><i
|
||||||
|
class="fas fa-times"></i>
|
||||||
|
<span class="d-none d-sm-inline"> {{"item.edit.metadata.discard-button" | translate}}</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<table class="table table-responsive table-striped table-bordered" *ngIf="((updates$ | async)| dsObjectValues).length > 0">
|
<table class="table table-responsive table-striped table-bordered" *ngIf="((updates$ | async)| dsObjectValues).length > 0">
|
||||||
<tbody>
|
<tbody>
|
||||||
@@ -47,20 +47,20 @@
|
|||||||
<ds-alert [content]="'item.edit.metadata.empty'" [type]="AlertTypeEnum.Info"></ds-alert>
|
<ds-alert [content]="'item.edit.metadata.empty'" [type]="AlertTypeEnum.Info"></ds-alert>
|
||||||
</div>
|
</div>
|
||||||
<div class="button-row bottom">
|
<div class="button-row bottom">
|
||||||
<div class="float-right">
|
<div class="mt-2 float-right">
|
||||||
<button class="btn btn-danger mr-1" *ngIf="!(isReinstatable() | async)"
|
<button class="btn btn-warning" *ngIf="isReinstatable() | async"
|
||||||
|
(click)="reinstate()"><i
|
||||||
|
class="fas fa-undo-alt"></i> {{"item.edit.metadata.reinstate-button" | translate}}
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-primary mr-0" [disabled]="!(hasChanges() | async)"
|
||||||
|
(click)="submit()"><i
|
||||||
|
class="fas fa-save"></i> {{"item.edit.metadata.save-button" | translate}}
|
||||||
|
</button>
|
||||||
|
<button class="btn btn-danger" *ngIf="!(isReinstatable() | async)"
|
||||||
[disabled]="!(hasChanges() | async)"
|
[disabled]="!(hasChanges() | async)"
|
||||||
(click)="discard()"><i
|
(click)="discard()"><i
|
||||||
class="fas fa-times"></i> {{"item.edit.metadata.discard-button" | translate}}
|
class="fas fa-times"></i> {{"item.edit.metadata.discard-button" | translate}}
|
||||||
</button>
|
</button>
|
||||||
<button class="btn btn-warning mr-1" *ngIf="isReinstatable() | async"
|
|
||||||
(click)="reinstate()"><i
|
|
||||||
class="fas fa-undo-alt"></i> {{"item.edit.metadata.reinstate-button" | translate}}
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-primary" [disabled]="!(hasChanges() | async)"
|
|
||||||
(click)="submit()"><i
|
|
||||||
class="fas fa-save"></i> {{"item.edit.metadata.save-button" | translate}}
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="!operation.disabled" class="col-9 float-left action-button">
|
<div *ngIf="!operation.disabled" class="col-9 float-left action-button">
|
||||||
<a class="btn btn-outline-secondary" [routerLink]="operation.operationUrl">
|
<a class="btn btn-outline-primary" [routerLink]="operation.operationUrl">
|
||||||
{{'item.edit.tabs.status.buttons.' + operation.operationKey + '.button' | translate}}
|
{{'item.edit.tabs.status.buttons.' + operation.operationKey + '.button' | translate}}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
@@ -12,4 +12,4 @@
|
|||||||
<span class="btn btn-danger">
|
<span class="btn btn-danger">
|
||||||
{{'item.edit.tabs.status.buttons.' + operation.operationKey + '.button' | translate}}
|
{{'item.edit.tabs.status.buttons.' + operation.operationKey + '.button' | translate}}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -75,7 +75,7 @@ export class ItemRelationshipsComponent extends AbstractItemUpdateComponent {
|
|||||||
*/
|
*/
|
||||||
public initializeUpdates(): void {
|
public initializeUpdates(): void {
|
||||||
|
|
||||||
const label = this.item.firstMetadataValue('relationship.type');
|
const label = this.item.firstMetadataValue('dspace.entity.type');
|
||||||
if (label !== undefined) {
|
if (label !== undefined) {
|
||||||
|
|
||||||
this.entityType$ = this.entityTypeService.getEntityTypeByLabel(label).pipe(
|
this.entityType$ = this.entityTypeService.getEntityTypeByLabel(label).pipe(
|
||||||
|
@@ -10,11 +10,11 @@ export function getItemModuleRoute() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the route to an item's page
|
* Get the route to an item's page
|
||||||
* Depending on the item's relationship type, the route will either start with /items or /entities
|
* Depending on the item's entity type, the route will either start with /items or /entities
|
||||||
* @param item The item to retrieve the route for
|
* @param item The item to retrieve the route for
|
||||||
*/
|
*/
|
||||||
export function getItemPageRoute(item: Item) {
|
export function getItemPageRoute(item: Item) {
|
||||||
const type = item.firstMetadataValue('relationship.type');
|
const type = item.firstMetadataValue('dspace.entity.type');
|
||||||
return getEntityPageRoute(type, item.uuid);
|
return getEntityPageRoute(type, item.uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
<h2 class="item-page-title-field">
|
<h2 class="item-page-title-field">
|
||||||
<div *ngIf="item.firstMetadataValue('relationship.type') as type">
|
<div *ngIf="item.firstMetadataValue('dspace.entity.type') as type">
|
||||||
{{ type.toLowerCase() + '.page.titleprefix' | translate }}
|
{{ type.toLowerCase() + '.page.titleprefix' | translate }}
|
||||||
</div>
|
</div>
|
||||||
<ds-metadata-values [mdValues]="item?.allMetadata(fields)"></ds-metadata-values>
|
<ds-metadata-values [mdValues]="item?.allMetadata(fields)"></ds-metadata-values>
|
||||||
|
@@ -79,8 +79,8 @@
|
|||||||
</ds-item-page-uri-field>
|
</ds-item-page-uri-field>
|
||||||
<ds-item-page-collections [item]="object"></ds-item-page-collections>
|
<ds-item-page-collections [item]="object"></ds-item-page-collections>
|
||||||
<div>
|
<div>
|
||||||
<a class="btn btn-outline-primary" [routerLink]="[itemPageRoute + '/full']">
|
<a class="btn btn-outline-primary" role="button" [routerLink]="[itemPageRoute + '/full']">
|
||||||
{{"item.page.link.full" | translate}}
|
<i class="fas fa-info-circle"></i> {{"item.page.link.full" | translate}}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -64,8 +64,8 @@
|
|||||||
</ds-item-page-uri-field>
|
</ds-item-page-uri-field>
|
||||||
<ds-item-page-collections [item]="object"></ds-item-page-collections>
|
<ds-item-page-collections [item]="object"></ds-item-page-collections>
|
||||||
<div>
|
<div>
|
||||||
<a class="btn btn-outline-primary" [routerLink]="[itemPageRoute + '/full']">
|
<a class="btn btn-outline-primary" [routerLink]="[itemPageRoute + '/full']" role="button">
|
||||||
{{"item.page.link.full" | translate}}
|
<i class="fas fa-info-circle"></i> {{"item.page.link.full" | translate}}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
<div class="container w-100 h-100">
|
<div class="container w-100 h-100">
|
||||||
<div class="text-center mt-5 row justify-content-center">
|
<div class="text-center mt-5 row justify-content-center">
|
||||||
<div>
|
<div>
|
||||||
<img class="mb-4 login-logo" src="assets/images/dspace-logo.png">
|
<img class="mb-4 login-logo" src="assets/images/dspace-logo.png" alt="{{'repository.image.logo' | translate}}">
|
||||||
<h1 class="h3 mb-0 font-weight-normal">{{"login.form.header" | translate}}</h1>
|
<h1 class="h3 mb-0 font-weight-normal">{{"login.form.header" | translate}}</h1>
|
||||||
<ds-log-in
|
<ds-log-in
|
||||||
[isStandalonePage]="true"></ds-log-in>
|
[isStandalonePage]="true"></ds-log-in>
|
||||||
|
@@ -8,12 +8,12 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
<div class="add">
|
<div class="add">
|
||||||
<button class="btn btn-lg btn-primary mt-1 ml-2" (click)="openDialog()" role="button" title="{{'mydspace.new-submission' | translate}}">
|
<button class="btn btn-lg btn-primary mt-1 ml-2" (click)="openDialog()" attr.aria-label="'mydspace.new-submission' | translate" title="{{'mydspace.new-submission' | translate}}">
|
||||||
<i class="fa fa-plus-circle" aria-hidden="true"></i>
|
<i class="fa fa-plus" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="add">
|
<div class="add">
|
||||||
<a class="btn btn-lg btn-primary mt-1 ml-2" [routerLink]="['/import-external']" role="button" title="{{'mydspace.new-submission-external' | translate}}">
|
<a class="btn btn-lg btn-outline-primary mt-1 ml-2" [routerLink]="['/import-external']" role="button" attr.aria-label="{{'mydspace.new-submission-external' | translate}}" title="{{'mydspace.new-submission-external' | translate}}">
|
||||||
<i class="fa fa-file-import" aria-hidden="true"></i>
|
<i class="fa fa-file-import" aria-hidden="true"></i>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -2,6 +2,7 @@ import { NgModule } from '@angular/core';
|
|||||||
import { RouterModule } from '@angular/router';
|
import { RouterModule } from '@angular/router';
|
||||||
import { MyDSpaceGuard } from './my-dspace.guard';
|
import { MyDSpaceGuard } from './my-dspace.guard';
|
||||||
import { ThemedMyDSpacePageComponent } from './themed-my-dspace-page.component';
|
import { ThemedMyDSpacePageComponent } from './themed-my-dspace-page.component';
|
||||||
|
import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -9,7 +10,10 @@ import { ThemedMyDSpacePageComponent } from './themed-my-dspace-page.component';
|
|||||||
{
|
{
|
||||||
path: '',
|
path: '',
|
||||||
component: ThemedMyDSpacePageComponent,
|
component: ThemedMyDSpacePageComponent,
|
||||||
data: { title: 'mydspace.title' },
|
resolve: {
|
||||||
|
breadcrumb: I18nBreadcrumbResolver
|
||||||
|
},
|
||||||
|
data: { title: 'mydspace.title', breadcrumbKey: 'mydspace' },
|
||||||
canActivate: [
|
canActivate: [
|
||||||
MyDSpaceGuard
|
MyDSpaceGuard
|
||||||
]
|
]
|
||||||
|
@@ -14,7 +14,8 @@
|
|||||||
[scope]="(searchOptions$ | async)?.scope"
|
[scope]="(searchOptions$ | async)?.scope"
|
||||||
[currentUrl]="getSearchLink()"
|
[currentUrl]="getSearchLink()"
|
||||||
[scopes]="(scopeListRD$ | async)"
|
[scopes]="(scopeListRD$ | async)"
|
||||||
[inPlaceSearch]="inPlaceSearch">
|
[inPlaceSearch]="inPlaceSearch"
|
||||||
|
[searchPlaceholder]="'mydspace.search-form.placeholder' | translate">
|
||||||
</ds-search-form>
|
</ds-search-form>
|
||||||
<ds-search-labels [inPlaceSearch]="inPlaceSearch"></ds-search-labels>
|
<ds-search-labels [inPlaceSearch]="inPlaceSearch"></ds-search-labels>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
@@ -45,7 +45,8 @@
|
|||||||
[scope]="(searchOptions$ | async)?.scope"
|
[scope]="(searchOptions$ | async)?.scope"
|
||||||
[currentUrl]="searchLink"
|
[currentUrl]="searchLink"
|
||||||
[scopes]="(scopeListRD$ | async)"
|
[scopes]="(scopeListRD$ | async)"
|
||||||
[inPlaceSearch]="inPlaceSearch">
|
[inPlaceSearch]="inPlaceSearch"
|
||||||
|
[searchPlaceholder]="'search.search-form.placeholder' | translate">
|
||||||
</ds-search-form>
|
</ds-search-form>
|
||||||
<div class="row mb-3 mb-md-1">
|
<div class="row mb-3 mb-md-1">
|
||||||
<div class="labels col-sm-9 offset-sm-3">
|
<div class="labels col-sm-9 offset-sm-3">
|
||||||
|
@@ -3,6 +3,7 @@ import { RouterModule } from '@angular/router';
|
|||||||
|
|
||||||
import { AuthenticatedGuard } from '../core/auth/authenticated.guard';
|
import { AuthenticatedGuard } from '../core/auth/authenticated.guard';
|
||||||
import { ThemedSubmissionSubmitComponent } from '../submission/submit/themed-submission-submit.component';
|
import { ThemedSubmissionSubmitComponent } from '../submission/submit/themed-submission-submit.component';
|
||||||
|
import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -12,7 +13,10 @@ import { ThemedSubmissionSubmitComponent } from '../submission/submit/themed-sub
|
|||||||
path: '',
|
path: '',
|
||||||
pathMatch: 'full',
|
pathMatch: 'full',
|
||||||
component: ThemedSubmissionSubmitComponent,
|
component: ThemedSubmissionSubmitComponent,
|
||||||
data: { title: 'submission.submit.title' }
|
resolve: {
|
||||||
|
breadcrumb: I18nBreadcrumbResolver
|
||||||
|
},
|
||||||
|
data: { title: 'submission.submit.title', breadcrumbKey: 'submission.submit' }
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
]
|
]
|
||||||
|
@@ -3,10 +3,15 @@ import { RouterModule } from '@angular/router';
|
|||||||
|
|
||||||
import { AuthenticatedGuard } from '../core/auth/authenticated.guard';
|
import { AuthenticatedGuard } from '../core/auth/authenticated.guard';
|
||||||
import { WorkflowItemPageResolver } from './workflow-item-page.resolver';
|
import { WorkflowItemPageResolver } from './workflow-item-page.resolver';
|
||||||
import { WORKFLOW_ITEM_DELETE_PATH, WORKFLOW_ITEM_EDIT_PATH, WORKFLOW_ITEM_SEND_BACK_PATH } from './workflowitems-edit-page-routing-paths';
|
import {
|
||||||
|
WORKFLOW_ITEM_DELETE_PATH,
|
||||||
|
WORKFLOW_ITEM_EDIT_PATH,
|
||||||
|
WORKFLOW_ITEM_SEND_BACK_PATH
|
||||||
|
} from './workflowitems-edit-page-routing-paths';
|
||||||
import { ThemedSubmissionEditComponent } from '../submission/edit/themed-submission-edit.component';
|
import { ThemedSubmissionEditComponent } from '../submission/edit/themed-submission-edit.component';
|
||||||
import { ThemedWorkflowItemDeleteComponent } from './workflow-item-delete/themed-workflow-item-delete.component';
|
import { ThemedWorkflowItemDeleteComponent } from './workflow-item-delete/themed-workflow-item-delete.component';
|
||||||
import { ThemedWorkflowItemSendBackComponent } from './workflow-item-send-back/themed-workflow-item-send-back.component';
|
import { ThemedWorkflowItemSendBackComponent } from './workflow-item-send-back/themed-workflow-item-send-back.component';
|
||||||
|
import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -19,19 +24,28 @@ import { ThemedWorkflowItemSendBackComponent } from './workflow-item-send-back/t
|
|||||||
canActivate: [AuthenticatedGuard],
|
canActivate: [AuthenticatedGuard],
|
||||||
path: WORKFLOW_ITEM_EDIT_PATH,
|
path: WORKFLOW_ITEM_EDIT_PATH,
|
||||||
component: ThemedSubmissionEditComponent,
|
component: ThemedSubmissionEditComponent,
|
||||||
data: { title: 'submission.edit.title' }
|
resolve: {
|
||||||
|
breadcrumb: I18nBreadcrumbResolver
|
||||||
|
},
|
||||||
|
data: { title: 'workflow-item.edit.title', breadcrumbKey: 'workflow-item.edit' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
canActivate: [AuthenticatedGuard],
|
canActivate: [AuthenticatedGuard],
|
||||||
path: WORKFLOW_ITEM_DELETE_PATH,
|
path: WORKFLOW_ITEM_DELETE_PATH,
|
||||||
component: ThemedWorkflowItemDeleteComponent,
|
component: ThemedWorkflowItemDeleteComponent,
|
||||||
data: { title: 'workflow-item.delete.title' }
|
resolve: {
|
||||||
|
breadcrumb: I18nBreadcrumbResolver
|
||||||
|
},
|
||||||
|
data: { title: 'workflow-item.delete.title', breadcrumbKey: 'workflow-item.edit' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
canActivate: [AuthenticatedGuard],
|
canActivate: [AuthenticatedGuard],
|
||||||
path: WORKFLOW_ITEM_SEND_BACK_PATH,
|
path: WORKFLOW_ITEM_SEND_BACK_PATH,
|
||||||
component: ThemedWorkflowItemSendBackComponent,
|
component: ThemedWorkflowItemSendBackComponent,
|
||||||
data: { title: 'workflow-item.send-back.title' }
|
resolve: {
|
||||||
|
breadcrumb: I18nBreadcrumbResolver
|
||||||
|
},
|
||||||
|
data: { title: 'workflow-item.send-back.title', breadcrumbKey: 'workflow-item.edit' }
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
|
@@ -3,6 +3,7 @@ import { RouterModule } from '@angular/router';
|
|||||||
|
|
||||||
import { AuthenticatedGuard } from '../core/auth/authenticated.guard';
|
import { AuthenticatedGuard } from '../core/auth/authenticated.guard';
|
||||||
import { ThemedSubmissionEditComponent } from '../submission/edit/themed-submission-edit.component';
|
import { ThemedSubmissionEditComponent } from '../submission/edit/themed-submission-edit.component';
|
||||||
|
import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
@@ -12,7 +13,10 @@ import { ThemedSubmissionEditComponent } from '../submission/edit/themed-submiss
|
|||||||
canActivate: [AuthenticatedGuard],
|
canActivate: [AuthenticatedGuard],
|
||||||
path: ':id/edit',
|
path: ':id/edit',
|
||||||
component: ThemedSubmissionEditComponent,
|
component: ThemedSubmissionEditComponent,
|
||||||
data: { title: 'submission.edit.title' }
|
resolve: {
|
||||||
|
breadcrumb: I18nBreadcrumbResolver
|
||||||
|
},
|
||||||
|
data: { title: 'submission.edit.title', breadcrumbKey: 'submission.edit' }
|
||||||
}
|
}
|
||||||
])
|
])
|
||||||
]
|
]
|
||||||
|
@@ -4,22 +4,43 @@ import { EPeopleRegistryComponent } from './epeople-registry/epeople-registry.co
|
|||||||
import { GroupFormComponent } from './group-registry/group-form/group-form.component';
|
import { GroupFormComponent } from './group-registry/group-form/group-form.component';
|
||||||
import { GroupsRegistryComponent } from './group-registry/groups-registry.component';
|
import { GroupsRegistryComponent } from './group-registry/groups-registry.component';
|
||||||
import { GROUP_EDIT_PATH } from './access-control-routing-paths';
|
import { GROUP_EDIT_PATH } from './access-control-routing-paths';
|
||||||
|
import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
RouterModule.forChild([
|
RouterModule.forChild([
|
||||||
{ path: 'epeople', component: EPeopleRegistryComponent, data: { title: 'admin.access-control.epeople.title' } },
|
|
||||||
{ path: GROUP_EDIT_PATH, component: GroupsRegistryComponent, data: { title: 'admin.access-control.groups.title' } },
|
|
||||||
{
|
{
|
||||||
path: `${GROUP_EDIT_PATH}/:groupId`,
|
path: 'epeople',
|
||||||
component: GroupFormComponent,
|
component: EPeopleRegistryComponent,
|
||||||
data: {title: 'admin.access-control.groups.title.singleGroup'}
|
resolve: {
|
||||||
|
breadcrumb: I18nBreadcrumbResolver
|
||||||
|
},
|
||||||
|
data: { title: 'admin.access-control.epeople.title', breadcrumbKey: 'admin.access-control.epeople' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: GROUP_EDIT_PATH,
|
||||||
|
component: GroupsRegistryComponent,
|
||||||
|
resolve: {
|
||||||
|
breadcrumb: I18nBreadcrumbResolver
|
||||||
|
},
|
||||||
|
data: { title: 'admin.access-control.groups.title', breadcrumbKey: 'admin.access-control.groups' }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: `${GROUP_EDIT_PATH}/newGroup`,
|
path: `${GROUP_EDIT_PATH}/newGroup`,
|
||||||
component: GroupFormComponent,
|
component: GroupFormComponent,
|
||||||
data: {title: 'admin.access-control.groups.title.addGroup'}
|
resolve: {
|
||||||
|
breadcrumb: I18nBreadcrumbResolver
|
||||||
|
},
|
||||||
|
data: { title: 'admin.access-control.groups.title.addGroup', breadcrumbKey: 'admin.access-control.groups.addGroup' }
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: `${GROUP_EDIT_PATH}/:groupId`,
|
||||||
|
component: GroupFormComponent,
|
||||||
|
resolve: {
|
||||||
|
breadcrumb: I18nBreadcrumbResolver
|
||||||
|
},
|
||||||
|
data: { title: 'admin.access-control.groups.title.singleGroup', breadcrumbKey: 'admin.access-control.groups.singleGroup' }
|
||||||
|
}
|
||||||
])
|
])
|
||||||
]
|
]
|
||||||
})
|
})
|
||||||
|
@@ -1,46 +1,53 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="epeople-registry row">
|
<div class="epeople-registry row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
|
<div class="d-flex justify-content-between border-bottom mb-3">
|
||||||
|
<h2 id="header" class="pb-2">{{labelPrefix + 'head' | translate}}</h2>
|
||||||
|
|
||||||
<h2 id="header" class="border-bottom pb-2">{{labelPrefix + 'head' | translate}}</h2>
|
<div *ngIf="!isEPersonFormShown">
|
||||||
|
|
||||||
<ds-eperson-form *ngIf="isEPersonFormShown" (submitForm)="reset()"
|
|
||||||
(cancelForm)="isEPersonFormShown = false"></ds-eperson-form>
|
|
||||||
|
|
||||||
<div *ngIf="!isEPersonFormShown">
|
|
||||||
<div class="button-row top d-flex pb-2">
|
|
||||||
<button class="mr-auto btn btn-success addEPerson-button"
|
<button class="mr-auto btn btn-success addEPerson-button"
|
||||||
(click)="isEPersonFormShown = true">
|
(click)="isEPersonFormShown = true">
|
||||||
<i class="fas fa-plus"></i>
|
<i class="fas fa-plus"></i>
|
||||||
<span class="d-none d-sm-inline">{{labelPrefix + 'button.add' | translate}}</span>
|
<span class="d-none d-sm-inline">{{labelPrefix + 'button.add' | translate}}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ds-eperson-form *ngIf="isEPersonFormShown" (submitForm)="reset()"
|
||||||
|
(cancelForm)="isEPersonFormShown = false"></ds-eperson-form>
|
||||||
|
|
||||||
|
<div *ngIf="!isEPersonFormShown">
|
||||||
<h3 id="search" class="border-bottom pb-2">{{labelPrefix + 'search.head' | translate}}
|
<h3 id="search" class="border-bottom pb-2">{{labelPrefix + 'search.head' | translate}}
|
||||||
<button (click)="clearFormAndResetResult();"
|
|
||||||
class="btn btn-primary float-right">{{labelPrefix + 'button.see-all' | translate}}</button>
|
|
||||||
</h3>
|
</h3>
|
||||||
<form [formGroup]="searchForm" (ngSubmit)="search(searchForm.value)" class="row">
|
<form [formGroup]="searchForm" (ngSubmit)="search(searchForm.value)" class="d-flex justify-content-between">
|
||||||
<div class="col-12 col-sm-3">
|
<div>
|
||||||
<select name="scope" id="scope" formControlName="scope" class="form-control" aria-label="Search scope">
|
<select name="scope" id="scope" formControlName="scope" class="form-control" aria-label="Search scope">
|
||||||
<option value="metadata">{{labelPrefix + 'search.scope.metadata' | translate}}</option>
|
<option value="metadata">{{labelPrefix + 'search.scope.metadata' | translate}}</option>
|
||||||
<option value="email">{{labelPrefix + 'search.scope.email' | translate}}</option>
|
<option value="email">{{labelPrefix + 'search.scope.email' | translate}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-9 col-12">
|
<div class="flex-grow-1 mr-3 ml-3">
|
||||||
<div class="form-group input-group">
|
<div class="form-group input-group">
|
||||||
<input type="text" name="query" id="query" formControlName="query"
|
<input type="text" name="query" id="query" formControlName="query"
|
||||||
class="form-control" aria-label="Search input">
|
class="form-control" attr.aria-label="{{labelPrefix + 'search.placeholder' | translate}}"
|
||||||
|
[placeholder]="(labelPrefix + 'search.placeholder' | translate)">
|
||||||
<span class="input-group-append">
|
<span class="input-group-append">
|
||||||
<button type="submit"
|
<button type="submit" class="search-button btn btn-primary">
|
||||||
class="search-button btn btn-secondary">{{ labelPrefix + 'search.button' | translate }}</button>
|
<i class="fas fa-search"></i> {{ labelPrefix + 'search.button' | translate }}
|
||||||
</span>
|
</button>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<button (click)="clearFormAndResetResult();"
|
||||||
|
class="search-button btn btn-secondary">{{labelPrefix + 'button.see-all' | translate}}</button>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<ds-loading *ngIf="searching$ | async"></ds-loading>
|
||||||
<ds-pagination
|
<ds-pagination
|
||||||
*ngIf="(pageInfoState$ | async)?.totalElements > 0"
|
*ngIf="(pageInfoState$ | async)?.totalElements > 0 && !(searching$ | async)"
|
||||||
[paginationOptions]="config"
|
[paginationOptions]="config"
|
||||||
[pageInfoState]="pageInfoState$"
|
[pageInfoState]="pageInfoState$"
|
||||||
[collectionSize]="(pageInfoState$ | async)?.totalElements"
|
[collectionSize]="(pageInfoState$ | async)?.totalElements"
|
||||||
|
@@ -51,6 +51,11 @@ export class EPeopleRegistryComponent implements OnInit, OnDestroy {
|
|||||||
*/
|
*/
|
||||||
pageInfoState$: BehaviorSubject<PageInfo> = new BehaviorSubject<PageInfo>(undefined);
|
pageInfoState$: BehaviorSubject<PageInfo> = new BehaviorSubject<PageInfo>(undefined);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean representing if a search is pending
|
||||||
|
*/
|
||||||
|
searching$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pagination config used to display the list of epeople
|
* Pagination config used to display the list of epeople
|
||||||
*/
|
*/
|
||||||
@@ -106,6 +111,7 @@ export class EPeopleRegistryComponent implements OnInit, OnDestroy {
|
|||||||
* This method will initialise the page
|
* This method will initialise the page
|
||||||
*/
|
*/
|
||||||
initialisePage() {
|
initialisePage() {
|
||||||
|
this.searching$.next(true);
|
||||||
this.isEPersonFormShown = false;
|
this.isEPersonFormShown = false;
|
||||||
this.search({ scope: this.currentSearchScope, query: this.currentSearchQuery });
|
this.search({ scope: this.currentSearchScope, query: this.currentSearchQuery });
|
||||||
this.subs.push(this.epersonService.getActiveEPerson().subscribe((eperson: EPerson) => {
|
this.subs.push(this.epersonService.getActiveEPerson().subscribe((eperson: EPerson) => {
|
||||||
@@ -133,6 +139,7 @@ export class EPeopleRegistryComponent implements OnInit, OnDestroy {
|
|||||||
return [epeople];
|
return [epeople];
|
||||||
}
|
}
|
||||||
})).subscribe((value: PaginatedList<EpersonDtoModel>) => {
|
})).subscribe((value: PaginatedList<EpersonDtoModel>) => {
|
||||||
|
this.searching$.next(false);
|
||||||
this.ePeopleDto$.next(value);
|
this.ePeopleDto$.next(value);
|
||||||
this.pageInfoState$.next(value.pageInfo);
|
this.pageInfoState$.next(value.pageInfo);
|
||||||
}));
|
}));
|
||||||
@@ -154,6 +161,7 @@ export class EPeopleRegistryComponent implements OnInit, OnDestroy {
|
|||||||
* @param data Contains scope and query param
|
* @param data Contains scope and query param
|
||||||
*/
|
*/
|
||||||
search(data: any) {
|
search(data: any) {
|
||||||
|
this.searching$.next(true);
|
||||||
const query: string = data.query;
|
const query: string = data.query;
|
||||||
const scope: string = data.scope;
|
const scope: string = data.scope;
|
||||||
if (query != null && this.currentSearchQuery !== query) {
|
if (query != null && this.currentSearchQuery !== query) {
|
||||||
@@ -228,6 +236,8 @@ export class EPeopleRegistryComponent implements OnInit, OnDestroy {
|
|||||||
modalRef.componentInstance.infoLabel = 'confirmation-modal.delete-eperson.info';
|
modalRef.componentInstance.infoLabel = 'confirmation-modal.delete-eperson.info';
|
||||||
modalRef.componentInstance.cancelLabel = 'confirmation-modal.delete-eperson.cancel';
|
modalRef.componentInstance.cancelLabel = 'confirmation-modal.delete-eperson.cancel';
|
||||||
modalRef.componentInstance.confirmLabel = 'confirmation-modal.delete-eperson.confirm';
|
modalRef.componentInstance.confirmLabel = 'confirmation-modal.delete-eperson.confirm';
|
||||||
|
modalRef.componentInstance.brandColor = 'danger';
|
||||||
|
modalRef.componentInstance.confirmIcon = 'fas fa-trash';
|
||||||
modalRef.componentInstance.response.pipe(take(1)).subscribe((confirm: boolean) => {
|
modalRef.componentInstance.response.pipe(take(1)).subscribe((confirm: boolean) => {
|
||||||
if (confirm) {
|
if (confirm) {
|
||||||
if (hasValue(ePerson.id)) {
|
if (hasValue(ePerson.id)) {
|
||||||
|
@@ -12,19 +12,27 @@
|
|||||||
[formModel]="formModel"
|
[formModel]="formModel"
|
||||||
[formGroup]="formGroup"
|
[formGroup]="formGroup"
|
||||||
[formLayout]="formLayout"
|
[formLayout]="formLayout"
|
||||||
(cancel)="onCancel()"
|
[displayCancel]="false"
|
||||||
(submitForm)="onSubmit()">
|
(submitForm)="onSubmit()">
|
||||||
<button class="btn btn-light" [disabled]="!(canReset$ | async)">
|
<div before class="btn-group">
|
||||||
<i class="fa fa-key"></i> {{'admin.access-control.epeople.actions.reset' | translate}}
|
<button (click)="onCancel()"
|
||||||
</button>
|
class="btn btn-outline-secondary"><i class="fas fa-arrow-left"></i> {{messagePrefix + '.return' | translate}}</button>
|
||||||
<button class="btn btn-light delete-button" [disabled]="!(canDelete$ | async)" (click)="delete()">
|
</div>
|
||||||
<i class="fa fa-trash"></i> {{'admin.access-control.epeople.actions.delete' | translate}}
|
<div between class="btn-group">
|
||||||
</button>
|
<button class="btn btn-primary" [disabled]="!(canReset$ | async)">
|
||||||
<button *ngIf="!isImpersonated" class="btn btn-light" [ngClass]="{'d-none' : !(canImpersonate$ | async)}" (click)="impersonate()">
|
<i class="fa fa-key"></i> {{'admin.access-control.epeople.actions.reset' | translate}}
|
||||||
<i class="fa fa-user-secret"></i> {{'admin.access-control.epeople.actions.impersonate' | translate}}
|
</button>
|
||||||
</button>
|
</div>
|
||||||
<button *ngIf="isImpersonated" class="btn btn-light" (click)="stopImpersonating()">
|
<div between class="btn-group ml-1">
|
||||||
<i class="fa fa-user-secret"></i> {{'admin.access-control.epeople.actions.stop-impersonating' | translate}}
|
<button *ngIf="!isImpersonated" class="btn btn-primary" [ngClass]="{'d-none' : !(canImpersonate$ | async)}" (click)="impersonate()">
|
||||||
|
<i class="fa fa-user-secret"></i> {{'admin.access-control.epeople.actions.impersonate' | translate}}
|
||||||
|
</button>
|
||||||
|
<button *ngIf="isImpersonated" class="btn btn-primary" (click)="stopImpersonating()">
|
||||||
|
<i class="fa fa-user-secret"></i> {{'admin.access-control.epeople.actions.stop-impersonating' | translate}}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<button after class="btn btn-danger delete-button" [disabled]="!(canDelete$ | async)" (click)="delete()">
|
||||||
|
<i class="fas fa-trash"></i> {{'admin.access-control.epeople.actions.delete' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</ds-form>
|
</ds-form>
|
||||||
|
|
||||||
|
@@ -436,6 +436,8 @@ export class EPersonFormComponent implements OnInit, OnDestroy {
|
|||||||
modalRef.componentInstance.infoLabel = 'confirmation-modal.delete-eperson.info';
|
modalRef.componentInstance.infoLabel = 'confirmation-modal.delete-eperson.info';
|
||||||
modalRef.componentInstance.cancelLabel = 'confirmation-modal.delete-eperson.cancel';
|
modalRef.componentInstance.cancelLabel = 'confirmation-modal.delete-eperson.cancel';
|
||||||
modalRef.componentInstance.confirmLabel = 'confirmation-modal.delete-eperson.confirm';
|
modalRef.componentInstance.confirmLabel = 'confirmation-modal.delete-eperson.confirm';
|
||||||
|
modalRef.componentInstance.brandColor = 'danger';
|
||||||
|
modalRef.componentInstance.confirmIcon = 'fas fa-trash';
|
||||||
modalRef.componentInstance.response.pipe(take(1)).subscribe((confirm: boolean) => {
|
modalRef.componentInstance.response.pipe(take(1)).subscribe((confirm: boolean) => {
|
||||||
if (confirm) {
|
if (confirm) {
|
||||||
if (hasValue(eperson.id)) {
|
if (hasValue(eperson.id)) {
|
||||||
|
@@ -1,11 +1,6 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="group-form row">
|
<div class="group-form row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<ds-alert *ngIf="groupBeingEdited?.permanent" [type]="AlertTypeEnum.Warning"
|
|
||||||
[content]="messagePrefix + '.alert.permanent'"></ds-alert>
|
|
||||||
<ds-alert *ngIf="!(canEdit$ | async) && (groupDataService.getActiveGroup() | async)" [type]="AlertTypeEnum.Warning"
|
|
||||||
[content]="(messagePrefix + '.alert.workflowGroup' | translate:{ name: (getLinkedDSO(groupBeingEdited) | async)?.payload?.name, comcol: (getLinkedDSO(groupBeingEdited) | async)?.payload?.type, comcolEditRolesRoute: (getLinkedEditRolesRoute(groupBeingEdited) | async) })">
|
|
||||||
</ds-alert>
|
|
||||||
|
|
||||||
<div *ngIf="groupDataService.getActiveGroup() | async; then editheader; else createHeader"></div>
|
<div *ngIf="groupDataService.getActiveGroup() | async; then editheader; else createHeader"></div>
|
||||||
|
|
||||||
@@ -17,29 +12,38 @@
|
|||||||
<h2 class="border-bottom pb-2">{{messagePrefix + '.head.edit' | translate}}</h2>
|
<h2 class="border-bottom pb-2">{{messagePrefix + '.head.edit' | translate}}</h2>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
|
|
||||||
|
<ds-alert *ngIf="groupBeingEdited?.permanent" [type]="AlertTypeEnum.Warning"
|
||||||
|
[content]="messagePrefix + '.alert.permanent'"></ds-alert>
|
||||||
|
<ds-alert *ngIf="!(canEdit$ | async) && (groupDataService.getActiveGroup() | async)" [type]="AlertTypeEnum.Warning"
|
||||||
|
[content]="(messagePrefix + '.alert.workflowGroup' | translate:{ name: (getLinkedDSO(groupBeingEdited) | async)?.payload?.name, comcol: (getLinkedDSO(groupBeingEdited) | async)?.payload?.type, comcolEditRolesRoute: (getLinkedEditRolesRoute(groupBeingEdited) | async) })">
|
||||||
|
</ds-alert>
|
||||||
|
|
||||||
<ds-form [formId]="formId"
|
<ds-form [formId]="formId"
|
||||||
[formModel]="formModel"
|
[formModel]="formModel"
|
||||||
[formGroup]="formGroup"
|
[formGroup]="formGroup"
|
||||||
[formLayout]="formLayout"
|
[formLayout]="formLayout"
|
||||||
(cancel)="onCancel()"
|
[displayCancel]="false"
|
||||||
(submitForm)="onSubmit()">
|
(submitForm)="onSubmit()">
|
||||||
<div *ngIf="groupBeingEdited != null" class="row">
|
<div before class="btn-group">
|
||||||
<button class="btn btn-light delete-button" [disabled]="!(canEdit$ | async) || groupBeingEdited.permanent"
|
<button (click)="onCancel()"
|
||||||
|
class="btn btn-outline-secondary"><i class="fas fa-arrow-left"></i> {{messagePrefix + '.return' | translate}}</button>
|
||||||
|
</div>
|
||||||
|
<div after *ngIf="groupBeingEdited != null" class="btn-group">
|
||||||
|
<button class="btn btn-danger delete-button" [disabled]="!(canEdit$ | async) || groupBeingEdited.permanent"
|
||||||
(click)="delete()">
|
(click)="delete()">
|
||||||
<i class="fa fa-trash"></i> {{ messagePrefix + '.actions.delete' | translate}}
|
<i class="fa fa-trash"></i> {{ messagePrefix + '.actions.delete' | translate}}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</ds-form>
|
</ds-form>
|
||||||
|
|
||||||
<ds-members-list *ngIf="groupBeingEdited != null"
|
<div class="mb-5">
|
||||||
[messagePrefix]="messagePrefix + '.members-list'"></ds-members-list>
|
<ds-members-list *ngIf="groupBeingEdited != null"
|
||||||
|
[messagePrefix]="messagePrefix + '.members-list'"></ds-members-list>
|
||||||
|
</div>
|
||||||
<ds-subgroups-list *ngIf="groupBeingEdited != null"
|
<ds-subgroups-list *ngIf="groupBeingEdited != null"
|
||||||
[messagePrefix]="messagePrefix + '.subgroups-list'"></ds-subgroups-list>
|
[messagePrefix]="messagePrefix + '.subgroups-list'"></ds-subgroups-list>
|
||||||
|
|
||||||
<div>
|
|
||||||
<button [routerLink]="[this.groupDataService.getGroupRegistryRouterLink()]"
|
|
||||||
class="btn btn-primary">{{messagePrefix + '.return' | translate}}</button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -368,6 +368,8 @@ export class GroupFormComponent implements OnInit, OnDestroy {
|
|||||||
modalRef.componentInstance.infoLabel = this.messagePrefix + '.delete-group.modal.info';
|
modalRef.componentInstance.infoLabel = this.messagePrefix + '.delete-group.modal.info';
|
||||||
modalRef.componentInstance.cancelLabel = this.messagePrefix + '.delete-group.modal.cancel';
|
modalRef.componentInstance.cancelLabel = this.messagePrefix + '.delete-group.modal.cancel';
|
||||||
modalRef.componentInstance.confirmLabel = this.messagePrefix + '.delete-group.modal.confirm';
|
modalRef.componentInstance.confirmLabel = this.messagePrefix + '.delete-group.modal.confirm';
|
||||||
|
modalRef.componentInstance.brandColor = 'danger';
|
||||||
|
modalRef.componentInstance.confirmIcon = 'fas fa-trash';
|
||||||
modalRef.componentInstance.response.pipe(take(1)).subscribe((confirm: boolean) => {
|
modalRef.componentInstance.response.pipe(take(1)).subscribe((confirm: boolean) => {
|
||||||
if (confirm) {
|
if (confirm) {
|
||||||
if (hasValue(group.id)) {
|
if (hasValue(group.id)) {
|
||||||
|
@@ -2,26 +2,29 @@
|
|||||||
<h3 class="border-bottom pb-2">{{messagePrefix + '.head' | translate}}</h3>
|
<h3 class="border-bottom pb-2">{{messagePrefix + '.head' | translate}}</h3>
|
||||||
|
|
||||||
<h4 id="search" class="border-bottom pb-2">{{messagePrefix + '.search.head' | translate}}
|
<h4 id="search" class="border-bottom pb-2">{{messagePrefix + '.search.head' | translate}}
|
||||||
<button (click)="clearFormAndResetResult();"
|
|
||||||
class="btn btn-primary float-right">{{messagePrefix + '.button.see-all' | translate}}</button>
|
|
||||||
</h4>
|
</h4>
|
||||||
<form [formGroup]="searchForm" (ngSubmit)="search(searchForm.value)" class="row">
|
<form [formGroup]="searchForm" (ngSubmit)="search(searchForm.value)" class="d-flex justify-content-between">
|
||||||
<div class="col-12 col-sm-3">
|
<div>
|
||||||
<select name="scope" id="scope" formControlName="scope" class="form-control" aria-label="Search scope">
|
<select name="scope" id="scope" formControlName="scope" class="form-control" aria-label="Search scope">
|
||||||
<option value="metadata">{{messagePrefix + '.search.scope.metadata' | translate}}</option>
|
<option value="metadata">{{messagePrefix + '.search.scope.metadata' | translate}}</option>
|
||||||
<option value="email">{{messagePrefix + '.search.scope.email' | translate}}</option>
|
<option value="email">{{messagePrefix + '.search.scope.email' | translate}}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-9 col-12">
|
<div class="flex-grow-1 mr-3 ml-3">
|
||||||
<div class="form-group input-group">
|
<div class="form-group input-group">
|
||||||
<input type="text" name="query" id="query" formControlName="query"
|
<input type="text" name="query" id="query" formControlName="query"
|
||||||
class="form-control" aria-label="Search input">
|
class="form-control" aria-label="Search input">
|
||||||
<span class="input-group-append">
|
<span class="input-group-append">
|
||||||
<button type="submit"
|
<button type="submit" class="search-button btn btn-primary">
|
||||||
class="search-button btn btn-secondary">{{ messagePrefix + '.search.button' | translate }}</button>
|
<i class="fas fa-search"></i> {{ messagePrefix + '.search.button' | translate }}</button>
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<button (click)="clearFormAndResetResult();"
|
||||||
|
class="btn btn-secondary">{{messagePrefix + '.button.see-all' | translate}}</button>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<ds-pagination *ngIf="(ePeopleSearchDtos | async)?.totalElements > 0"
|
<ds-pagination *ngIf="(ePeopleSearchDtos | async)?.totalElements > 0"
|
||||||
|
@@ -2,20 +2,26 @@
|
|||||||
<h3 class="border-bottom pb-2">{{messagePrefix + '.head' | translate}}</h3>
|
<h3 class="border-bottom pb-2">{{messagePrefix + '.head' | translate}}</h3>
|
||||||
|
|
||||||
<h4 id="search" class="border-bottom pb-2">{{messagePrefix + '.search.head' | translate}}
|
<h4 id="search" class="border-bottom pb-2">{{messagePrefix + '.search.head' | translate}}
|
||||||
<button (click)="clearFormAndResetResult();"
|
|
||||||
class="btn btn-primary float-right">{{messagePrefix + '.button.see-all' | translate}}</button>
|
|
||||||
</h4>
|
</h4>
|
||||||
<form [formGroup]="searchForm" (ngSubmit)="search(searchForm.value)" class="row">
|
<form [formGroup]="searchForm" (ngSubmit)="search(searchForm.value)" class="d-flex justify-content-between">
|
||||||
<div class="col-12">
|
<div class="flex-grow-1 mr-3">
|
||||||
<div class="form-group input-group">
|
<div class="form-group input-group mr-3">
|
||||||
<input type="text" name="query" id="query" formControlName="query"
|
<input type="text" name="query" id="query" formControlName="query"
|
||||||
class="form-control" aria-label="Search input">
|
class="form-control" aria-label="Search input">
|
||||||
<span class="input-group-append">
|
<span class="input-group-append">
|
||||||
<button type="submit"
|
<button type="submit" class="search-button btn btn-primary">
|
||||||
class="search-button btn btn-secondary">{{ messagePrefix + '.search.button' | translate }}</button>
|
<i class="fas fa-search"></i> {{ messagePrefix + '.search.button' | translate }}
|
||||||
|
</button>
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<button (click)="clearFormAndResetResult();" class="btn btn-secondary float-right">
|
||||||
|
{{messagePrefix + '.button.see-all' | translate}}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<ds-pagination *ngIf="(searchResults$ | async)?.payload?.totalElements > 0"
|
<ds-pagination *ngIf="(searchResults$ | async)?.payload?.totalElements > 0"
|
||||||
|
@@ -1,36 +1,41 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="groups-registry row">
|
<div class="groups-registry row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
|
<div class="d-flex justify-content-between border-bottom mb-3">
|
||||||
<h2 id="header" class="border-bottom pb-2">{{messagePrefix + 'head' | translate}}</h2>
|
<h2 id="header" class="pb-2">{{messagePrefix + 'head' | translate}}</h2>
|
||||||
|
<div>
|
||||||
<div class="button-row top d-flex pb-2">
|
<button class="mr-auto btn btn-success"
|
||||||
<button class="mr-auto btn btn-success"
|
[routerLink]="['newGroup']">
|
||||||
[routerLink]="['newGroup']">
|
<i class="fas fa-plus"></i>
|
||||||
<i class="fas fa-plus"></i>
|
<span class="d-none d-sm-inline">{{messagePrefix + 'button.add' | translate}}</span>
|
||||||
<span class="d-none d-sm-inline">{{messagePrefix + 'button.add' | translate}}</span>
|
</button>
|
||||||
</button>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h3 id="search" class="border-bottom pb-2">{{messagePrefix + 'search.head' | translate}}
|
<h3 id="search" class="border-bottom pb-2">{{messagePrefix + 'search.head' | translate}}</h3>
|
||||||
<button (click)="clearFormAndResetResult();"
|
<form [formGroup]="searchForm" (ngSubmit)="search(searchForm.value)" class="d-flex justify-content-between">
|
||||||
class="btn btn-primary float-right">{{messagePrefix + 'button.see-all' | translate}}</button>
|
<div class="flex-grow-1 mr-3">
|
||||||
</h3>
|
|
||||||
<form [formGroup]="searchForm" (ngSubmit)="search(searchForm.value)" class="row">
|
|
||||||
<div class="col-12">
|
|
||||||
<div class="form-group input-group">
|
<div class="form-group input-group">
|
||||||
<input type="text" name="query" id="query" formControlName="query"
|
<input type="text" name="query" id="query" formControlName="query"
|
||||||
class="form-control" aria-label="Search input">
|
class="form-control" attr.aria-label="{{messagePrefix + 'search.placeholder' | translate}}"
|
||||||
|
[placeholder]="(messagePrefix + 'search.placeholder' | translate)" >
|
||||||
<span class="input-group-append">
|
<span class="input-group-append">
|
||||||
<button type="submit"
|
<button type="submit" class="search-button btn btn-primary">
|
||||||
class="search-button btn btn-secondary">{{ messagePrefix + 'search.button' | translate }}</button>
|
<i class="fas fa-search"></i> {{ messagePrefix + 'search.button' | translate }}
|
||||||
</span>
|
</button>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div>
|
||||||
|
<button (click)="clearFormAndResetResult();" class="btn btn-secondary">
|
||||||
|
{{messagePrefix + 'button.see-all' | translate}}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<ds-loading *ngIf="searching$ | async"></ds-loading>
|
||||||
<ds-pagination
|
<ds-pagination
|
||||||
*ngIf="(pageInfoState$ | async)?.totalElements > 0"
|
*ngIf="(pageInfoState$ | async)?.totalElements > 0 && !(searching$ | async)"
|
||||||
[paginationOptions]="config"
|
[paginationOptions]="config"
|
||||||
[pageInfoState]="pageInfoState$"
|
[pageInfoState]="pageInfoState$"
|
||||||
[collectionSize]="(pageInfoState$ | async)?.totalElements"
|
[collectionSize]="(pageInfoState$ | async)?.totalElements"
|
||||||
@@ -38,7 +43,7 @@
|
|||||||
[hidePagerWhenSinglePage]="true"
|
[hidePagerWhenSinglePage]="true"
|
||||||
(pageChange)="onPageChange($event)">
|
(pageChange)="onPageChange($event)">
|
||||||
|
|
||||||
<div class="table-responsive">
|
<div class="table-responsive">
|
||||||
<table id="groups" class="table table-striped table-hover table-bordered">
|
<table id="groups" class="table table-striped table-hover table-bordered">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@@ -70,6 +70,11 @@ export class GroupsRegistryComponent implements OnInit, OnDestroy {
|
|||||||
// The search form
|
// The search form
|
||||||
searchForm;
|
searchForm;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean representing if a search is pending
|
||||||
|
*/
|
||||||
|
searching$: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
||||||
|
|
||||||
// Current search in groups registry
|
// Current search in groups registry
|
||||||
currentSearchQuery: string;
|
currentSearchQuery: string;
|
||||||
|
|
||||||
@@ -117,6 +122,7 @@ export class GroupsRegistryComponent implements OnInit, OnDestroy {
|
|||||||
* @param data Contains query param
|
* @param data Contains query param
|
||||||
*/
|
*/
|
||||||
search(data: any) {
|
search(data: any) {
|
||||||
|
this.searching$.next(true);
|
||||||
const query: string = data.query;
|
const query: string = data.query;
|
||||||
if (query != null && this.currentSearchQuery !== query) {
|
if (query != null && this.currentSearchQuery !== query) {
|
||||||
this.router.navigateByUrl(this.groupService.getGroupRegistryRouterLink());
|
this.router.navigateByUrl(this.groupService.getGroupRegistryRouterLink());
|
||||||
@@ -163,6 +169,7 @@ export class GroupsRegistryComponent implements OnInit, OnDestroy {
|
|||||||
})).subscribe((value: PaginatedList<GroupDtoModel>) => {
|
})).subscribe((value: PaginatedList<GroupDtoModel>) => {
|
||||||
this.groupsDto$.next(value);
|
this.groupsDto$.next(value);
|
||||||
this.pageInfoState$.next(value.pageInfo);
|
this.pageInfoState$.next(value.pageInfo);
|
||||||
|
this.searching$.next(false);
|
||||||
});
|
});
|
||||||
this.subs.push(this.searchSub);
|
this.subs.push(this.searchSub);
|
||||||
}
|
}
|
||||||
|
@@ -15,14 +15,11 @@ import { AdminSidebarSectionComponent } from './+admin/admin-sidebar/admin-sideb
|
|||||||
import { AdminSidebarComponent } from './+admin/admin-sidebar/admin-sidebar.component';
|
import { AdminSidebarComponent } from './+admin/admin-sidebar/admin-sidebar.component';
|
||||||
import { ExpandableAdminSidebarSectionComponent } from './+admin/admin-sidebar/expandable-admin-sidebar-section/expandable-admin-sidebar-section.component';
|
import { ExpandableAdminSidebarSectionComponent } from './+admin/admin-sidebar/expandable-admin-sidebar-section/expandable-admin-sidebar-section.component';
|
||||||
import { AppRoutingModule } from './app-routing.module';
|
import { AppRoutingModule } from './app-routing.module';
|
||||||
|
|
||||||
import { AppComponent } from './app.component';
|
import { AppComponent } from './app.component';
|
||||||
|
|
||||||
import { appEffects } from './app.effects';
|
import { appEffects } from './app.effects';
|
||||||
import { appMetaReducers, debugMetaReducers } from './app.metareducers';
|
import { appMetaReducers, debugMetaReducers } from './app.metareducers';
|
||||||
import { appReducers, AppState, storeModuleConfig } from './app.reducer';
|
import { appReducers, AppState, storeModuleConfig } from './app.reducer';
|
||||||
import { CheckAuthenticationTokenAction } from './core/auth/auth.actions';
|
import { CheckAuthenticationTokenAction } from './core/auth/auth.actions';
|
||||||
|
|
||||||
import { CoreModule } from './core/core.module';
|
import { CoreModule } from './core/core.module';
|
||||||
import { ClientCookieService } from './core/services/client-cookie.service';
|
import { ClientCookieService } from './core/services/client-cookie.service';
|
||||||
import { FooterComponent } from './footer/footer.component';
|
import { FooterComponent } from './footer/footer.component';
|
||||||
@@ -30,8 +27,6 @@ import { HeaderNavbarWrapperComponent } from './header-nav-wrapper/header-navbar
|
|||||||
import { HeaderComponent } from './header/header.component';
|
import { HeaderComponent } from './header/header.component';
|
||||||
import { NavbarModule } from './navbar/navbar.module';
|
import { NavbarModule } from './navbar/navbar.module';
|
||||||
import { PageNotFoundComponent } from './pagenotfound/pagenotfound.component';
|
import { PageNotFoundComponent } from './pagenotfound/pagenotfound.component';
|
||||||
import { SearchNavbarComponent } from './search-navbar/search-navbar.component';
|
|
||||||
|
|
||||||
import { DSpaceRouterStateSerializer } from './shared/ngrx/dspace-router-state-serializer';
|
import { DSpaceRouterStateSerializer } from './shared/ngrx/dspace-router-state-serializer';
|
||||||
import { NotificationComponent } from './shared/notifications/notification/notification.component';
|
import { NotificationComponent } from './shared/notifications/notification/notification.component';
|
||||||
import { NotificationsBoardComponent } from './shared/notifications/notifications-board/notifications-board.component';
|
import { NotificationsBoardComponent } from './shared/notifications/notifications-board/notifications-board.component';
|
||||||
@@ -143,7 +138,6 @@ const DECLARATIONS = [
|
|||||||
ThemedPageNotFoundComponent,
|
ThemedPageNotFoundComponent,
|
||||||
NotificationComponent,
|
NotificationComponent,
|
||||||
NotificationsBoardComponent,
|
NotificationsBoardComponent,
|
||||||
SearchNavbarComponent,
|
|
||||||
BreadcrumbsComponent,
|
BreadcrumbsComponent,
|
||||||
ThemedBreadcrumbsComponent,
|
ThemedBreadcrumbsComponent,
|
||||||
ForbiddenComponent,
|
ForbiddenComponent,
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
<ng-container *ngVar="(breadcrumbs$ | async) as breadcrumbs">
|
<ng-container *ngVar="(breadcrumbs$ | async) as breadcrumbs">
|
||||||
<nav *ngIf="(showBreadcrumbs$ | async)" aria-label="breadcrumb">
|
<nav *ngIf="(showBreadcrumbs$ | async)" aria-label="breadcrumb" class="nav-breadcrumb">
|
||||||
<ol class="breadcrumb">
|
<ol class="container breadcrumb">
|
||||||
<ng-container
|
<ng-container
|
||||||
*ngTemplateOutlet="breadcrumbs?.length > 0 ? breadcrumb : activeBreadcrumb; context: {text: 'home.breadcrumbs', url: '/'}"></ng-container>
|
*ngTemplateOutlet="breadcrumbs?.length > 0 ? breadcrumb : activeBreadcrumb; context: {text: 'home.breadcrumbs', url: '/'}"></ng-container>
|
||||||
<ng-container *ngFor="let bc of breadcrumbs; let last = last;">
|
<ng-container *ngFor="let bc of breadcrumbs; let last = last;">
|
||||||
|
@@ -0,0 +1,22 @@
|
|||||||
|
.nav-breadcrumb {
|
||||||
|
background-color: var(--ds-breadcrumb-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb {
|
||||||
|
border-radius: 0;
|
||||||
|
margin-top: calc(-1 * var(--ds-content-spacing));
|
||||||
|
padding-bottom: var(--ds-content-spacing / 3);
|
||||||
|
padding-top: var(--ds-content-spacing / 3);
|
||||||
|
background-color: var(--ds-breadcrumb-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
li.breadcrumb-item > a {
|
||||||
|
color: var(--ds-breadcrumb-link-color) !important;
|
||||||
|
}
|
||||||
|
li.breadcrumb-item.active {
|
||||||
|
color: var(--ds-breadcrumb-link-active-color) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb-item+ .breadcrumb-item::before {
|
||||||
|
content: quote("•") !important;
|
||||||
|
}
|
||||||
|
@@ -4,6 +4,7 @@ import { CdkTreeModule } from '@angular/cdk/tree';
|
|||||||
|
|
||||||
import { CommunityListService } from './community-list-service';
|
import { CommunityListService } from './community-list-service';
|
||||||
import { ThemedCommunityListPageComponent } from './themed-community-list-page.component';
|
import { ThemedCommunityListPageComponent } from './themed-community-list-page.component';
|
||||||
|
import { I18nBreadcrumbResolver } from '../core/breadcrumbs/i18n-breadcrumb.resolver';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* RouterModule to help navigate to the page with the community list tree
|
* RouterModule to help navigate to the page with the community list tree
|
||||||
@@ -15,7 +16,10 @@ import { ThemedCommunityListPageComponent } from './themed-community-list-page.c
|
|||||||
path: '',
|
path: '',
|
||||||
component: ThemedCommunityListPageComponent,
|
component: ThemedCommunityListPageComponent,
|
||||||
pathMatch: 'full',
|
pathMatch: 'full',
|
||||||
data: { title: 'communityList.tabTitle' }
|
resolve: {
|
||||||
|
breadcrumb: I18nBreadcrumbResolver
|
||||||
|
},
|
||||||
|
data: { title: 'communityList.tabTitle', breadcrumbKey: 'communityList' }
|
||||||
}
|
}
|
||||||
]),
|
]),
|
||||||
CdkTreeModule,
|
CdkTreeModule,
|
||||||
|
@@ -9,8 +9,8 @@
|
|||||||
</button>
|
</button>
|
||||||
<div class="align-middle pt-2">
|
<div class="align-middle pt-2">
|
||||||
<a *ngIf="node!==loadingNode" [routerLink]="" (click)="getNextPage(node)"
|
<a *ngIf="node!==loadingNode" [routerLink]="" (click)="getNextPage(node)"
|
||||||
class="btn btn-outline-secondary btn-sm">
|
class="btn btn-outline-primary btn-sm" role="button">
|
||||||
{{ 'communityList.showMore' | translate }}
|
<i class="fas fa-angle-down"></i> {{ 'communityList.showMore' | translate }}
|
||||||
</a>
|
</a>
|
||||||
<ds-loading *ngIf="node===loadingNode && dataSource.loading$ | async" class="ds-loading"></ds-loading>
|
<ds-loading *ngIf="node===loadingNode && dataSource.loading$ | async" class="ds-loading"></ds-loading>
|
||||||
</div>
|
</div>
|
||||||
@@ -25,6 +25,7 @@
|
|||||||
class="example-tree-node expandable-node">
|
class="example-tree-node expandable-node">
|
||||||
<div class="btn-group">
|
<div class="btn-group">
|
||||||
<button type="button" class="btn btn-default" cdkTreeNodeToggle
|
<button type="button" class="btn btn-default" cdkTreeNodeToggle
|
||||||
|
[title]="'toggle ' + node.name"
|
||||||
[attr.aria-label]="'toggle ' + node.name"
|
[attr.aria-label]="'toggle ' + node.name"
|
||||||
(click)="toggleExpanded(node)"
|
(click)="toggleExpanded(node)"
|
||||||
[ngClass]="(hasChild(null, node)| async) ? 'visible' : 'invisible'">
|
[ngClass]="(hasChild(null, node)| async) ? 'visible' : 'invisible'">
|
||||||
|
@@ -120,7 +120,7 @@ describe('DsoRedirectDataService', () => {
|
|||||||
it('should navigate to entities route with the corresponding entity type', () => {
|
it('should navigate to entities route with the corresponding entity type', () => {
|
||||||
remoteData.payload.type = 'item';
|
remoteData.payload.type = 'item';
|
||||||
remoteData.payload.metadata = {
|
remoteData.payload.metadata = {
|
||||||
'relationship.type': [
|
'dspace.entity.type': [
|
||||||
{
|
{
|
||||||
language: 'en_US',
|
language: 'en_US',
|
||||||
value: 'Publication'
|
value: 'Publication'
|
||||||
|
@@ -8,6 +8,8 @@ import { TranslateLoaderMock } from '../../shared/mocks/translate-loader.mock';
|
|||||||
import { LANG_COOKIE, LANG_ORIGIN, LocaleService } from './locale.service';
|
import { LANG_COOKIE, LANG_ORIGIN, LocaleService } from './locale.service';
|
||||||
import { AuthService } from '../auth/auth.service';
|
import { AuthService } from '../auth/auth.service';
|
||||||
import { NativeWindowRef } from '../services/window.service';
|
import { NativeWindowRef } from '../services/window.service';
|
||||||
|
import { RouteService } from '../services/route.service';
|
||||||
|
import { routeServiceStub } from '../../shared/testing/route-service.stub';
|
||||||
|
|
||||||
describe('LocaleService test suite', () => {
|
describe('LocaleService test suite', () => {
|
||||||
let service: LocaleService;
|
let service: LocaleService;
|
||||||
@@ -18,6 +20,7 @@ describe('LocaleService test suite', () => {
|
|||||||
let spyOnGet;
|
let spyOnGet;
|
||||||
let spyOnSet;
|
let spyOnSet;
|
||||||
let authService;
|
let authService;
|
||||||
|
let routeService;
|
||||||
|
|
||||||
authService = jasmine.createSpyObj('AuthService', {
|
authService = jasmine.createSpyObj('AuthService', {
|
||||||
isAuthenticated: jasmine.createSpy('isAuthenticated'),
|
isAuthenticated: jasmine.createSpy('isAuthenticated'),
|
||||||
@@ -38,7 +41,8 @@ describe('LocaleService test suite', () => {
|
|||||||
],
|
],
|
||||||
providers: [
|
providers: [
|
||||||
{ provide: CookieService, useValue: new CookieServiceMock() },
|
{ provide: CookieService, useValue: new CookieServiceMock() },
|
||||||
{ provide: AuthService, userValue: authService }
|
{ provide: AuthService, userValue: authService },
|
||||||
|
{ provide: RouteService, useValue: routeServiceStub },
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
@@ -46,8 +50,9 @@ describe('LocaleService test suite', () => {
|
|||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
cookieService = TestBed.inject(CookieService);
|
cookieService = TestBed.inject(CookieService);
|
||||||
translateService = TestBed.inject(TranslateService);
|
translateService = TestBed.inject(TranslateService);
|
||||||
|
routeService = TestBed.inject(RouteService);
|
||||||
window = new NativeWindowRef();
|
window = new NativeWindowRef();
|
||||||
service = new LocaleService(window, cookieService, translateService, authService);
|
service = new LocaleService(window, cookieService, translateService, authService, routeService);
|
||||||
serviceAsAny = service;
|
serviceAsAny = service;
|
||||||
spyOnGet = spyOn(cookieService, 'get');
|
spyOnGet = spyOn(cookieService, 'get');
|
||||||
spyOnSet = spyOn(cookieService, 'set');
|
spyOnSet = spyOn(cookieService, 'set');
|
||||||
|
@@ -9,6 +9,7 @@ import { AuthService } from '../auth/auth.service';
|
|||||||
import { combineLatest, Observable, of as observableOf } from 'rxjs';
|
import { combineLatest, Observable, of as observableOf } from 'rxjs';
|
||||||
import { map, mergeMap, take } from 'rxjs/operators';
|
import { map, mergeMap, take } from 'rxjs/operators';
|
||||||
import { NativeWindowRef, NativeWindowService } from '../services/window.service';
|
import { NativeWindowRef, NativeWindowService } from '../services/window.service';
|
||||||
|
import { RouteService } from '../services/route.service';
|
||||||
|
|
||||||
export const LANG_COOKIE = 'dsLanguage';
|
export const LANG_COOKIE = 'dsLanguage';
|
||||||
|
|
||||||
@@ -36,7 +37,8 @@ export class LocaleService {
|
|||||||
@Inject(NativeWindowService) protected _window: NativeWindowRef,
|
@Inject(NativeWindowService) protected _window: NativeWindowRef,
|
||||||
protected cookie: CookieService,
|
protected cookie: CookieService,
|
||||||
protected translate: TranslateService,
|
protected translate: TranslateService,
|
||||||
protected authService: AuthService) {
|
protected authService: AuthService,
|
||||||
|
protected routeService: RouteService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -183,9 +185,12 @@ export class LocaleService {
|
|||||||
* Refresh route navigated
|
* Refresh route navigated
|
||||||
*/
|
*/
|
||||||
public refreshAfterChangeLanguage() {
|
public refreshAfterChangeLanguage() {
|
||||||
// Hard redirect to the reload page with a unique number behind it
|
this.routeService.getCurrentUrl().pipe(take(1)).subscribe((currentURL) => {
|
||||||
// so that all state is definitely lost
|
// Hard redirect to the reload page with a unique number behind it
|
||||||
this._window.nativeWindow.location.href = `/reload/${new Date().getTime()}`;
|
// so that all state is definitely lost
|
||||||
|
this._window.nativeWindow.location.href = `/reload/${new Date().getTime()}?redirect=` + encodeURIComponent(currentURL);
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -8,8 +8,8 @@ import { RouterTestingModule } from '@angular/router/testing';
|
|||||||
|
|
||||||
import { Store, StoreModule } from '@ngrx/store';
|
import { Store, StoreModule } from '@ngrx/store';
|
||||||
|
|
||||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
import { TranslateLoader, TranslateModule, TranslateService } from '@ngx-translate/core';
|
||||||
import { EmptyError, Observable } from 'rxjs';
|
import { EmptyError, Observable, of } from 'rxjs';
|
||||||
|
|
||||||
import { RemoteData } from '../data/remote-data';
|
import { RemoteData } from '../data/remote-data';
|
||||||
import { Item } from '../shared/item.model';
|
import { Item } from '../shared/item.model';
|
||||||
@@ -94,6 +94,7 @@ describe('MetadataService', () => {
|
|||||||
let itemDataService: ItemDataService;
|
let itemDataService: ItemDataService;
|
||||||
let authService: AuthService;
|
let authService: AuthService;
|
||||||
let rootService: RootDataService;
|
let rootService: RootDataService;
|
||||||
|
let translateService: TranslateService;
|
||||||
|
|
||||||
let location: Location;
|
let location: Location;
|
||||||
let router: Router;
|
let router: Router;
|
||||||
@@ -195,6 +196,7 @@ describe('MetadataService', () => {
|
|||||||
itemDataService = TestBed.inject(ItemDataService);
|
itemDataService = TestBed.inject(ItemDataService);
|
||||||
metadataService = TestBed.inject(MetadataService);
|
metadataService = TestBed.inject(MetadataService);
|
||||||
authService = TestBed.inject(AuthService);
|
authService = TestBed.inject(AuthService);
|
||||||
|
translateService = TestBed.inject(TranslateService);
|
||||||
|
|
||||||
router = TestBed.inject(Router);
|
router = TestBed.inject(Router);
|
||||||
location = TestBed.inject(Location);
|
location = TestBed.inject(Location);
|
||||||
@@ -236,14 +238,15 @@ describe('MetadataService', () => {
|
|||||||
|
|
||||||
it('other navigation should add title, description and Generator', fakeAsync(() => {
|
it('other navigation should add title, description and Generator', fakeAsync(() => {
|
||||||
spyOn(itemDataService, 'findById').and.returnValue(mockRemoteData(ItemMock));
|
spyOn(itemDataService, 'findById').and.returnValue(mockRemoteData(ItemMock));
|
||||||
|
spyOn(translateService, 'get').and.returnValues(of('DSpace :: '), of('Dummy Title'), of('This is a dummy item component for testing!'));
|
||||||
router.navigate(['/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357']);
|
router.navigate(['/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357']);
|
||||||
tick();
|
tick();
|
||||||
expect(tagStore.size).toBeGreaterThan(0);
|
expect(tagStore.size).toBeGreaterThan(0);
|
||||||
router.navigate(['/other']);
|
router.navigate(['/other']);
|
||||||
tick();
|
tick();
|
||||||
expect(tagStore.size).toEqual(3);
|
expect(tagStore.size).toEqual(3);
|
||||||
expect(title.getTitle()).toEqual('Dummy Title');
|
expect(title.getTitle()).toEqual('DSpace :: Dummy Title');
|
||||||
expect(tagStore.get('title')[0].content).toEqual('Dummy Title');
|
expect(tagStore.get('title')[0].content).toEqual('DSpace :: Dummy Title');
|
||||||
expect(tagStore.get('description')[0].content).toEqual('This is a dummy item component for testing!');
|
expect(tagStore.get('description')[0].content).toEqual('This is a dummy item component for testing!');
|
||||||
expect(tagStore.get('Generator')[0].content).toEqual('mock-dspace-version');
|
expect(tagStore.get('Generator')[0].content).toEqual('mock-dspace-version');
|
||||||
}));
|
}));
|
||||||
|
@@ -5,7 +5,7 @@ import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
|
|||||||
|
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
|
||||||
import { BehaviorSubject, Observable } from 'rxjs';
|
import { BehaviorSubject, combineLatest, Observable } from 'rxjs';
|
||||||
import { catchError, distinctUntilKeyChanged, filter, first, map, take } from 'rxjs/operators';
|
import { catchError, distinctUntilKeyChanged, filter, first, map, take } from 'rxjs/operators';
|
||||||
|
|
||||||
import { hasValue, isNotEmpty } from '../../shared/empty.util';
|
import { hasValue, isNotEmpty } from '../../shared/empty.util';
|
||||||
@@ -83,9 +83,11 @@ export class MetadataService {
|
|||||||
this.clearMetaTags();
|
this.clearMetaTags();
|
||||||
}
|
}
|
||||||
if (routeInfo.data.value.title) {
|
if (routeInfo.data.value.title) {
|
||||||
this.translate.get(routeInfo.data.value.title, routeInfo.data.value).pipe(take(1)).subscribe((translatedTitle: string) => {
|
const titlePrefix = this.translate.get('repository.title.prefix');
|
||||||
this.addMetaTag('title', translatedTitle);
|
const title = this.translate.get(routeInfo.data.value.title, routeInfo.data.value);
|
||||||
this.title.setTitle(translatedTitle);
|
combineLatest([titlePrefix, title]).pipe(take(1)).subscribe(([translatedTitlePrefix, translatedTitle]: [string, string]) => {
|
||||||
|
this.addMetaTag('title', translatedTitlePrefix + translatedTitle);
|
||||||
|
this.title.setTitle(translatedTitlePrefix + translatedTitle);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (routeInfo.data.value.description) {
|
if (routeInfo.data.value.description) {
|
||||||
|
@@ -153,4 +153,32 @@ describe('RouteService', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('getCurrentUrl', () => {
|
||||||
|
it('should return an observable with the current url', () => {
|
||||||
|
serviceAsAny.store = observableOf({
|
||||||
|
core: {
|
||||||
|
history: ['url', 'newurl']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
service.getCurrentUrl().subscribe((history) => {
|
||||||
|
expect(history).toEqual('newurl');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('getCurrentUrl', () => {
|
||||||
|
it('should return an observable with the previous url', () => {
|
||||||
|
serviceAsAny.store = observableOf({
|
||||||
|
core: {
|
||||||
|
history: ['url', 'newurl']
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
service.getPreviousUrl().subscribe((history) => {
|
||||||
|
expect(history).toEqual('url');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@@ -172,6 +172,18 @@ export class RouteService {
|
|||||||
return this.store.pipe(select(historySelector));
|
return this.store.pipe(select(historySelector));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the current url retrieved from history
|
||||||
|
*/
|
||||||
|
public getCurrentUrl(): Observable<string> {
|
||||||
|
return this.getHistory().pipe(
|
||||||
|
map((history: string[]) => history[history.length - 1] || '')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the current url retrieved from history
|
||||||
|
*/
|
||||||
public getPreviousUrl(): Observable<string> {
|
public getPreviousUrl(): Observable<string> {
|
||||||
return this.getHistory().pipe(
|
return this.getHistory().pipe(
|
||||||
map((history: string[]) => history[history.length - 2] || '')
|
map((history: string[]) => history[history.length - 2] || '')
|
||||||
|
@@ -104,7 +104,7 @@ export class Item extends DSpaceObject implements ChildHALResource {
|
|||||||
* Method that returns as which type of object this object should be rendered
|
* Method that returns as which type of object this object should be rendered
|
||||||
*/
|
*/
|
||||||
getRenderTypes(): (string | GenericConstructor<ListableObject>)[] {
|
getRenderTypes(): (string | GenericConstructor<ListableObject>)[] {
|
||||||
const entityType = this.firstMetadataValue('relationship.type');
|
const entityType = this.firstMetadataValue('dspace.entity.type');
|
||||||
if (isEmpty(entityType)) {
|
if (isEmpty(entityType)) {
|
||||||
return super.getRenderTypes();
|
return super.getRenderTypes();
|
||||||
}
|
}
|
||||||
|
@@ -24,7 +24,7 @@ describe('ItemMetadataRepresentation', () => {
|
|||||||
for (const metadataField of Object.keys(item.metadata)) {
|
for (const metadataField of Object.keys(item.metadata)) {
|
||||||
describe(`when creating an ItemMetadataRepresentation`, () => {
|
describe(`when creating an ItemMetadataRepresentation`, () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
item.metadata['relationship.type'] = [
|
item.metadata['dspace.entity.type'] = [
|
||||||
Object.assign(new MetadataValue(), {
|
Object.assign(new MetadataValue(), {
|
||||||
value: itemType
|
value: itemType
|
||||||
})
|
})
|
||||||
@@ -41,7 +41,7 @@ describe('ItemMetadataRepresentation', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should return the correct item type', () => {
|
it('should return the correct item type', () => {
|
||||||
expect(itemMetadataRepresentation.itemType).toEqual(item.firstMetadataValue('relationship.type'));
|
expect(itemMetadataRepresentation.itemType).toEqual(item.firstMetadataValue('dspace.entity.type'));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@@ -21,7 +21,7 @@ export class ItemMetadataRepresentation extends Item implements MetadataRepresen
|
|||||||
* The type of item this item can be represented as
|
* The type of item this item can be represented as
|
||||||
*/
|
*/
|
||||||
get itemType(): string {
|
get itemType(): string {
|
||||||
return this.firstMetadataValue('relationship.type');
|
return this.firstMetadataValue('dspace.entity.type');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -1,21 +1,75 @@
|
|||||||
<footer class="footer">
|
<footer class="top-footer text-lg-start">
|
||||||
<div class="container-fluid content-container-fluid">
|
<!-- Grid container -->
|
||||||
<img src="assets/images/dspace-logo.png"/>
|
<div *ngIf="showTopFooter" class="container p-4">
|
||||||
<p>
|
<!--Grid row-->
|
||||||
<a href="http://www.dspace.org/">{{ 'footer.link.dspace' | translate}}</a>
|
<div class="row">
|
||||||
{{ 'footer.copyright' | translate:{year: dateObj | date:'y'} }}
|
|
||||||
<a href="http://www.duraspace.org/">{{ 'footer.link.duraspace' | translate}}</a>
|
<!--Grid column-->
|
||||||
</p>
|
<div class="col-lg-4 col-md-6 mb-4 mb-lg-0">
|
||||||
<ul class="list-unstyled small d-flex justify-content-center mb-0 text-secondary">
|
<h5 class="text-uppercase">Footer Content</h5>
|
||||||
<li>
|
|
||||||
<a href="#" (click)="showCookieSettings()">{{ 'footer.link.cookies' | translate}}</a>
|
<ul class="list-unstyled mb-0">
|
||||||
</li>
|
<li>
|
||||||
<li>
|
<a routerLink="./" class="">Lorem ipsum</a>
|
||||||
<a routerLink="info/privacy">{{ 'footer.link.privacy-policy' | translate}}</a>
|
</li>
|
||||||
</li>
|
<li>
|
||||||
<li>
|
<a routerLink="./" class="">Ut facilisis</a>
|
||||||
<a routerLink="info/end-user-agreement">{{ 'footer.link.end-user-agreement' | translate}}</a>
|
</li>
|
||||||
</li>
|
<li>
|
||||||
|
<a routerLink="./" class="">Aenean sit</a>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
</div>
|
||||||
|
<!--Grid column-->
|
||||||
|
|
||||||
|
<!--Grid column-->
|
||||||
|
<div class="col-lg-4 col-md-6 mb-4 mb-lg-0">
|
||||||
|
<h5 class="text-uppercase">Footer Content</h5>
|
||||||
|
|
||||||
|
<ul class="list-unstyled mb-0">
|
||||||
|
<li>
|
||||||
|
<a routerLink="./" class="">Suspendisse potenti</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<!--Grid column-->
|
||||||
|
|
||||||
|
<!--Grid column-->
|
||||||
|
<div class="col-lg-4 col-md-12 mb-4 mb-md-0">
|
||||||
|
<h5 class="text-uppercase">Footer Content</h5>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Iste atque ea quis
|
||||||
|
molestias. Fugiat pariatur maxime quis culpa corporis vitae repudiandae aliquam
|
||||||
|
voluptatem veniam, est atque cumque eum delectus sint!
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<!--Grid column-->
|
||||||
</div>
|
</div>
|
||||||
|
<!--Grid row-->
|
||||||
|
</div>
|
||||||
|
<!-- Grid container -->
|
||||||
|
|
||||||
|
<!-- Copyright -->
|
||||||
|
<div class="footer p-1 d-flex justify-content-center align-items-center text-white">
|
||||||
|
<div class="content-container">
|
||||||
|
<p class="m-0">
|
||||||
|
<a class="text-white" href="http://www.dspace.org/">{{ 'footer.link.dspace' | translate}}</a>
|
||||||
|
{{ 'footer.copyright' | translate:{year: dateObj | date:'y'} }}
|
||||||
|
<a class="text-white" href="http://www.duraspace.org/">{{ 'footer.link.duraspace' | translate}}</a>
|
||||||
|
</p>
|
||||||
|
<ul class="footer-info list-unstyled small d-flex justify-content-center mb-0">
|
||||||
|
<li>
|
||||||
|
<a class="text-white" href="#" (click)="showCookieSettings()">{{ 'footer.link.cookies' | translate}}</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="text-white" routerLink="info/privacy">{{ 'footer.link.privacy-policy' | translate}}</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a class="text-white" routerLink="info/end-user-agreement">{{ 'footer.link.end-user-agreement' | translate}}</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- Copyright -->
|
||||||
</footer>
|
</footer>
|
||||||
|
@@ -1,42 +1,42 @@
|
|||||||
:host {
|
:host {
|
||||||
--ds-footer-bg: var(--bs-gray-100);
|
|
||||||
--ds-footer-border: 1px solid var(--bs-gray-300);
|
|
||||||
--ds-footer-padding: calc(var(--bs-spacer) * 1.5);
|
|
||||||
--ds-footer-logo-height: 55px;
|
|
||||||
|
|
||||||
.footer {
|
.top-footer {
|
||||||
background-color: var(--ds-footer-bg);
|
background-color: var(--ds-top-footer-bg);
|
||||||
border-top: var(--ds-footer-border);
|
border-top: var(--ds-footer-border);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: var(--ds-footer-padding);
|
padding: var(--ds-footer-padding);
|
||||||
padding-bottom: var(--bs-spacer);
|
z-index: var(--ds-footer-z-index);
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
div > img {
|
||||||
height: var(--ds-footer-logo-height);
|
height: var(--ds-footer-logo-height);
|
||||||
}
|
}
|
||||||
|
|
||||||
ul {
|
.footer {
|
||||||
padding-top: calc(var(--bs-spacer) * 0.5);
|
background-color: var(--ds-footer-bg);
|
||||||
|
|
||||||
li {
|
ul {
|
||||||
display: inline-flex;
|
li {
|
||||||
a {
|
display: inline-flex;
|
||||||
padding: 0 calc(var(--bs-spacer) / 2);
|
a {
|
||||||
color: inherit
|
padding: 0 calc(var(--bs-spacer) / 2);
|
||||||
}
|
color: inherit
|
||||||
|
|
||||||
&:not(:last-child) {
|
|
||||||
&:after {
|
|
||||||
content: '';
|
|
||||||
border-right: 1px var(--bs-secondary) solid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&:not(:last-child) {
|
||||||
|
&:after {
|
||||||
|
content: '';
|
||||||
|
border-right: 1px var(--bs-secondary) solid;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -10,6 +10,11 @@ import { KlaroService } from '../shared/cookies/klaro.service';
|
|||||||
export class FooterComponent {
|
export class FooterComponent {
|
||||||
dateObj: number = Date.now();
|
dateObj: number = Date.now();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean representing if to show or not the top footer container
|
||||||
|
*/
|
||||||
|
showTopFooter = false;
|
||||||
|
|
||||||
constructor(@Optional() private cookies: KlaroService) {
|
constructor(@Optional() private cookies: KlaroService) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,4 +1,3 @@
|
|||||||
<div [ngClass]="{'open': !(isNavBarCollapsed | async)}">
|
<div [ngClass]="{'open': !(isNavBarCollapsed | async)}">
|
||||||
<ds-themed-header></ds-themed-header>
|
<ds-themed-header></ds-themed-header>
|
||||||
<ds-themed-navbar></ds-themed-navbar>
|
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,11 +1,12 @@
|
|||||||
<header>
|
<header class="header">
|
||||||
<div class="container">
|
<nav role="navigation" [attr.aria-label]="'nav.user.description' |translate" class="container navbar navbar-expand-md px-0">
|
||||||
<a class="navbar-brand my-2" routerLink="/home">
|
<div class="d-flex flex-grow-1">
|
||||||
<img src="assets/images/dspace-logo.svg"/>
|
<a class="navbar-brand m-2" routerLink="/home">
|
||||||
</a>
|
<img src="assets/images/dspace-logo.svg" alt="logo"/>
|
||||||
|
</a>
|
||||||
<nav class="navbar navbar-light navbar-expand-md float-right px-0">
|
</div>
|
||||||
<ds-search-navbar></ds-search-navbar>
|
<div class="d-flex flex-grow-1 ml-auto justify-content-end align-items-center">
|
||||||
|
<ds-search-navbar class="navbar-search"></ds-search-navbar>
|
||||||
<ds-lang-switch></ds-lang-switch>
|
<ds-lang-switch></ds-lang-switch>
|
||||||
<ds-auth-nav-menu></ds-auth-nav-menu>
|
<ds-auth-nav-menu></ds-auth-nav-menu>
|
||||||
<ds-impersonate-navbar></ds-impersonate-navbar>
|
<ds-impersonate-navbar></ds-impersonate-navbar>
|
||||||
@@ -16,6 +17,8 @@
|
|||||||
<span class="navbar-toggler-icon fas fa-bars fa-fw" aria-hidden="true"></span>
|
<span class="navbar-toggler-icon fas fa-bars fa-fw" aria-hidden="true"></span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</div>
|
||||||
</div>
|
</nav>
|
||||||
|
<ds-themed-navbar></ds-themed-navbar>
|
||||||
|
|
||||||
</header>
|
</header>
|
||||||
|
@@ -1,21 +1,19 @@
|
|||||||
|
@media screen and (min-width: map-get($grid-breakpoints, md)) {
|
||||||
|
nav.navbar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.header {
|
||||||
|
background-color: var(--ds-header-bg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.navbar-brand img {
|
.navbar-brand img {
|
||||||
height: var(--ds-header-logo-height);
|
@media screen and (max-width: map-get($grid-breakpoints, md)) {
|
||||||
@media screen and (max-width: map-get($grid-breakpoints, sm)) {
|
|
||||||
height: var(--ds-header-logo-height-xs);
|
height: var(--ds-header-logo-height-xs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.navbar-toggler .navbar-toggler-icon {
|
.navbar-toggler .navbar-toggler-icon {
|
||||||
background-image: none !important;
|
background-image: none !important;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
|
color: var(--bs-link-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.navbar ::ng-deep {
|
|
||||||
a {
|
|
||||||
color: var(--ds-header-icon-color);
|
|
||||||
|
|
||||||
&:hover, &focus {
|
|
||||||
color: var(--ds-header-icon-color-hover);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
<li class="nav-item dropdown"
|
<li class="nav-item dropdown h-100 d-flex flex-column justify-content-center"
|
||||||
(mouseenter)="activateSection($event)"
|
(mouseenter)="activateSection($event)"
|
||||||
(mouseleave)="deactivateSection($event)">
|
(mouseleave)="deactivateSection($event)">
|
||||||
<a href="#" class="nav-link dropdown-toggle" routerLinkActive="active"
|
<a href="#" class="nav-link dropdown-toggle" routerLinkActive="active"
|
||||||
|
@@ -1,4 +1,4 @@
|
|||||||
<li class="nav-item">
|
<li class="nav-item h-100 d-flex flex-column justify-content-center">
|
||||||
<ng-container
|
<ng-container
|
||||||
*ngComponentOutlet="(sectionMap$ | async).get(section.id).component; injector: (sectionMap$ | async).get(section.id).injector;"></ng-container>
|
*ngComponentOutlet="(sectionMap$ | async).get(section.id).component; injector: (sectionMap$ | async).get(section.id).injector;"></ng-container>
|
||||||
</li>
|
</li>
|
||||||
|
@@ -1,17 +1,24 @@
|
|||||||
<nav [ngClass]="{'open': !(menuCollapsed | async)}"
|
<nav [ngClass]="{'open': !(menuCollapsed | async)}"
|
||||||
[@slideMobileNav]="!(windowService.isXsOrSm() | async) ? 'default' : ((menuCollapsed | async) ? 'collapsed' : 'expanded')"
|
[@slideMobileNav]="!(windowService.isXsOrSm() | async) ? 'default' : ((menuCollapsed | async) ? 'collapsed' : 'expanded')"
|
||||||
class="navbar navbar-light navbar-expand-md p-md-0 navbar-container"> <!-- TODO remove navbar-container class when https://github.com/twbs/bootstrap/issues/24726 is fixed -->
|
class="navbar navbar-expand-md navbar-light p-0 navbar-container"
|
||||||
<div class="container">
|
role="navigation" role="navigation" [attr.aria-label]="'nav.main.description' |translate">
|
||||||
<div class="reset-padding-md w-100">
|
<div class="container h-100">
|
||||||
<div id="collapsingNav">
|
<a class="navbar-brand my-2" routerLink="/home">
|
||||||
<ul class="navbar-nav mr-auto shadow-none">
|
<img src="assets/images/dspace-logo.svg" alt="logo"/>
|
||||||
<ng-container *ngFor="let section of (sections | async)">
|
</a>
|
||||||
<ng-container
|
|
||||||
*ngComponentOutlet="(sectionMap$ | async).get(section.id).component; injector: (sectionMap$ | async).get(section.id).injector;"></ng-container>
|
<div id="collapsingNav" class="w-100 h-100">
|
||||||
</ng-container>
|
<ul class="navbar-nav me-auto mb-2 mb-lg-0 h-100">
|
||||||
</ul>
|
<ng-container *ngFor="let section of (sections | async)">
|
||||||
</div>
|
<ng-container
|
||||||
</div>
|
*ngComponentOutlet="(sectionMap$ | async).get(section.id).component; injector: (sectionMap$ | async).get(section.id).injector;"></ng-container>
|
||||||
|
</ng-container>
|
||||||
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
<ds-search-navbar class="navbar-collapsed"></ds-search-navbar>
|
||||||
|
<ds-lang-switch class="navbar-collapsed"></ds-lang-switch>
|
||||||
|
<ds-auth-nav-menu class="navbar-collapsed"></ds-auth-nav-menu>
|
||||||
|
<ds-impersonate-navbar class="navbar-collapsed"></ds-impersonate-navbar>
|
||||||
|
</div>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
@@ -1,6 +1,8 @@
|
|||||||
nav.navbar {
|
nav.navbar {
|
||||||
border-bottom: 1px var(--bs-gray-400) solid;
|
border-top: 1px var(--ds-header-navbar-border-top-color) solid;
|
||||||
|
border-bottom: 1px var(--ds-header-navbar-border-bottom-color) solid;
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
|
color: var(--ds-header-icon-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Mobile menu styling **/
|
/** Mobile menu styling **/
|
||||||
@@ -29,7 +31,27 @@ nav.navbar {
|
|||||||
@media screen and (max-width: map-get($grid-breakpoints, md)) {
|
@media screen and (max-width: map-get($grid-breakpoints, md)) {
|
||||||
> .container {
|
> .container {
|
||||||
padding: 0 var(--bs-spacer);
|
padding: 0 var(--bs-spacer);
|
||||||
|
a.navbar-brand {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.navbar-collapsed {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
height: 80px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.navbar-brand img {
|
||||||
|
max-height: var(--ds-header-logo-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar-nav {
|
||||||
|
::ng-deep a.nav-link {
|
||||||
|
color: var(--ds-navbar-link-color);
|
||||||
|
}
|
||||||
|
::ng-deep a.nav-link:hover {
|
||||||
|
color: var(--ds-navbar-link-color-hover);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -41,6 +41,17 @@ export class NavbarComponent extends MenuComponent {
|
|||||||
*/
|
*/
|
||||||
createMenu() {
|
createMenu() {
|
||||||
const menuList: any[] = [
|
const menuList: any[] = [
|
||||||
|
/* Communities & Collections tree */
|
||||||
|
{
|
||||||
|
id: `browse_global_communities_and_collections`,
|
||||||
|
active: false,
|
||||||
|
visible: true,
|
||||||
|
model: {
|
||||||
|
type: MenuItemType.LINK,
|
||||||
|
text: `menu.section.browse_global_communities_and_collections`,
|
||||||
|
link: `/community-list`
|
||||||
|
} as LinkMenuItemModel
|
||||||
|
},
|
||||||
/* News */
|
/* News */
|
||||||
{
|
{
|
||||||
id: 'browse_global',
|
id: 'browse_global',
|
||||||
@@ -52,18 +63,6 @@ export class NavbarComponent extends MenuComponent {
|
|||||||
} as TextMenuItemModel,
|
} as TextMenuItemModel,
|
||||||
index: 0
|
index: 0
|
||||||
},
|
},
|
||||||
/* Communities & Collections tree */
|
|
||||||
{
|
|
||||||
id: `browse_global_communities_and_collections`,
|
|
||||||
parentID: 'browse_global',
|
|
||||||
active: false,
|
|
||||||
visible: true,
|
|
||||||
model: {
|
|
||||||
type: MenuItemType.LINK,
|
|
||||||
text: `menu.section.browse_global_communities_and_collections`,
|
|
||||||
link: `/community-list`
|
|
||||||
} as LinkMenuItemModel
|
|
||||||
},
|
|
||||||
];
|
];
|
||||||
// Read the different Browse-By types from config and add them to the browse menu
|
// Read the different Browse-By types from config and add them to the browse menu
|
||||||
const types = environment.browseBy.types;
|
const types = environment.browseBy.types;
|
||||||
|
@@ -9,6 +9,7 @@ import { NavbarSectionComponent } from './navbar-section/navbar-section.componen
|
|||||||
import { ExpandableNavbarSectionComponent } from './expandable-navbar-section/expandable-navbar-section.component';
|
import { ExpandableNavbarSectionComponent } from './expandable-navbar-section/expandable-navbar-section.component';
|
||||||
import { NavbarComponent } from './navbar.component';
|
import { NavbarComponent } from './navbar.component';
|
||||||
import { MenuModule } from '../shared/menu/menu.module';
|
import { MenuModule } from '../shared/menu/menu.module';
|
||||||
|
import { SharedModule } from '../shared/shared.module';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { ThemedNavbarComponent } from './themed-navbar.component';
|
import { ThemedNavbarComponent } from './themed-navbar.component';
|
||||||
|
|
||||||
@@ -25,6 +26,7 @@ const ENTRY_COMPONENTS = [
|
|||||||
@NgModule({
|
@NgModule({
|
||||||
imports: [
|
imports: [
|
||||||
CommonModule,
|
CommonModule,
|
||||||
|
SharedModule,
|
||||||
MenuModule,
|
MenuModule,
|
||||||
FormsModule,
|
FormsModule,
|
||||||
EffectsModule.forFeature(effects),
|
EffectsModule.forFeature(effects),
|
||||||
|
@@ -2,5 +2,6 @@
|
|||||||
[formId]="'profile-page-metadata-form-id'"
|
[formId]="'profile-page-metadata-form-id'"
|
||||||
[formModel]="formModel"
|
[formModel]="formModel"
|
||||||
[formGroup]="formGroup"
|
[formGroup]="formGroup"
|
||||||
[displaySubmit]="false">
|
[displaySubmit]="false"
|
||||||
|
[displayCancel]="false">
|
||||||
</ds-form>
|
</ds-form>
|
||||||
|
@@ -3,7 +3,8 @@
|
|||||||
[formId]="FORM_PREFIX"
|
[formId]="FORM_PREFIX"
|
||||||
[formModel]="formModel"
|
[formModel]="formModel"
|
||||||
[formGroup]="formGroup"
|
[formGroup]="formGroup"
|
||||||
[displaySubmit]="false">
|
[displaySubmit]="false"
|
||||||
|
[displayCancel]="false">
|
||||||
</ds-form>
|
</ds-form>
|
||||||
<div id="notLongEnough" class="container-fluid text-danger" *ngIf="formGroup.hasError('notLongEnough')">{{FORM_PREFIX + 'error.password-length' | translate}}</div>
|
<div id="notLongEnough" class="container-fluid text-danger" *ngIf="formGroup.hasError('notLongEnough')">{{FORM_PREFIX + 'error.password-length' | translate}}</div>
|
||||||
<div id="notSame" class="container-fluid text-danger" *ngIf="formGroup.hasError('notSame')">{{FORM_PREFIX + 'error.matching-passwords' | translate}}</div>
|
<div id="notSame" class="container-fluid text-danger" *ngIf="formGroup.hasError('notSame')">{{FORM_PREFIX + 'error.matching-passwords' | translate}}</div>
|
||||||
|
@@ -17,7 +17,9 @@
|
|||||||
></ds-profile-page-security-form>
|
></ds-profile-page-security-form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-outline-primary" (click)="updateProfile()">{{'profile.form.submit' | translate}}</button>
|
<div class="col-12 text-right pr-0">
|
||||||
|
<button class="btn btn-primary" (click)="updateProfile()"><i class="fas fa-edit"></i> {{'profile.form.submit' | translate}}</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<ng-container *ngVar="(groupsRD$ | async)?.payload?.page as groups">
|
<ng-container *ngVar="(groupsRD$ | async)?.payload?.page as groups">
|
||||||
<div *ngIf="groups">
|
<div *ngIf="groups">
|
||||||
|
@@ -10,14 +10,14 @@
|
|||||||
[options]="notificationOptions">
|
[options]="notificationOptions">
|
||||||
</ds-notifications-board>
|
</ds-notifications-board>
|
||||||
<main class="main-content">
|
<main class="main-content">
|
||||||
<div class="container">
|
<ds-themed-breadcrumbs></ds-themed-breadcrumbs>
|
||||||
<ds-themed-breadcrumbs></ds-themed-breadcrumbs>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="container" *ngIf="isLoading">
|
<div class="container d-flex justify-content-center align-items-center h-100" *ngIf="isLoading">
|
||||||
<ds-loading message="{{'loading.default' | translate}}"></ds-loading>
|
<ds-loading [showMessage]="false"></ds-loading>
|
||||||
|
</div>
|
||||||
|
<div [class.d-none]="isLoading">
|
||||||
|
<router-outlet></router-outlet>
|
||||||
</div>
|
</div>
|
||||||
<router-outlet></router-outlet>
|
|
||||||
</main>
|
</main>
|
||||||
|
|
||||||
<ds-themed-footer></ds-themed-footer>
|
<ds-themed-footer></ds-themed-footer>
|
||||||
|
@@ -4,7 +4,7 @@
|
|||||||
<input #searchInput [@toggleAnimation]="isExpanded" id="query" name="query"
|
<input #searchInput [@toggleAnimation]="isExpanded" id="query" name="query"
|
||||||
formControlName="query" type="text" placeholder="{{searchExpanded ? ('nav.search' | translate) : ''}}"
|
formControlName="query" type="text" placeholder="{{searchExpanded ? ('nav.search' | translate) : ''}}"
|
||||||
class="d-inline-block bg-transparent position-absolute form-control dropdown-menu-right p-1">
|
class="d-inline-block bg-transparent position-absolute form-control dropdown-menu-right p-1">
|
||||||
<a class="sticky-top submit-icon" (click)="searchExpanded ? onSubmit(searchForm.value) : expand()">
|
<a class="submit-icon" (click)="searchExpanded ? onSubmit(searchForm.value) : expand()">
|
||||||
<em class="fas fa-search fa-lg fa-fw"></em>
|
<em class="fas fa-search fa-lg fa-fw"></em>
|
||||||
</a>
|
</a>
|
||||||
</form>
|
</form>
|
||||||
|
@@ -12,14 +12,18 @@ input[type="text"] {
|
|||||||
|
|
||||||
a.submit-icon {
|
a.submit-icon {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: map-get($grid-breakpoints, md)) {
|
||||||
|
|
||||||
@media screen and (max-width: map-get($grid-breakpoints, sm)) {
|
|
||||||
#query:focus {
|
#query:focus {
|
||||||
max-width: 250px !important;
|
max-width: 250px !important;
|
||||||
width: 40vw !important;
|
width: 40vw !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a.submit-icon {
|
||||||
|
color: var(--bs-link-color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -12,22 +12,24 @@
|
|||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li *ngIf="!(isAuthenticated | async) && (isXsOrSm$ | async)" class="nav-item">
|
<li *ngIf="!(isAuthenticated | async) && (isXsOrSm$ | async)" class="nav-item">
|
||||||
<a id="loginLink" routerLink="/login" routerLinkActive="active" class="px-1">{{ 'nav.login' | translate }}<span
|
<a id="loginLink" routerLink="/login" routerLinkActive="active" class="px-1">
|
||||||
class="sr-only">(current)</span></a>
|
{{ 'nav.login' | translate }}<span class="sr-only">(current)</span>
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li *ngIf="(isAuthenticated | async) && !(isXsOrSm$ | async) && (showAuth | async)" class="nav-item">
|
<li *ngIf="(isAuthenticated | async) && !(isXsOrSm$ | async) && (showAuth | async)" class="nav-item">
|
||||||
<div ngbDropdown display="dynamic" placement="bottom-right" class="d-inline-block" @fadeInOut>
|
<div ngbDropdown display="dynamic" placement="bottom-right" class="d-inline-block" @fadeInOut>
|
||||||
<a href="#" id="dropdownUser" (click)="$event.preventDefault()" class="px-1" ngbDropdownToggle><i
|
<a href="#" id="dropdownUser" role="button" [attr.aria-label]="'nav.logout' |translate" (click)="$event.preventDefault()" [title]="'nav.logout' | translate" class="px-1" ngbDropdownToggle>
|
||||||
class="fas fa-user-circle fa-lg fa-fw" [title]="'nav.logout' | translate"></i></a>
|
<i class="fas fa-user-circle fa-lg fa-fw"></i></a>
|
||||||
<div id="logoutDropdownMenu" ngbDropdownMenu aria-labelledby="dropdownUser">
|
<div id="logoutDropdownMenu" ngbDropdownMenu aria-labelledby="dropdownUser">
|
||||||
<ds-user-menu></ds-user-menu>
|
<ds-user-menu></ds-user-menu>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li *ngIf="(isAuthenticated | async) && (isXsOrSm$ | async)" class="nav-item">
|
<li *ngIf="(isAuthenticated | async) && (isXsOrSm$ | async)" class="nav-item">
|
||||||
<a id="logoutLink" routerLink="/logout" routerLinkActive="active" class="px-1"><i
|
<a id="logoutLink" role="button" [attr.aria-label]="'nav.logout' |translate" [title]="'nav.logout' | translate" routerLink="/logout" routerLinkActive="active" class="px-1">
|
||||||
class="fas fa-user-circle fa-lg fa-fw" [title]="'nav.logout' | translate"></i><span
|
<i class="fas fa-user-circle fa-lg fa-fw"></i>
|
||||||
class="sr-only">(current)</span></a>
|
<span class="sr-only">(current)</span>
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
@@ -11,3 +11,11 @@
|
|||||||
.dropdown-item:hover, .dropdown-item:focus {
|
.dropdown-item:hover, .dropdown-item:focus {
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dropdown-toggle {
|
||||||
|
color: var(--ds-header-icon-color) !important;
|
||||||
|
|
||||||
|
&:hover, &focus {
|
||||||
|
color: var(--ds-header-icon-color-hover);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div *ngIf="!hideGear" ngbDropdown #paginationControls="ngbDropdown" placement="bottom-right" class="d-inline-block float-right">
|
<div *ngIf="!hideGear" ngbDropdown #paginationControls="ngbDropdown" placement="bottom-right" class="d-inline-block float-right">
|
||||||
<button class="btn btn-outline-primary" id="paginationControls" ngbDropdownToggle><i class="fas fa-cog" aria-hidden="true"></i></button>
|
<button class="btn btn-secondary" id="paginationControls" [title]="'pagination.options.description' | translate" [attr.aria-label]="'pagination.options.description' | translate" ngbDropdownToggle><i class="fas fa-cog" aria-hidden="true"></i></button>
|
||||||
<div id="paginationControlsDropdownMenu" aria-labelledby="paginationControls" ngbDropdownMenu>
|
<div id="paginationControlsDropdownMenu" aria-labelledby="paginationControls" ngbDropdownMenu>
|
||||||
<h6 class="dropdown-header">{{ 'pagination.results-per-page' | translate}}</h6>
|
<h6 class="dropdown-header">{{ 'pagination.results-per-page' | translate}}</h6>
|
||||||
<button class="dropdown-item page-size-change" *ngFor="let item of paginationConfig?.pageSizeOptions" (click)="doPageSizeChange(item)"><i [ngClass]="{'invisible': item != paginationConfig?.pageSize}" class="fas fa-check" aria-hidden="true"></i> {{item}} </button>
|
<button class="dropdown-item page-size-change" *ngFor="let item of paginationConfig?.pageSizeOptions" (click)="doPageSizeChange(item)"><i [ngClass]="{'invisible': item != paginationConfig?.pageSize}" class="fas fa-check" aria-hidden="true"></i> {{item}} </button>
|
||||||
@@ -29,8 +29,8 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<div>
|
<div>
|
||||||
<button id="nav-prev" type="button" class="btn btn-outline-secondary float-left" (click)="goPrev()" [disabled]="objects?.payload?.currentPage <= 1"><<</button>
|
<button id="nav-prev" type="button" class="btn btn-outline-primary float-left" (click)="goPrev()" [disabled]="objects?.payload?.currentPage <= 1"><i class="fas fa-angle-left"></i> {{'browse.previous.button' |translate}}</button>
|
||||||
<button id="nav-next" type="button" class="btn btn-outline-secondary float-right" (click)="goNext()" [disabled]="objects?.payload?.currentPage >= objects?.payload?.totalPages">>></button>
|
<button id="nav-next" type="button" class="btn btn-outline-primary float-right" (click)="goNext()" [disabled]="objects?.payload?.currentPage >= objects?.payload?.totalPages"><i class="fas fa-angle-right"></i> {{'browse.next.button' |translate}}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
(dragend)="onDragEnd(i)"
|
(dragend)="onDragEnd(i)"
|
||||||
(mouseover)="showTooltip(t, i)"
|
(mouseover)="showTooltip(t, i)"
|
||||||
(mouseout)="t.close()">
|
(mouseout)="t.close()">
|
||||||
<a class="flex-sm-fill text-sm-center nav-link active"
|
<a class="flex-sm-fill text-sm-center nav-link active bg-info"
|
||||||
href="#"
|
href="#"
|
||||||
[ngClass]="{'chip-selected disabled': (editable && c.editMode) || dragged == i}"
|
[ngClass]="{'chip-selected disabled': (editable && c.editMode) || dragged == i}"
|
||||||
(click)="chipsSelected($event, i);">
|
(click)="chipsSelected($event, i);">
|
||||||
@@ -42,7 +42,8 @@
|
|||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
|
<div [class.chips-sort-ignore]="(isDragging | async)" class="flex-grow-1">
|
||||||
<ng-content></ng-content>
|
<ng-content ></ng-content>
|
||||||
|
</div>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -1,5 +1,5 @@
|
|||||||
.chip-selected {
|
.chip-selected {
|
||||||
background-color: var(--bs-info) !important;
|
background-color: var(--bs-secondary) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.chip-label {
|
.chip-label {
|
||||||
|
@@ -8,6 +8,7 @@ import { ChipsItem } from './models/chips-item.model';
|
|||||||
import { UploaderService } from '../uploader/uploader.service';
|
import { UploaderService } from '../uploader/uploader.service';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { Options } from 'sortablejs';
|
import { Options } from 'sortablejs';
|
||||||
|
import { BehaviorSubject } from 'rxjs/internal/BehaviorSubject';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'ds-chips',
|
selector: 'ds-chips',
|
||||||
@@ -25,6 +26,7 @@ export class ChipsComponent implements OnChanges {
|
|||||||
@Output() remove: EventEmitter<number> = new EventEmitter<number>();
|
@Output() remove: EventEmitter<number> = new EventEmitter<number>();
|
||||||
@Output() change: EventEmitter<any> = new EventEmitter<any>();
|
@Output() change: EventEmitter<any> = new EventEmitter<any>();
|
||||||
|
|
||||||
|
isDragging: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(false);
|
||||||
options: Options;
|
options: Options;
|
||||||
dragged = -1;
|
dragged = -1;
|
||||||
tipText: string[];
|
tipText: string[];
|
||||||
@@ -73,6 +75,7 @@ export class ChipsComponent implements OnChanges {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onDragStart(index) {
|
onDragStart(index) {
|
||||||
|
this.isDragging.next(true);
|
||||||
this.uploaderService.overrideDragOverPage();
|
this.uploaderService.overrideDragOverPage();
|
||||||
this.dragged = index;
|
this.dragged = index;
|
||||||
}
|
}
|
||||||
@@ -81,6 +84,7 @@ export class ChipsComponent implements OnChanges {
|
|||||||
this.uploaderService.allowDragOverPage();
|
this.uploaderService.allowDragOverPage();
|
||||||
this.dragged = -1;
|
this.dragged = -1;
|
||||||
this.chips.updateOrder();
|
this.chips.updateOrder();
|
||||||
|
this.isDragging.next(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
showTooltip(tooltip: NgbTooltip, index, field?) {
|
showTooltip(tooltip: NgbTooltip, index, field?) {
|
||||||
|
@@ -11,10 +11,14 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-4 d-inline-block">
|
<div class="col-4 d-inline-block">
|
||||||
<div *ngIf="logo" class="btn-group btn-group-sm float-right" role="group">
|
<div *ngIf="logo" class="btn-group btn-group-sm float-right" role="group">
|
||||||
<button *ngIf="!markLogoForDeletion" type="button" class="btn btn-danger" (click)="deleteLogo()">
|
<button *ngIf="!markLogoForDeletion" type="button" class="btn btn-danger"
|
||||||
|
title="{{type.value + '.edit.logo.delete.title' | translate}}"
|
||||||
|
(click)="deleteLogo()">
|
||||||
<i class="fas fa-trash" aria-hidden="true"></i>
|
<i class="fas fa-trash" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
<button *ngIf="markLogoForDeletion" type="button" class="btn btn-warning" (click)="undoDeleteLogo()">
|
<button *ngIf="markLogoForDeletion" type="button" class="btn btn-warning"
|
||||||
|
title="{{type.value + '.edit.logo.delete-undo.title' | translate}}"
|
||||||
|
(click)="undoDeleteLogo()">
|
||||||
<i class="fas fa-undo" aria-hidden="true"></i>
|
<i class="fas fa-undo" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@@ -35,4 +39,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<ds-form *ngIf="formModel"
|
<ds-form *ngIf="formModel"
|
||||||
[formId]="'comcol-form-id'"
|
[formId]="'comcol-form-id'"
|
||||||
[formModel]="formModel" (submitForm)="onSubmit()" (cancel)="onCancel()"></ds-form>
|
[formModel]="formModel"
|
||||||
|
[displayCancel]="false"
|
||||||
|
(submitForm)="onSubmit()">
|
||||||
|
<button before (click)="back.emit()" class="btn btn-outline-secondary">
|
||||||
|
<i class="fas fa-arrow-left"></i> {{ type.value + '.edit.return' | translate }}
|
||||||
|
</button>
|
||||||
|
</ds-form>
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user