mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 18:14:17 +00:00
Support external links in menus
This commit is contained in:
@@ -2,5 +2,5 @@
|
|||||||
* List of possible MenuItemTypes
|
* List of possible MenuItemTypes
|
||||||
*/
|
*/
|
||||||
export enum MenuItemType {
|
export enum MenuItemType {
|
||||||
TEXT, LINK, ALTMETRIC, SEARCH, ONCLICK
|
TEXT, LINK, ALTMETRIC, SEARCH, ONCLICK, EXTERNAL
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,7 @@
|
|||||||
|
<a class="nav-item nav-link"
|
||||||
|
[ngClass]="{'disabled': !hasLink }"
|
||||||
|
[attr.aria-disabled]="!hasLink"
|
||||||
|
[href]="href"
|
||||||
|
[title]="item.text | translate"
|
||||||
|
(click)="$event.stopPropagation()"
|
||||||
|
>{{item.text | translate}}</a>
|
@@ -0,0 +1,53 @@
|
|||||||
|
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
|
||||||
|
import { TranslateModule } from '@ngx-translate/core';
|
||||||
|
import { DebugElement, NO_ERRORS_SCHEMA } from '@angular/core';
|
||||||
|
import { By } from '@angular/platform-browser';
|
||||||
|
import { ExternalLinkMenuItemComponent } from './external-link-menu-item.component';
|
||||||
|
|
||||||
|
describe('ExternalLinkMenuItemComponent', () => {
|
||||||
|
let component: ExternalLinkMenuItemComponent;
|
||||||
|
let fixture: ComponentFixture<ExternalLinkMenuItemComponent>;
|
||||||
|
let debugElement: DebugElement;
|
||||||
|
let text;
|
||||||
|
let link;
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
text = 'HELLO';
|
||||||
|
link = 'https://google.com/';
|
||||||
|
}
|
||||||
|
|
||||||
|
beforeEach(waitForAsync(() => {
|
||||||
|
init();
|
||||||
|
TestBed.configureTestingModule({
|
||||||
|
imports: [TranslateModule.forRoot()],
|
||||||
|
declarations: [ExternalLinkMenuItemComponent],
|
||||||
|
providers: [
|
||||||
|
{ provide: 'itemModelProvider', useValue: { text: text, href: link } },
|
||||||
|
],
|
||||||
|
schemas: [NO_ERRORS_SCHEMA]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
}));
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
fixture = TestBed.createComponent(ExternalLinkMenuItemComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
debugElement = fixture.debugElement;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should contain the correct text', () => {
|
||||||
|
const textContent = debugElement.query(By.css('a')).nativeElement.textContent;
|
||||||
|
expect(textContent).toEqual(text);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should have the right href attribute', () => {
|
||||||
|
const links = fixture.debugElement.queryAll(By.css('a'));
|
||||||
|
expect(links.length).toBe(1);
|
||||||
|
expect(links[0].nativeElement.href).toBe(link);
|
||||||
|
});
|
||||||
|
});
|
@@ -0,0 +1,36 @@
|
|||||||
|
import { Component, Inject, OnInit } from '@angular/core';
|
||||||
|
import { rendersMenuItemForType } from '../menu-item.decorator';
|
||||||
|
import { isNotEmpty } from '../../empty.util';
|
||||||
|
import { ExternalLinkMenuItemModel } from './models/external-link.model';
|
||||||
|
import { MenuItemType } from '../menu-item-type.model';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component that renders a menu section of type EXTERNAL
|
||||||
|
*/
|
||||||
|
@Component({
|
||||||
|
selector: 'ds-external-link-menu-item',
|
||||||
|
templateUrl: './external-link-menu-item.component.html'
|
||||||
|
})
|
||||||
|
@rendersMenuItemForType(MenuItemType.EXTERNAL)
|
||||||
|
export class ExternalLinkMenuItemComponent implements OnInit {
|
||||||
|
item: ExternalLinkMenuItemModel;
|
||||||
|
|
||||||
|
hasLink: boolean;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
@Inject('itemModelProvider') item: ExternalLinkMenuItemModel
|
||||||
|
) {
|
||||||
|
this.item = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngOnInit() {
|
||||||
|
this.hasLink = isNotEmpty(this.item.href);
|
||||||
|
}
|
||||||
|
|
||||||
|
get href() {
|
||||||
|
if (this.hasLink) {
|
||||||
|
return this.item.href;
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
}
|
@@ -19,7 +19,7 @@ describe('LinkMenuItemComponent', () => {
|
|||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
text = 'HELLO';
|
text = 'HELLO';
|
||||||
link = 'http://google.com';
|
link = '/world/hello';
|
||||||
queryParams = {params: true};
|
queryParams = {params: true};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
11
src/app/shared/menu/menu-item/models/external-link.model.ts
Normal file
11
src/app/shared/menu/menu-item/models/external-link.model.ts
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { MenuItemModel } from './menu-item.model';
|
||||||
|
import { MenuItemType } from '../../menu-item-type.model';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Model representing a Link Menu Section for an external link
|
||||||
|
*/
|
||||||
|
export class ExternalLinkMenuItemModel implements MenuItemModel {
|
||||||
|
type = MenuItemType.EXTERNAL;
|
||||||
|
text: string;
|
||||||
|
href: string;
|
||||||
|
}
|
@@ -7,13 +7,15 @@ import { LinkMenuItemComponent } from './menu-item/link-menu-item.component';
|
|||||||
import { TextMenuItemComponent } from './menu-item/text-menu-item.component';
|
import { TextMenuItemComponent } from './menu-item/text-menu-item.component';
|
||||||
import { OnClickMenuItemComponent } from './menu-item/onclick-menu-item.component';
|
import { OnClickMenuItemComponent } from './menu-item/onclick-menu-item.component';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { ExternalLinkMenuItemComponent } from './menu-item/external-link-menu-item.component';
|
||||||
|
|
||||||
const COMPONENTS = [
|
const COMPONENTS = [
|
||||||
MenuSectionComponent,
|
MenuSectionComponent,
|
||||||
MenuComponent,
|
MenuComponent,
|
||||||
LinkMenuItemComponent,
|
LinkMenuItemComponent,
|
||||||
TextMenuItemComponent,
|
TextMenuItemComponent,
|
||||||
OnClickMenuItemComponent
|
OnClickMenuItemComponent,
|
||||||
|
ExternalLinkMenuItemComponent,
|
||||||
];
|
];
|
||||||
|
|
||||||
const MODULES = [
|
const MODULES = [
|
||||||
|
@@ -172,6 +172,7 @@ import { BitstreamRequestACopyPageComponent } from './bitstream-request-a-copy-p
|
|||||||
import { DsSelectComponent } from './ds-select/ds-select.component';
|
import { DsSelectComponent } from './ds-select/ds-select.component';
|
||||||
import { LogInOidcComponent } from './log-in/methods/oidc/log-in-oidc.component';
|
import { LogInOidcComponent } from './log-in/methods/oidc/log-in-oidc.component';
|
||||||
import { ThemedItemListPreviewComponent } from './object-list/my-dspace-result-list-element/item-list-preview/themed-item-list-preview.component';
|
import { ThemedItemListPreviewComponent } from './object-list/my-dspace-result-list-element/item-list-preview/themed-item-list-preview.component';
|
||||||
|
import { ExternalLinkMenuItemComponent } from './menu/menu-item/external-link-menu-item.component';
|
||||||
|
|
||||||
const MODULES = [
|
const MODULES = [
|
||||||
// Do NOT include UniversalModule, HttpModule, or JsonpModule here
|
// Do NOT include UniversalModule, HttpModule, or JsonpModule here
|
||||||
@@ -397,6 +398,7 @@ const ENTRY_COMPONENTS = [
|
|||||||
OnClickMenuItemComponent,
|
OnClickMenuItemComponent,
|
||||||
TextMenuItemComponent,
|
TextMenuItemComponent,
|
||||||
ScopeSelectorModalComponent,
|
ScopeSelectorModalComponent,
|
||||||
|
ExternalLinkMenuItemComponent,
|
||||||
];
|
];
|
||||||
|
|
||||||
const SHARED_ITEM_PAGE_COMPONENTS = [
|
const SHARED_ITEM_PAGE_COMPONENTS = [
|
||||||
|
Reference in New Issue
Block a user