Merge pull request #389 from atmire/Theme-for-item-pages

Preview release theme, extended for Configurable Entities
This commit is contained in:
Tim Donohue
2019-05-14 09:19:00 -05:00
committed by GitHub
88 changed files with 1458 additions and 177 deletions

View File

@@ -224,6 +224,7 @@
"webpack-bundle-analyzer": "^2.13.1",
"webpack-dev-middleware": "3.2.0",
"webpack-dev-server": "^3.1.5",
"webpack-import-glob-loader": "^1.6.3",
"webpack-merge": "4.1.4",
"webpack-node-externals": "1.7.2"
}

View File

@@ -109,6 +109,16 @@
"link": {
"simple": "Simple item page",
"full": "Full item page"
},
"journal": {
"search": {
"title": "Articles in this journal"
}
},
"person": {
"search": {
"title": "Articles by this author"
}
}
},
"select": {

BIN
resources/images/banner.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
width="231.893px" height="167.458px" viewBox="0 0 231.893 167.458" enable-background="new 0 0 231.893 167.458"
xml:space="preserve">
<path fill="#43515F" d="M51.733,143.32c0-1.94,1.65-3.202,4.562-3.202c3.303,0,6.798,1.115,9.419,3.543l3.835-5.146
c-3.202-2.963-7.476-4.516-12.621-4.516c-7.622,0-12.284,4.467-12.284,9.855c0,12.188,18.644,8.254,18.644,13.887
c0,1.893-1.797,3.592-5.632,3.592c-4.466,0-8.011-2.039-10.292-4.418l-3.787,5.39c3.058,3.059,7.525,5.153,13.788,5.153
c8.691,0,12.964-4.474,12.964-10.396C70.329,144.971,51.733,148.418,51.733,143.32z M100.682,134.484H85.534v32.386h6.895v-11.557
h8.254c6.99,0,10.875-4.759,10.875-10.391C111.558,139.243,107.722,134.484,100.682,134.484z M99.71,149.245h-7.283v-8.69h7.283
c2.72,0,4.808,1.651,4.808,4.368C104.518,147.592,102.43,149.245,99.71,149.245z M180.759,140.067c3.302,0,6.215,2.09,7.573,4.71
l5.923-2.913c-2.28-4.078-6.407-7.914-13.496-7.914c-9.759,0-17.283,6.75-17.283,16.75c0,9.954,7.524,16.76,17.283,16.76
c7.089,0,11.216-3.94,13.496-7.971l-5.923-2.865c-1.358,2.623-4.271,4.711-7.573,4.711c-5.924,0-10.194-4.517-10.194-10.635
C170.564,144.583,174.835,140.067,180.759,140.067z M131.958,134.484l-12.485,32.386h7.823l2.04-5.486h13.887l2.038,5.486h7.816
l-12.479-32.386H131.958z M131.228,155.313l5.05-13.936l5.05,13.936H131.228z M231.892,140.553v-6.069h-22.916v32.386h22.916v-6.07
H215.87v-7.379h15.684v-6.069H215.87v-6.797L231.892,140.553L231.892,140.553z"/>
<path fill="#43515F" d="M29.956,150.652c0-9.71-7.04-16.168-17.187-16.168H0v32.386h12.817
C22.916,166.87,29.956,160.458,29.956,150.652z M12.769,160.799H6.894v-20.246h5.924c6.603,0,10.098,4.418,10.098,10.099
C22.916,156.187,19.177,160.799,12.769,160.799z"/>
<path fill="#43515F" d="M120.726,58.569l0.109-0.006l0.116-0.01l0.106-0.013l0.11-0.01l0.11-0.023l0.109-0.019l0.106-0.023
l0.106-0.029l0.105-0.023l0.106-0.033l0.103-0.034l0.097-0.035l0.104-0.04l0.101-0.042l0.1-0.042v-0.001l0.096-0.045l0,0
l0.095-0.044l0.097-0.049l0.091-0.056v-0.001l0.094-0.05v-0.002l0.09-0.056v-0.001l0.093-0.06l0.083-0.056v-0.001l0.085-0.063
l0.088-0.065v-0.002l0.087-0.062v-0.001c0.816-0.683,1.393-1.646,1.561-2.738l0.013-0.104V54.72l0.014-0.101v-0.011l0.009-0.098
v-0.012l0.009-0.101V54.38l0.005-0.095v-0.016l0.002-0.105v-16.46l-0.002-0.105v-0.016l-0.005-0.095v-0.013l-0.009-0.101v-0.012
l-0.009-0.098v-0.011l-0.014-0.1v-0.01l-0.013-0.104c-0.167-1.092-0.744-2.057-1.561-2.738V34.3l-0.087-0.063v-0.002l-0.088-0.065
l-0.085-0.063v-0.001l-0.083-0.056l-0.093-0.061l0,0l-0.09-0.056V33.93l-0.094-0.05v-0.001l-0.091-0.056l-0.097-0.049l-0.095-0.043
V33.73l-0.096-0.045v-0.001l-0.1-0.043l-0.101-0.042l-0.104-0.04l-0.097-0.035l-0.103-0.031l-0.106-0.036l-0.105-0.023l-0.106-0.028
l-0.106-0.024l-0.109-0.019l-0.11-0.023l-0.11-0.009l-0.106-0.014l-0.116-0.01l-0.109-0.006l-0.114-0.005h-7.89
c-9.716,0-15.858-7.838-15.858-17.15V6.92c0-3.812-3.102-6.915-6.914-6.915H74.085c-3.813,0-6.92,3.106-6.92,6.915v16.682
c0,3.806,3.104,6.909,6.92,6.909h8.414c9.169,0,16.906,5.95,17.146,15.403v0.04c-0.24,9.453-7.978,15.402-17.146,15.402h-8.414
c-3.815,0-6.92,3.103-6.92,6.909v16.682c0,3.81,3.106,6.915,6.92,6.915H89.95c3.812,0,6.914-3.104,6.914-6.915v-9.223
c0-9.312,6.144-17.149,15.858-17.149h7.89L120.726,58.569z M154.772,9.956C148.631,3.814,140.15,0,130.816,0h-15.024v17.424h15.024
c4.526,0,8.647,1.858,11.64,4.849c2.99,2.99,4.849,7.112,4.849,11.639v24.042c0,4.538-1.853,8.665-4.832,11.655l-0.017-0.016
c-2.991,2.991-7.113,4.849-11.64,4.849h-15.024v17.424h15.024c9.333,0,17.814-3.814,23.956-9.956v-0.033
c6.142-6.143,9.955-14.614,9.955-23.923V33.912C164.727,24.578,160.914,16.097,154.772,9.956z"/>
</svg>

After

Width:  |  Height:  |  Size: 3.9 KiB

View File

@@ -1,4 +1,4 @@
<nav @slideHorizontal class="navbar navbar-dark bg-dark p-0"
<nav @slideHorizontal class="navbar navbar-dark p-0"
[ngClass]="{'active': sidebarOpen, 'inactive': sidebarClosed}"
[@slideSidebar]="{
value: (!(sidebarExpanded | async) ? 'collapsed' : 'expanded'),

View File

@@ -8,6 +8,7 @@ $icon-z-index: 10;
height: 100vh;
flex: 1 1 auto;
nav {
background-color: $admin-sidebar-bg;
height: 100%;
flex-direction: column;
> div {
@@ -44,7 +45,7 @@ $icon-z-index: 10;
.sidebar-section {
display: flex;
align-content: stretch;
background-color: $dark;
background-color: $admin-sidebar-bg;
.nav-item {
padding-top: $spacer;
padding-bottom: $spacer;

View File

@@ -0,0 +1,16 @@
@import '../../../styles/variables.scss';
:host {
display: block;
margin-top: -$content-spacing;
margin-bottom: -$content-spacing;
}
.display-3 {
word-break: break-word;
}
.dspace-logo {
height: 110px;
width: 110px;
}

View File

@@ -1,16 +1,2 @@
@import '../../../styles/variables.scss';
:host {
display: block;
margin-top: -$content-spacing;
margin-bottom: -$content-spacing;
}
.display-3 {
word-break: break-word;
}
.dspace-logo {
height: 110px;
width: 110px;
}
@import './home-news.component.default';
@import './themes/*.scss';

View File

@@ -3,7 +3,8 @@ import { Component } from '@angular/core';
@Component({
selector: 'ds-home-news',
styleUrls: ['./home-news.component.scss'],
templateUrl: './home-news.component.html'
// templateUrl: './home-news.component.html',
templateUrl: './themes/home-news.component.mantis.html'
})
/**

View File

@@ -0,0 +1,21 @@
<div class="jumbotron jumbotron-fluid">
<div class="d-flex flex-wrap">
<div>
<h1 class="display-3">DSpace 7</h1>
<p class="lead">DSpace is the world leading open source repository platform that enables
organisations to:</p>
</div>
</div>
<ul>
<li>easily ingest documents, audio, video, datasets and their corresponding Dublin Core
metadata
</li>
<li>open up this content to local and global audiences, thanks to the OAI-PMH interface and
Google Scholar optimizations
</li>
<li>issue permanent urls and trustworthy identifiers, including optional integrations with
handle.net and DataCite DOI
</li>
</ul>
<p>Join an international community of <A HREF="https://wiki.duraspace.org/display/DSPACE/DSpace+Positioning" TARGET="_NEW">leading institutions using DSpace</A>.</p>
</div>

View File

@@ -0,0 +1,19 @@
@import '../../../../styles/variables.scss';
@import '../../../../styles/mixins.scss';
:host-context(.mantis) {
$home-news-link-color: $green !default;
$home-news-link-color: darken($home-news-link-color, 15%) !default;
.jumbotron {
background-color: transparent;
}
a {
color: $home-news-link-color;
@include hover {
color: $home-news-link-color;
}
}
}

View File

@@ -0,0 +1,3 @@
:host {
//color: red;
}

View File

@@ -1 +1,2 @@
@import '../../styles/variables.scss';
@import './home-page.component.default';
@import './themes/*.scss';

View File

@@ -3,7 +3,8 @@ import { Component } from '@angular/core';
@Component({
selector: 'ds-home-page',
styleUrls: ['./home-page.component.scss'],
templateUrl: './home-page.component.html'
// templateUrl: './home-page.component.html'
templateUrl: './themes/home-page.component.mantis.html'
})
export class HomePageComponent {
}

View File

@@ -0,0 +1,10 @@
<div class="background-image">
<div class="container">
<ds-home-news></ds-home-news>
<ds-search-form class="d-block pb-3" [large]="true" [brandColor]="'success'"></ds-search-form>
</div>
<small class="credits">Photo by <a href="https://www.pexels.com/@inspiredimages">@inspiredimages</a></small>
</div>
<div class="container pt-3">
<ds-top-level-community-list></ds-top-level-community-list>
</div>

View File

@@ -0,0 +1,52 @@
@import '../../../styles/variables.scss';
:host-context(.mantis) {
div.background-image {
color: white;
background-color: $info;
position: relative;
background-position-y: -200px;
background-image: url('/assets/images/banner.jpg');
background-size: cover;
@media screen and (max-width: map-get($grid-breakpoints, lg)) {
background-position-y: 0;
}
.container {
position: relative;
text-shadow: 1px 1px 4px rgba(0, 0, 0, 0.6);
&:before, &:after {
content: '';
display: block;
width: $banner-background-gradient-width;
height: 100%;
top: 0;
position: absolute;
}
&:before {
background: linear-gradient(to left, $banner-text-background, transparent);
left: -$banner-background-gradient-width;
}
&:after {
background: linear-gradient(to right, $banner-text-background, transparent);
right: -$banner-background-gradient-width;
}
background-color: $banner-text-background;
}
small.credits {
a {
color: inherit;
}
opacity: 0.3;
position: absolute;
right: $spacer;
bottom: 0;
}
}
}

View File

@@ -25,7 +25,7 @@ import { ItemViewMode } from '../../shared/items/item-type-decorator';
@Component({
selector: 'ds-item-page',
styleUrls: ['./item-page.component.scss'],
templateUrl: './item-page.component.html',
templateUrl: './themes/item-page.component.mantis.html',
changeDetection: ChangeDetectionStrategy.OnPush,
animations: [fadeInOut]
})

View File

@@ -11,8 +11,8 @@ import { filterRelationsByTypeLabel, relationsToItems } from '../shared/item-rel
@rendersItemType('JournalIssue', ItemViewMode.Full)
@Component({
selector: 'ds-journal-issue',
styleUrls: ['./journal-issue.component.scss'],
templateUrl: './journal-issue.component.html'
styleUrls: ['./themes/journal-issue.component.mantis.scss'],
templateUrl: './themes/journal-issue.component.mantis.html'
})
/**
* The component for displaying metadata and relations of an item of the type Journal Issue

View File

@@ -0,0 +1,73 @@
<div class="top-item-page">
<div class="container">
<div class="row">
<div class="col-12 col-md-2 d-flex flex-md-column justify-content-between">
<ds-metadata-field-wrapper>
<ds-thumbnail [thumbnail]="this.item.getThumbnail() | async"></ds-thumbnail>
</ds-metadata-field-wrapper>
<div>
<a class="btn btn-secondary"
[routerLink]="['/items/' + item.id + '/full']">
{{"item.page.link.full" | translate}}
</a>
</div>
</div>
<div class="col-12 col-md-10">
<h2 class="item-page-title-field">
{{'journalissue.page.titleprefix' | translate}}
<ds-metadata-values
[mdValues]="item?.allMetadata(['dc.title'])"></ds-metadata-values>
</h2>
<div class="row">
<div class="col-12 col-md-6">
<ds-generic-item-page-field [item]="item"
[fields]="['journal.title']"
[label]="'journalissue.page.journal-title'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[fields]="['journalissue.identifier.number']"
[label]="'journalissue.page.number'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[fields]="['journal.identifier.issn']"
[label]="'journalissue.page.journal-issn'">
</ds-generic-item-page-field>
</div>
<div class="col-12 col-md-6">
<ds-generic-item-page-field [item]="item"
[fields]="['journalissue.issuedate']"
[label]="'journalissue.page.issuedate'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[fields]="['journalissue.identifier.description']"
[label]="'journalissue.page.description'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[fields]="['journalissue.identifier.keyword']"
[label]="'journalissue.page.keyword'">
</ds-generic-item-page-field>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="relationships-item-page" *ngIf="(volumes$ | async) || (publications$ | async)">
<div class="container">
<div class="row">
<div class="col-12 col-md-4" *ngIf="volumes$ | async">
<ds-related-items
[items]="volumes$ | async"
[label]="'relationships.isSingleVolumeOf' | translate">
</ds-related-items>
</div>
<div class="col-12 col-md-4" *ngIf="publications$ | async">
<ds-related-items
[items]="publications$ | async"
[label]="'relationships.isPublicationOfJournalIssue' | translate">
</ds-related-items>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,30 @@
@import '../../../../../../styles/variables.scss';
:host {
> * {
display: block;
padding-top: $content-spacing;
padding-bottom: $content-spacing;
}
.top-item-page {
background-color: $gray-100;
margin-top: -$content-spacing;
}
.relationships-item-page {
padding-bottom: $content-spacing - $spacer;
}
ds-metadata-field-wrapper {
@media screen and (max-width: map-get($grid-breakpoints, md)) {
flex: 1;
padding-right: $spacer/2;
}
ds-thumbnail {
display: block;
max-width: $thumbnail-max-width;
}
}
}

View File

@@ -11,8 +11,8 @@ import { filterRelationsByTypeLabel, relationsToItems } from '../shared/item-rel
@rendersItemType('JournalVolume', ItemViewMode.Full)
@Component({
selector: 'ds-journal-volume',
styleUrls: ['./journal-volume.component.scss'],
templateUrl: './journal-volume.component.html'
styleUrls: ['./themes/journal-volume.component.mantis.scss'],
templateUrl: './themes/journal-volume.component.mantis.html'
})
/**
* The component for displaying metadata and relations of an item of the type Journal Volume

View File

@@ -0,0 +1,62 @@
<div class="top-item-page">
<div class="container">
<div class="row">
<div class="col-12 col-md-2 d-flex flex-md-column justify-content-between">
<ds-metadata-field-wrapper>
<ds-thumbnail [thumbnail]="this.item.getThumbnail() | async"></ds-thumbnail>
</ds-metadata-field-wrapper>
<div>
<a class="btn btn-secondary"
[routerLink]="['/items/' + item.id + '/full']">
{{"item.page.link.full" | translate}}
</a>
</div>
</div>
<div class="col-12 col-md-10">
<h2 class="item-page-title-field">
{{'journalvolume.page.titleprefix' | translate}}
<ds-metadata-values
[mdValues]="item?.allMetadata(['dc.title'])"></ds-metadata-values>
</h2>
<div class="row">
<div class="col-12 col-md-6">
<ds-generic-item-page-field [item]="item"
[fields]="['journalvolume.identifier.volume']"
[label]="'journalvolume.page.volume'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[fields]="['journalvolume.issuedate']"
[label]="'journalvolume.page.issuedate'">
</ds-generic-item-page-field>
</div>
<div class="col-12 col-md-6">
<ds-generic-item-page-field [item]="item"
[fields]="['journalvolume.identifier.description']"
[label]="'journalvolume.page.description'">
</ds-generic-item-page-field>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="relationships-item-page" *ngIf="(journals$ | async) || (issues$ | async)">
<div class="container">
<div class="row">
<div class="col-12 col-md-4" *ngIf="journals$ | async">
<ds-related-items
[items]="journals$ | async"
[label]="'relationships.isSingleJournalOf' | translate">
</ds-related-items>
</div>
<div class="col-12 col-md-4" *ngIf="issues$ | async">
<ds-related-items
[items]="issues$ | async"
[label]="'relationships.isIssueOf' | translate">
</ds-related-items>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,30 @@
@import '../../../../../../styles/variables.scss';
:host {
> * {
display: block;
padding-top: $content-spacing;
padding-bottom: $content-spacing;
}
.top-item-page {
background-color: $gray-100;
margin-top: -$content-spacing;
}
.relationships-item-page {
padding-bottom: $content-spacing - $spacer;
}
ds-metadata-field-wrapper {
@media screen and (max-width: map-get($grid-breakpoints, md)) {
flex: 1;
padding-right: $spacer/2;
}
ds-thumbnail {
display: block;
max-width: $thumbnail-max-width;
}
}
}

View File

@@ -11,8 +11,8 @@ import { filterRelationsByTypeLabel, relationsToItems } from '../shared/item-rel
@rendersItemType('Journal', ItemViewMode.Full)
@Component({
selector: 'ds-journal',
styleUrls: ['./journal.component.scss'],
templateUrl: './journal.component.html'
styleUrls: ['./themes/journal.component.mantis.scss'],
templateUrl: './themes/journal.component.mantis.html'
})
/**
* The component for displaying metadata and relations of an item of the type Journal

View File

@@ -0,0 +1,67 @@
<div class="top-item-page">
<div class="container">
<div class="row">
<div class="col-12 col-md-2 d-flex flex-md-column justify-content-between">
<ds-metadata-field-wrapper>
<ds-thumbnail [thumbnail]="this.item.getThumbnail() | async"></ds-thumbnail>
</ds-metadata-field-wrapper>
<div>
<a class="btn btn-secondary"
[routerLink]="['/items/' + item.id + '/full']">
{{"item.page.link.full" | translate}}
</a>
</div>
</div>
<div class="col-12 col-md-10">
<h2 class="item-page-title-field">
{{'journal.page.titleprefix' | translate}}
<ds-metadata-values
[mdValues]="item?.allMetadata(['dc.title'])"></ds-metadata-values>
</h2>
<div class="row">
<div class="col-12 col-md-6">
<ds-generic-item-page-field class="item-page-fields" [item]="item"
[fields]="['journal.identifier.issn']"
[label]="'journal.page.issn'">
</ds-generic-item-page-field>
<ds-generic-item-page-field class="item-page-fields" [item]="item"
[fields]="['journal.publisher']"
[label]="'journal.page.publisher'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[fields]="['journal.contributor.editor']"
[label]="'journal.page.editor'">
</ds-generic-item-page-field>
</div>
<div class="col-12 col-md-6">
<ds-generic-item-page-field class="item-page-fields" [item]="item"
[fields]="['journal.identifier.description']"
[label]="'journal.page.description'">
</ds-generic-item-page-field>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="relationships-item-page" *ngIf="volumes$ | async">
<div class="container">
<div class="row">
<div class="col-12 col-md-4" *ngIf="volumes$ | async">
<ds-related-items
[items]="volumes$ | async"
[label]="'relationships.isVolumeOf' | translate">
</ds-related-items>
</div>
</div>
</div>
</div>
<div>
<div class="container search-container">
<h3 class="h2">{{"item.page.journal.search.title" | translate}}</h3>
</div>
<ds-related-entities-search [item]="item"
[relationType]="'isJournalOfPublication'">
</ds-related-entities-search>
</div>

View File

@@ -0,0 +1,38 @@
@import '../../../../../../styles/variables.scss';
:host {
> * {
display: block;
padding-top: $content-spacing;
padding-bottom: $content-spacing;
}
.top-item-page {
background-color: $gray-100;
margin-top: -$content-spacing;
}
.relationships-item-page {
padding-bottom: $content-spacing - $spacer;
}
ds-metadata-field-wrapper {
@media screen and (max-width: map-get($grid-breakpoints, md)) {
flex: 1;
padding-right: $spacer/2;
}
ds-thumbnail {
display: block;
max-width: $thumbnail-max-width;
}
}
.search-container {
margin-bottom: $spacer;
@media screen and (max-width: map-get($grid-breakpoints, lg)) {
width: 100%;
max-width: none;
}
}
}

View File

@@ -11,8 +11,8 @@ import { filterRelationsByTypeLabel, relationsToItems } from '../shared/item-rel
@rendersItemType('OrgUnit', ItemViewMode.Full)
@Component({
selector: 'ds-orgunit',
styleUrls: ['./orgunit.component.scss'],
templateUrl: './orgunit.component.html'
styleUrls: ['./themes/orgunit.component.mantis.scss'],
templateUrl: './themes/orgunit.component.mantis.html'
})
/**
* The component for displaying metadata and relations of an item of the type Organisation Unit

View File

@@ -0,0 +1,76 @@
<div class="top-item-page">
<div class="container">
<div class="row">
<div class="col-12 col-md-2 d-flex flex-md-column justify-content-between">
<ds-metadata-field-wrapper>
<ds-thumbnail [thumbnail]="this.item.getThumbnail() | async"
[defaultImage]="'assets/images/orgunit-placeholder.svg'"></ds-thumbnail>
</ds-metadata-field-wrapper>
<div>
<a class="btn btn-secondary"
[routerLink]="['/items/' + item.id + '/full']">
{{"item.page.link.full" | translate}}
</a>
</div>
</div>
<div class="col-12 col-md-10">
<h2 class="item-page-title-field">
{{'orgunit.page.titleprefix' | translate}}
<ds-metadata-values
[mdValues]="item?.allMetadata(['orgunit.identifier.name'])"></ds-metadata-values>
</h2>
<div class="row">
<div class="col-12 col-md-6">
<ds-generic-item-page-field [item]="item"
[fields]="['orgunit.identifier.city']"
[label]="'orgunit.page.city'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[fields]="['orgunit.identifier.country']"
[label]="'orgunit.page.country'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[fields]="['orgunit.identifier.id']"
[label]="'orgunit.page.id'">
</ds-generic-item-page-field>
</div>
<div class="col-12 col-md-6">
<ds-generic-item-page-field [item]="item"
[fields]="['orgunit.identifier.dateestablished']"
[label]="'orgunit.page.dateestablished'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[fields]="['orgunit.identifier.description']"
[label]="'orgunit.page.description'">
</ds-generic-item-page-field>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="relationships-item-page" *ngIf="(people$ | async) || (projects$ | async) || (publications$ | async)">
<div class="container">
<div class="row">
<div class="col-12 col-md-4" *ngIf="people$ | async">
<ds-related-items
[items]="people$ | async"
[label]="'relationships.isPersonOf' | translate">
</ds-related-items>
</div>
<div class="col-12 col-md-4" *ngIf="projects$ | async">
<ds-related-items
[items]="projects$ | async"
[label]="'relationships.isProjectOf' | translate">
</ds-related-items>
</div>
<div class="col-12 col-md-4" *ngIf="publications$ | async">
<ds-related-items
[items]="publications$ | async"
[label]="'relationships.isPublicationOf' | translate">
</ds-related-items>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,30 @@
@import '../../../../../../styles/variables.scss';
:host {
> * {
display: block;
padding-top: $content-spacing;
padding-bottom: $content-spacing;
}
.top-item-page {
background-color: $gray-100;
margin-top: -$content-spacing;
}
.relationships-item-page {
padding-bottom: $content-spacing - $spacer;
}
ds-metadata-field-wrapper {
@media screen and (max-width: map-get($grid-breakpoints, md)) {
flex: 1;
padding-right: $spacer/2;
}
ds-thumbnail {
display: block;
max-width: $thumbnail-max-width;
}
}
}

View File

@@ -12,8 +12,8 @@ import { filterRelationsByTypeLabel, relationsToItems } from '../shared/item-rel
@rendersItemType('Person', ItemViewMode.Full)
@Component({
selector: 'ds-person',
styleUrls: ['./person.component.scss'],
templateUrl: './person.component.html'
styleUrls: ['./themes/person.component.mantis.scss'],
templateUrl: './themes/person.component.mantis.html'
})
/**
* The component for displaying metadata and relations of an item of the type Person

View File

@@ -0,0 +1,85 @@
<div class="top-item-page">
<div class="container">
<div class="row">
<div class="col-12 col-md-2 d-flex flex-md-column justify-content-between">
<ds-metadata-field-wrapper>
<ds-thumbnail [thumbnail]="this.item.getThumbnail() | async"
[defaultImage]="'assets/images/person-placeholder.svg'"></ds-thumbnail>
</ds-metadata-field-wrapper>
<div>
<a class="btn btn-secondary"
[routerLink]="['/items/' + item.id + '/full']">
{{"item.page.link.full" | translate}}
</a>
</div>
</div>
<div class="col-12 col-md-10">
<h2 class="item-page-title-field">
{{'person.page.titleprefix' | translate}}<ds-metadata-values
[mdValues]="item?.allMetadata(['dc.contributor.author'])"></ds-metadata-values>
</h2>
<div class="row">
<div class="col-12 col-md-6">
<ds-generic-item-page-field [item]="item"
[fields]="['person.identifier.email']"
[label]="'person.page.email'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[fields]="['person.identifier.orcid']"
[label]="'person.page.orcid'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[fields]="['person.identifier.birthdate']"
[label]="'person.page.birthdate'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[fields]="['person.identifier.staffid']"
[label]="'person.page.staffid'">
</ds-generic-item-page-field>
</div>
<div class="col-12 col-md-6">
<ds-generic-item-page-field [item]="item"
[fields]="['person.identifier.jobtitle']"
[label]="'person.page.jobtitle'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[fields]="['person.identifier.lastname']"
[label]="'person.page.lastname'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[fields]="['person.identifier.firstname']"
[label]="'person.page.firstname'">
</ds-generic-item-page-field>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="relationships-item-page" *ngIf="(projects$ | async) || (orgUnits$ | async)">
<div class="container">
<div class="row">
<div class="col-12 col-md-4" *ngIf="projects$ | async">
<ds-related-items
[items]="projects$ | async"
[label]="'relationships.isProjectOf' | translate">
</ds-related-items>
</div>
<div class="col-12 col-md-4" *ngIf="orgUnits$ | async">
<ds-related-items
[items]="orgUnits$ | async"
[label]="'relationships.isOrgUnitOf' | translate">
</ds-related-items>
</div>
</div>
</div>
</div>
<div>
<div class="container search-container">
<h3 class="h2">{{"item.page.person.search.title" | translate}}</h3>
</div>
<ds-related-entities-search [item]="item"
[relationType]="'isAuthorOfPublication'">
</ds-related-entities-search>
</div>

View File

@@ -0,0 +1,38 @@
@import '../../../../../../styles/variables.scss';
:host {
> * {
display: block;
padding-top: $content-spacing;
padding-bottom: $content-spacing;
}
.top-item-page {
background-color: $gray-100;
margin-top: -$content-spacing;
}
.relationships-item-page {
padding-bottom: $content-spacing - $spacer;
}
ds-metadata-field-wrapper {
@media screen and (max-width: map-get($grid-breakpoints, md)) {
flex: 1;
padding-right: $spacer/2;
}
ds-thumbnail {
display: block;
max-width: $thumbnail-max-width;
}
}
.search-container {
margin-bottom: $spacer;
@media screen and (max-width: map-get($grid-breakpoints, lg)) {
width: 100%;
max-width: none;
}
}
}

View File

@@ -12,8 +12,8 @@ import { filterRelationsByTypeLabel, relationsToItems } from '../shared/item-rel
@rendersItemType('Project', ItemViewMode.Full)
@Component({
selector: 'ds-project',
styleUrls: ['./project.component.scss'],
templateUrl: './project.component.html'
styleUrls: ['./themes/project.component.mantis.scss'],
templateUrl: './themes/project.component.mantis.html'
})
/**
* The component for displaying metadata and relations of an item of the type Project

View File

@@ -0,0 +1,85 @@
<div class="top-item-page">
<div class="container">
<div class="row">
<div class="col-12 col-md-2 d-flex flex-md-column justify-content-between">
<ds-metadata-field-wrapper>
<ds-thumbnail [thumbnail]="this.item.getThumbnail() | async"
[defaultImage]="'assets/images/project-placeholder.svg'"></ds-thumbnail>
</ds-metadata-field-wrapper>
<div>
<a class="btn btn-secondary"
[routerLink]="['/items/' + item.id + '/full']">
{{"item.page.link.full" | translate}}
</a>
</div>
</div>
<div class="col-12 col-md-10">
<h2 class="item-page-title-field">
{{'project.page.titleprefix' | translate}}
<ds-metadata-values
[mdValues]="item?.allMetadata(['project.identifier.name'])"></ds-metadata-values>
</h2>
<div class="row">
<div class="col-12 col-md-6">
<ds-metadata-representation-list
[label]="'project.page.contributor' | translate"
[representations]="contributors$ | async">
</ds-metadata-representation-list>
<ds-generic-item-page-field [item]="item"
[fields]="['project.identifier.funder']"
[label]="'project.page.funder'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[fields]="['project.identifier.status']"
[label]="'project.page.status'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[fields]="['project.identifier.expectedcompletion']"
[label]="'project.page.expectedcompletion'">
</ds-generic-item-page-field>
</div>
<div class="col-12 col-md-6">
<ds-generic-item-page-field [item]="item"
[fields]="['project.identifier.id']"
[label]="'project.page.id'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[fields]="['project.identifier.description']"
[label]="'project.page.description'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[fields]="['project.identifier.keyword']"
[label]="'project.page.keyword'">
</ds-generic-item-page-field>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="relationships-item-page" *ngIf="(people$ | async) || (publications$ | async) || (orgUnits$ | async)">
<div class="container">
<div class="row">
<div class="col-12 col-md-4" *ngIf="people$ | async">
<ds-related-items
[items]="people$ | async"
[label]="'relationships.isPersonOf' | translate">
</ds-related-items>
</div>
<div class="col-12 col-md-4" *ngIf="publications$ | async">
<ds-related-items
[items]="publications$ | async"
[label]="'relationships.isPublicationOf' | translate">
</ds-related-items>
</div>
<div class="col-12 col-md-4" *ngIf="orgUnits$ | async">
<ds-related-items
[items]="orgUnits$ | async"
[label]="'relationships.isOrgUnitOf' | translate">
</ds-related-items>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,30 @@
@import '../../../../../../styles/variables.scss';
:host {
> * {
display: block;
padding-top: $content-spacing;
padding-bottom: $content-spacing;
}
.top-item-page {
background-color: $gray-100;
margin-top: -$content-spacing;
}
.relationships-item-page {
padding-bottom: $content-spacing - $spacer;
}
ds-metadata-field-wrapper {
@media screen and (max-width: map-get($grid-breakpoints, md)) {
flex: 1;
padding-right: $spacer/2;
}
ds-thumbnail {
display: block;
max-width: $thumbnail-max-width;
}
}
}

View File

@@ -15,8 +15,8 @@ import { filterRelationsByTypeLabel, relationsToItems } from '../shared/item-rel
@rendersItemType(DEFAULT_ITEM_TYPE, ItemViewMode.Full)
@Component({
selector: 'ds-publication',
styleUrls: ['./publication.component.scss'],
templateUrl: './publication.component.html',
styleUrls: ['./themes/publication.component.mantis.scss'],
templateUrl: './themes/publication.component.mantis.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class PublicationComponent extends ItemComponent implements OnInit {

View File

@@ -0,0 +1,83 @@
<div class="top-item-page">
<div class="container">
<div class="row">
<div class="col-12 col-md-2 d-flex flex-md-column justify-content-between">
<ds-metadata-field-wrapper>
<ds-thumbnail [thumbnail]="this.item.getThumbnail() | async"></ds-thumbnail>
</ds-metadata-field-wrapper>
<div>
<a class="btn btn-secondary"
[routerLink]="['/items/' + item.id + '/full']">
{{"item.page.link.full" | translate}}
</a>
</div>
</div>
<div class="col-12 col-md-10">
<ds-item-page-title-field [item]="item"></ds-item-page-title-field>
<div class="row">
<div class="col-12 col-md-6">
<ds-metadata-representation-list
[label]="'relationships.isAuthorOf' | translate"
[representations]="authors$ | async">
</ds-metadata-representation-list>
<ds-item-page-file-section [item]="item"></ds-item-page-file-section>
<ds-item-page-date-field [item]="item"></ds-item-page-date-field>
<ds-item-page-author-field *ngIf="!(authors$ | async)"
[item]="item"></ds-item-page-author-field>
<ds-generic-item-page-field [item]="item"
[fields]="['journal.title']"
[label]="'publication.page.journal-title'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[fields]="['journal.identifier.issn']"
[label]="'publication.page.journal-issn'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[fields]="['journalvolume.identifier.name']"
[label]="'publication.page.volume-title'">
</ds-generic-item-page-field>
</div>
<div class="col-12 col-md-6">
<ds-item-page-abstract-field [item]="item"></ds-item-page-abstract-field>
<ds-generic-item-page-field [item]="item"
[fields]="['dc.subject']"
[separator]="','"
[label]="'item.page.subject'">
</ds-generic-item-page-field>
<ds-generic-item-page-field [item]="item"
[fields]="['dc.identifier.citation']"
[label]="'item.page.citation'">
</ds-generic-item-page-field>
<ds-item-page-uri-field [item]="item"></ds-item-page-uri-field>
<ds-item-page-collections [item]="item"></ds-item-page-collections>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="relationships-item-page" *ngIf="(projects$ | async) || (orgUnits$ | async) || (journalIssues$ | async)">
<div class="container">
<div class="row">
<div class="col-12 col-md-4" *ngIf="projects$ | async">
<ds-related-items
[items]="projects$ | async"
[label]="'relationships.isProjectOf' | translate">
</ds-related-items>
</div>
<div class="col-12 col-md-4" *ngIf="orgUnits$ | async">
<ds-related-items
[items]="orgUnits$ | async"
[label]="'relationships.isOrgUnitOf' | translate">
</ds-related-items>
</div>
<div class="col-12 col-md-4" *ngIf="journalIssues$ | async">
<ds-related-items
[items]="journalIssues$ | async"
[label]="'relationships.isJournalIssueOf' | translate">
</ds-related-items>
</div>
</div>
</div>
</div>

View File

@@ -0,0 +1,30 @@
@import '../../../../../../styles/variables.scss';
:host {
> * {
display: block;
padding-top: $content-spacing;
padding-bottom: $content-spacing;
}
.top-item-page {
background-color: $gray-100;
margin-top: -$content-spacing;
}
.relationships-item-page {
padding-bottom: $content-spacing - $spacer;
}
ds-metadata-field-wrapper {
@media screen and (max-width: map-get($grid-breakpoints, md)) {
flex: 1;
padding-right: $spacer/2;
}
ds-thumbnail {
display: block;
max-width: $thumbnail-max-width;
}
}
}

View File

@@ -0,0 +1,9 @@
<div *ngVar="(itemRD$ | async) as itemRD">
<div class="item-page" *ngIf="itemRD?.hasSucceeded" @fadeInOut>
<div *ngIf="itemRD?.payload as item">
<ds-item-type-switcher [object]="item" [viewMode]="viewMode"></ds-item-type-switcher>
</div>
</div>
<ds-error *ngIf="itemRD?.hasFailed" message="{{'error.item' | translate}}"></ds-error>
<ds-loading *ngIf="itemRD?.isLoading" message="{{'loading.item' | translate}}"></ds-loading>
</div>

View File

@@ -0,0 +1,34 @@
<div>
<div class="filters py-2">
<a *ngFor="let value of (selectedValues | async)" class="d-flex flex-row"
[routerLink]="[getSearchLink()]"
[queryParams]="getRemoveParams(value) | async" queryParamsHandling="merge">
<input type="checkbox" [checked]="true" class="my-1 align-self-stretch"/>
<span class="filter-value pl-1">{{value}}</span>
</a>
<ng-container *ngFor="let page of (filterValues$ | async)?.payload">
<div [@facetLoad]="animationState">
<ng-container *ngFor="let value of page.page; let i=index">
<a *ngIf="!(selectedValues | async).includes(value.value)" class="d-flex flex-row"
[routerLink]="[getSearchLink()]"
[queryParams]="getAddParams(value.value) | async" queryParamsHandling="merge">
<input type="checkbox" [checked]="false" class="my-1 align-self-stretch"/>
<span class="filter-value px-1">{{value.value}}</span>
<span class="float-right filter-value-count ml-auto">
<span class="badge badge-primary badge-pill">{{value.count}}</span>
</span>
</a>
</ng-container>
</div>
</ng-container>
<div class="clearfix toggle-more-filters">
<a class="float-left" *ngIf="!(isLastPage$ | async)"
(click)="showMore()">{{"search.filters.filter.show-more"
| translate}}</a>
<a class="float-right" *ngIf="(currentPage | async) > 1"
(click)="showFirstPageOnly()">{{"search.filters.filter.show-less"
| translate}}</a>
</div>
</div>
</div>

View File

@@ -13,7 +13,8 @@ import { FilterType } from '../../../../search-service/filter-type.model';
@Component({
selector: 'ds-search-facet-option',
styleUrls: ['./search-facet-option.component.scss'],
templateUrl: './search-facet-option.component.html',
// templateUrl: './search-facet-option.component.html',
templateUrl: './themes/search-facet-option.component.mantis.html',
})
/**

View File

@@ -4,6 +4,6 @@
<input type="checkbox" [checked]="false" class="my-1 align-self-stretch"/>
<span class="filter-value px-1">{{filterValue.value}}</span>
<span class="float-right filter-value-count ml-auto">
<span class="badge badge-secondary badge-pill">{{filterValue.count}}</span>
<span class="badge badge-primary badge-pill">{{filterValue.count}}</span>
</span>
</a>

View File

@@ -18,7 +18,8 @@ const rangeDelimiter = '-';
@Component({
selector: 'ds-search-facet-range-option',
styleUrls: ['./search-facet-range-option.component.scss'],
templateUrl: './search-facet-range-option.component.html',
// templateUrl: './search-facet-range-option.component.html',
templateUrl: './themes/search-facet-range-option.component.mantis.html',
})
/**

View File

@@ -1,8 +1,8 @@
<a *ngIf="isVisible | async" class="d-flex flex-row"
[routerLink]="[getSearchLink()]"
[queryParams]="changeQueryParams" queryParamsHandling="merge">
<span class="filter-value px-1">{{filterValue.label}}</span>
<span class="filter-value px-1">{{filterValue.value}}</span>
<span class="float-right filter-value-count ml-auto">
<span class="badge badge-secondary badge-pill">{{filterValue.count}}</span>
<span class="badge badge-primary badge-pill">{{filterValue.count}}</span>
</span>
</a>
</a>

View File

@@ -0,0 +1,13 @@
@import '../../../../styles/variables.scss';
@import '../../../../styles/mixins.scss';
:host .facet-filter {
border: 1px solid map-get($theme-colors, light);
cursor: pointer;
.search-filter-wrapper.closed {
overflow: hidden;
}
.filter-toggle {
line-height: $line-height-base;
}
}

View File

@@ -1,13 +1,2 @@
@import '../../../../styles/variables.scss';
@import '../../../../styles/mixins.scss';
:host .facet-filter {
border: 1px solid map-get($theme-colors, light);
cursor: pointer;
.search-filter-wrapper.closed {
overflow: hidden;
}
.filter-toggle {
line-height: $line-height-base;
}
}
@import './search-filter.component.default';
@import './themes/*.scss';

View File

@@ -14,7 +14,8 @@ import { SEARCH_CONFIG_SERVICE } from '../../../+my-dspace-page/my-dspace-page.c
@Component({
selector: 'ds-search-filter',
styleUrls: ['./search-filter.component.scss'],
templateUrl: './search-filter.component.html',
// templateUrl: './search-filter.component.html',
templateUrl: './themes/search-filter.component.mantis.html',
animations: [slide],
})

View File

@@ -0,0 +1,43 @@
<div>
<div class="filters py-2">
<a *ngFor="let value of (selectedValues | async)" class="d-flex flex-row"
[routerLink]="[getSearchLink()]"
[queryParams]="getRemoveParams(value) | async" queryParamsHandling="merge">
<input type="checkbox" [checked]="true" class="my-1 align-self-stretch"/>
<span class="filter-value pl-1">{{value}}</span>
</a>
<ng-container *ngFor="let page of (filterValues$ | async)?.payload">
<div [@facetLoad]="animationState">
<ng-container *ngFor="let value of page.page; let i=index">
<a *ngIf="!(selectedValues | async).includes(value.value)" class="d-flex flex-row"
[routerLink]="[getSearchLink()]"
[queryParams]="getAddParams(value.value) | async" queryParamsHandling="merge" >
<input type="checkbox" [checked]="false" class="my-1 align-self-stretch"/>
<span class="filter-value px-1">{{value.value}}</span>
<span class="float-right filter-value-count ml-auto">
<span class="badge badge-primary badge-pill">{{value.count}}</span>
</span>
</a>
</ng-container>
</div>
</ng-container>
<div class="clearfix toggle-more-filters">
<a class="float-left" *ngIf="!(isLastPage$ | async)"
(click)="showMore()">{{"search.filters.filter.show-more"
| translate}}</a>
<a class="float-right" *ngIf="(currentPage | async) > 1"
(click)="showFirstPageOnly()">{{"search.filters.filter.show-less"
| translate}}</a>
</div>
</div>
<ds-input-suggestions [suggestions]="(filterSearchResults | async)"
[placeholder]="'search.filters.filter.' + filterConfig.name + '.placeholder'| translate"
[action]="getCurrentUrl()"
[name]="filterConfig.paramName"
[(ngModel)]="filter"
(submitSuggestion)="onSubmit($event)"
(clickSuggestion)="onClick($event)"
(findSuggestions)="findSuggestions($event)"
ngDefaultControl
></ds-input-suggestions>
</div>

View File

@@ -0,0 +1,31 @@
@import '../../../../../styles/variables.scss';
@import '../../../../../styles/mixins.scss';
.filters {
.toggle-more-filters a {
color: $link-color;
text-decoration: underline;
cursor: pointer;
}
}
$slider-handle-width: 18px;
::ng-deep
{
html:not([dir=rtl]) .noUi-horizontal .noUi-handle {
right: -$slider-handle-width/2;
}
.noUi-horizontal .noUi-handle {
width: $slider-handle-width;
&:before {
left: ($slider-handle-width - 2)/2 - 2;
}
&:after {
left: ($slider-handle-width - 2)/2 + 2;
}
&:focus {
outline: none;
}
}
}

View File

@@ -1,31 +1,2 @@
@import '../../../../../styles/variables.scss';
@import '../../../../../styles/mixins.scss';
.filters {
.toggle-more-filters a {
color: $link-color;
text-decoration: underline;
cursor: pointer;
}
}
$slider-handle-width: 18px;
::ng-deep
{
html:not([dir=rtl]) .noUi-horizontal .noUi-handle {
right: -$slider-handle-width/2;
}
.noUi-horizontal .noUi-handle {
width: $slider-handle-width;
&:before {
left: ($slider-handle-width - 2)/2 - 2;
}
&:after {
left: ($slider-handle-width - 2)/2 + 2;
}
&:focus {
outline: none;
}
}
}
@import './search-range-filter.component.default';
@import './themes/*.scss';

View File

@@ -0,0 +1,7 @@
@import '../../../../../../styles/variables.scss';
:host-context(.mantis) {
::ng-deep .noUi-connect {
background: $info;
}
}

View File

@@ -0,0 +1,40 @@
<div>
<div class="filters py-2">
<form #form="ngForm" (ngSubmit)="onSubmit()" class="add-filter row"
[action]="getCurrentUrl()">
<div class="col-6">
<input type="text" [(ngModel)]="range[0]" [name]="filterConfig.paramName + '.min'"
class="form-control" (blur)="onSubmit()"
aria-label="Mininum value"
[placeholder]="'search.filters.filter.' + filterConfig.name + '.min.placeholder'| translate"/>
</div>
<div class="col-6">
<input type="text" [(ngModel)]="range[1]" [name]="filterConfig.paramName + '.max'"
class="form-control" (blur)="onSubmit()"
aria-label="Maximum value"
[placeholder]="'search.filters.filter.' + filterConfig.name + '.max.placeholder'| translate"/>
</div>
<input type="submit" class="d-none"/>
</form>
<ng-container *ngIf="shouldShowSlider()">
<nouislider [connect]="true" [min]="min" [max]="max" [step]="1"
[(ngModel)]="range" (change)="onSubmit()" ngDefaultControl></nouislider>
</ng-container>
<ng-container *ngFor="let page of (filterValues$ | async)?.payload">
<div [@facetLoad]="animationState">
<ng-container *ngFor="let value of page.page; let i=index">
<a *ngIf="!(selectedValues | async).includes(value.value)" class="d-flex flex-row"
[routerLink]="[getSearchLink()]"
[queryParams]="getChangeParams(value.value) | async" queryParamsHandling="merge">
<span class="filter-value px-1">{{value.value}}</span>
<span class="float-right filter-value-count ml-auto">
<span class="badge badge-primary badge-pill">{{value.count}}</span>
</span>
</a>
</ng-container>
</div>
</ng-container>
</div>
</div>

View File

@@ -0,0 +1,45 @@
<div>
<div class="filters py-2">
<a *ngFor="let value of (selectedValues | async)" class="d-flex flex-row"
[routerLink]="[getSearchLink()]"
[queryParams]="getRemoveParams(value) | async" queryParamsHandling="merge">
<input type="checkbox" [checked]="true" class="my-1 align-self-stretch"/>
<span class="filter-value pl-1">{{value}}</span>
</a>
<ng-container *ngVar="(filterValues$ | async) as filterValuesRD">
<div [@facetLoad]="animationState">
<ng-container *ngFor="let page of filterValuesRD?.payload">
<ng-container *ngFor="let value of page.page; let i=index">
<a *ngIf="!(selectedValues | async).includes(value.value)" class="d-flex flex-row"
[routerLink]="[getSearchLink()]"
[queryParams]="getAddParams(value.value) | async" queryParamsHandling="merge" >
<input type="checkbox" [checked]="false" class="my-1 align-self-stretch"/>
<span class="filter-value px-1">{{value.value}}</span>
<span class="float-right filter-value-count ml-auto">
<span class="badge badge-primary badge-pill">{{value.count}}</span>
</span>
</a>
</ng-container>
</ng-container>
</div>
</ng-container>
<div class="clearfix toggle-more-filters">
<a class="float-left" *ngIf="!(isLastPage$ | async)"
(click)="showMore()">{{"search.filters.filter.show-more"
| translate}}</a>
<a class="float-right" *ngIf="(currentPage | async) > 1"
(click)="showFirstPageOnly()">{{"search.filters.filter.show-less"
| translate}}</a>
</div>
</div>
<ds-input-suggestions [suggestions]="(filterSearchResults | async)"
[placeholder]="'search.filters.filter.' + filterConfig.name + '.placeholder'| translate"
[action]="getCurrentUrl()"
[name]="filterConfig.paramName"
[(ngModel)]="filter"
(submitSuggestion)="onSubmit($event)"
(clickSuggestion)="onClick($event)"
(findSuggestions)="findSuggestions($event)"
ngDefaultControl
></ds-input-suggestions>
</div>

View File

@@ -0,0 +1,7 @@
<div class="facet-filter d-block mb-3 px-3 py-2" *ngIf="active$ | async">
<div (click)="toggle()" class="filter-name"><h5 class="d-inline-block mb-0">{{'search.filters.filter.' + filter.name + '.head'| translate}}</h5> <span class="filter-toggle fas float-right text-info"
[ngClass]="(collapsed$ | async) ? 'fa-caret-down' : 'fa-caret-up'"></span></div>
<div [@slide]="(collapsed$ | async) ? 'collapsed' : 'expanded'" (@slide.start)="startSlide($event)" (@slide.done)="finishSlide($event)" class="search-filter-wrapper" [ngClass]="{'closed' : closed}">
<ds-search-facet-filter-wrapper [filterConfig]="filter"></ds-search-facet-filter-wrapper>
</div>
</div>

View File

@@ -0,0 +1,11 @@
@import '../../../../../styles/variables.scss';
@import '../../../../../styles/mixins.scss';
:host-context(.mantis) .facet-filter {
background-color: map-get($theme-colors, light);
border-radius: $border-radius;
h5 {
font-size: 1.1rem
}
}

View File

@@ -14,7 +14,7 @@ import { SEARCH_CONFIG_SERVICE } from '../../+my-dspace-page/my-dspace-page.comp
@Component({
selector: 'ds-search-filters',
styleUrls: ['./search-filters.component.scss'],
templateUrl: './search-filters.component.html',
templateUrl: './themes/search-filters.component.mantis.html',
})
/**

View File

@@ -0,0 +1,7 @@
<h3>{{"search.filters.head" | translate}}</h3>
<div *ngIf="(filters | async)?.hasSucceeded">
<div *ngFor="let filter of (filters | async)?.payload">
<ds-search-filter [filter]="filter"></ds-search-filter>
</div>
</div>
<a class="btn btn-primary" [routerLink]="[getSearchLink()]" [queryParams]="clearParams | async" queryParamsHandling="merge" role="button">{{"search.filters.reset" | translate}}</a>

View File

@@ -0,0 +1,5 @@
@import '../../../styles/variables.scss';
.setting-option {
border: 1px solid map-get($theme-colors, light);
}

View File

@@ -1,5 +1,2 @@
@import '../../../styles/variables.scss';
.setting-option {
border: 1px solid map-get($theme-colors, light);
}
@import './search-settings.component.default';
@import './themes/*.scss';

View File

@@ -10,7 +10,8 @@ import { SEARCH_CONFIG_SERVICE } from '../../+my-dspace-page/my-dspace-page.comp
@Component({
selector: 'ds-search-settings',
styleUrls: ['./search-settings.component.scss'],
templateUrl: './search-settings.component.html'
// templateUrl: './search-settings.component.html'
templateUrl: './themes/search-settings.component.mantis.html'
})
/**

View File

@@ -0,0 +1,24 @@
<ng-container *ngVar="(searchOptions$ | async) as config">
<h3>{{ 'search.sidebar.settings.title' | translate}}</h3>
<div *ngIf="config?.sort" class="setting-option result-order-settings mb-3 px-3 py-2">
<h5 class="mb-0">{{ 'search.sidebar.settings.sort-by' | translate}}</h5>
<select class="form-control my-2" (change)="reloadOrder($event)">
<option *ngFor="let sortOption of searchOptionPossibilities"
[value]="sortOption.field + ',' + sortOption.direction.toString()"
[selected]="sortOption.field === config?.sort.field && sortOption.direction === (config?.sort.direction)? 'selected': null">
{{'sorting.' + sortOption.field + '.' + sortOption.direction | translate}}
</option>
</select>
</div>
<div class="setting-option page-size-settings mb-3 px-3 py-2">
<h5 class="mb-0">{{ 'search.sidebar.settings.rpp' | translate}}</h5>
<select class="form-control my-2" (change)="reloadRPP($event)">
<option *ngFor="let pageSizeOption of config?.pagination.pageSizeOptions"
[value]="pageSizeOption"
[selected]="pageSizeOption === +config?.pagination.pageSize ? 'selected': null">
{{pageSizeOption}}
</option>
</select>
</div>
</ng-container>

View File

@@ -0,0 +1,10 @@
@import '../../../../styles/variables.scss';
:host-context(.mantis) .setting-option {
background-color: map-get($theme-colors, light);
border-radius: $border-radius;
h5 {
font-size: 1.1rem
}
}

View File

@@ -1,4 +1,4 @@
<div class="outer-wrapper">
<div class="outer-wrapper mantis">
<ds-admin-sidebar></ds-admin-sidebar>
<div class="inner-wrapper" [@slideSidebarPadding]="{
value: (!(sidebarVisible | async) ? 'hidden' : (slideSidebarOver | async) ? 'shown' : 'expanded'),
@@ -9,7 +9,6 @@
<ds-notifications-board
[options]="config.notifications">
</ds-notifications-board>
<main class="main-content">
<div class="container" *ngIf="isLoading">
<ds-loading message="{{'loading.default' | translate}}"></ds-loading>

View File

@@ -48,4 +48,3 @@ ds-admin-sidebar {
position: fixed;
z-index: $sidebar-z-index;
}

View File

@@ -30,8 +30,9 @@ import { MenuService } from './shared/menu/menu.service';
import { MenuID } from './shared/menu/initial-menus-state';
import { Observable } from 'rxjs/internal/Observable';
import { slideSidebarPadding } from './shared/animations/slide';
import { combineLatest as combineLatestObservable } from 'rxjs';
import { combineLatest as combineLatestObservable, of } from 'rxjs';
import { HostWindowService } from './shared/host-window.service';
import { Theme } from '../config/theme.inferface';
@Component({
selector: 'ds-app',
@@ -47,6 +48,7 @@ export class AppComponent implements OnInit, AfterViewInit {
slideSidebarOver: Observable<boolean>;
collapsedSidebarWidth: Observable<string>;
totalSidebarWidth: Observable<string>;
theme: Observable<Theme>= of({} as any);
constructor(
@Inject(GLOBAL_CONFIG) public config: GlobalConfig,
@@ -60,8 +62,9 @@ export class AppComponent implements OnInit, AfterViewInit {
private routeService: RouteService,
private cssService: CSSVariableService,
private menuService: MenuService,
private windowService: HostWindowService
private windowService: HostWindowService,
) {
// Load all the languages that are defined as active from the config file
translate.addLangs(config.languages.filter((LangConfig) => LangConfig.active === true).map((a) => a.code));
@@ -83,10 +86,10 @@ export class AppComponent implements OnInit, AfterViewInit {
console.info(config);
}
this.storeCSSVariables();
}
ngOnInit() {
const env: string = this.config.production ? 'Production' : 'Development';
const color: string = this.config.production ? 'red' : 'green';
console.info(`Environment: %c${env}`, `color: ${color}; font-weight: bold;`);

View File

@@ -1,4 +1,3 @@
import { ObjectCacheEffects } from './cache/object-cache.effects';
import { UUIDIndexEffects } from './index/index.effects';
import { RequestEffects } from './data/request.effects';
@@ -14,5 +13,5 @@ export const coreEffects = [
AuthEffects,
JsonPatchOperationsEffects,
ServerSyncBufferEffects,
ObjectUpdatesEffects
ObjectUpdatesEffects,
];

View File

@@ -0,0 +1,12 @@
@import '../../styles/variables.scss';
.navbar-brand img {
height: $header-logo-height;
@media screen and (max-width: map-get($grid-breakpoints, sm)) {
height: $header-logo-height-xs;
}
}
.navbar-toggler .navbar-toggler-icon {
background-image: none !important;
line-height: 1.5;
}

View File

@@ -1,12 +1,2 @@
@import '../../styles/variables.scss';
.navbar-brand img {
height: $header-logo-height;
@media screen and (max-width: map-get($grid-breakpoints, sm)) {
height: $header-logo-height-xs;
}
}
.navbar-toggler .navbar-toggler-icon {
background-image: none !important;
line-height: 1.5;
}
@import './header.component.default';
@import './themes/*.scss';

View File

@@ -0,0 +1,7 @@
@import '../../../styles/variables.scss';
:host-context(.mantis) {
::ng-deep a {
//color: $dark;
}
}

View File

@@ -0,0 +1,39 @@
@import '../../styles/variables.scss';
nav.navbar {
border-bottom: 1px $gray-400 solid;
align-items: baseline;
}
/** Mobile menu styling **/
@media screen and (max-width: map-get($grid-breakpoints, md)) {
.navbar {
width: 100%;
background-color: $white;
position: absolute;
overflow: hidden;
height: 0;
&.open {
height: 100vh; //doesn't matter because wrapper is sticky
}
}
}
@media screen and (min-width: map-get($grid-breakpoints, md)) {
.reset-padding-md {
margin-left: -$spacer/2;
margin-right: -$spacer/2;
}
}
/* TODO remove when https://github.com/twbs/bootstrap/issues/24726 is fixed */
.navbar-expand-md.navbar-container {
@media screen and (max-width: map-get($grid-breakpoints, md)) {
> .container {
padding: 0 $spacer;
}
padding: 0;
}
}

View File

@@ -1,39 +1,3 @@
@import '../../styles/variables.scss';
nav.navbar {
border-bottom: 1px $gray-400 solid;
align-items: baseline;
}
/** Mobile menu styling **/
@media screen and (max-width: map-get($grid-breakpoints, md)) {
.navbar {
width: 100%;
background-color: $white;
position: absolute;
overflow: hidden;
height: 0;
&.open {
height: 100vh; //doesn't matter because wrapper is sticky
}
}
}
@media screen and (min-width: map-get($grid-breakpoints, md)) {
.reset-padding-md {
margin-left: -$spacer/2;
margin-right: -$spacer/2;
}
}
/* TODO remove when https://github.com/twbs/bootstrap/issues/24726 is fixed */
.navbar-expand-md.navbar-container {
@media screen and (max-width: map-get($grid-breakpoints, md)) {
> .container {
padding: 0 $spacer;
}
padding: 0;
}
}
@import './navbar.component.default';
@import './themes/*.scss';

View File

@@ -13,7 +13,8 @@ import { HostWindowService } from '../shared/host-window.service';
@Component({
selector: 'ds-navbar',
styleUrls: ['navbar.component.scss'],
templateUrl: 'navbar.component.html',
// templateUrl: './navbar.component.html',
templateUrl: './themes/navbar.component.mantis.html',
animations: [slideMobileNav]
})
export class NavbarComponent extends MenuComponent implements OnInit {

View File

@@ -0,0 +1,16 @@
<nav [ngClass]="{'open': !(menuCollapsed | async)}"
[@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 -->
<div class="container">
<div class="reset-padding-md w-100">
<div id="collapsingNav">
<ul class="navbar-nav mr-auto shadow-none">
<ng-container *ngFor="let section of (sections | async)">
<ng-container
*ngComponentOutlet="sectionComponents.get(section.id); injector: sectionInjectors.get(section.id);"></ng-container>
</ng-container>
</ul>
</div>
</div>
</div>
</nav>

View File

@@ -0,0 +1,9 @@
@import '../../../styles/variables.scss';
:host-context(.mantis) {
nav.navbar {
border-bottom: 5px $green solid;
}
}

View File

@@ -12,6 +12,7 @@
class="item-list-authors">
<span *ngFor="let author of allMetadataValues(['dc.contributor.author', 'dc.creator', 'dc.contributor.*']); let last=last;">
<span [innerHTML]="author"><span [innerHTML]="author"></span></span>
<span *ngIf="!last">; </span>
</span>
</span>
</ds-truncatable-part>

View File

@@ -14,7 +14,8 @@ import { MYDSPACE_ROUTE } from '../../+my-dspace-page/my-dspace-page.component';
@Component({
selector: 'ds-search-form',
styleUrls: ['./search-form.component.scss'],
templateUrl: './search-form.component.html'
// templateUrl: './search-form.component.html',
templateUrl: './themes/search-form.component.mantis.html'
})
/**
@@ -39,6 +40,16 @@ export class SearchFormComponent {
*/
@Input() scopes: DSpaceObject[];
/**
* Whether or not the search button should be displayed large
*/
@Input() large = false;
/**
* The brand color of the search button
*/
@Input() brandColor = 'primary';
constructor(private router: Router) {
}

View File

@@ -0,0 +1,21 @@
<form #form="ngForm" (ngSubmit)="onSubmit(form.value)" class="row" action="/search">
<div *ngIf="isNotEmpty(scopes)" class="col-12 col-sm-3">
<select [(ngModel)]="scope" name="scope" class="form-control" aria-label="Search scope"
(change)="onScopeChange($event.target.value)">
<option value>{{'search.form.search_dspace' | translate}}</option>
<option *ngFor="let scopeOption of scopes"
[value]="scopeOption.id">{{scopeOption?.name ? scopeOption.name : 'search.form.search_dspace' | translate}}</option>
</select>
</div>
<div [ngClass]="{'col-sm-9': isNotEmpty(scopes)}" class="col-12">
<div class="form-group input-group"
[ngClass]="{'input-group-lg': large}">
<input type="text" [(ngModel)]="query" name="query" class="form-control"
aria-label="Search input">
<span class="input-group-append">
<button type="submit"
class="search-button btn btn-{{brandColor}}">{{ ('search.form.search' | translate) }}</button>
</span>
</div>
</div>
</form>

View File

@@ -0,0 +1,4 @@
@import '../../../styles/variables.scss';
img {
width: 100%;
}

View File

@@ -9,7 +9,7 @@ import { Bitstream } from '../core/shared/bitstream.model';
@Component({
selector: 'ds-thumbnail',
styleUrls: ['./thumbnail.component.scss'],
styleUrls: ['./themes/thumbnail.component.mantis.scss'],
templateUrl: './thumbnail.component.html'
})
export class ThumbnailComponent {
@@ -21,7 +21,7 @@ export class ThumbnailComponent {
/**
* The default 'holder.js' image
*/
@Input() defaultImage? = 'data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2293%22%20height%3D%22120%22%20viewBox%3D%220%200%2093%20120%22%20preserveAspectRatio%3D%22none%22%3E%3C!--%0ASource%20URL%3A%20holder.js%2F93x120%3Ftext%3DNo%20Thumbnail%0ACreated%20with%20Holder.js%202.8.2.%0ALearn%20more%20at%20http%3A%2F%2Fholderjs.com%0A(c)%202012-2015%20Ivan%20Malopinsky%20-%20http%3A%2F%2Fimsky.co%0A--%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%3C!%5BCDATA%5B%23holder_1543e460b05%20text%20%7B%20fill%3A%23AAAAAA%3Bfont-weight%3Abold%3Bfont-family%3AArial%2C%20Helvetica%2C%20Open%20Sans%2C%20sans-serif%2C%20monospace%3Bfont-size%3A10pt%20%7D%20%5D%5D%3E%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_1543e460b05%22%3E%3Crect%20width%3D%2293%22%20height%3D%22120%22%20fill%3D%22%23EEEEEE%22%2F%3E%3Cg%3E%3Ctext%20x%3D%2235.6171875%22%20y%3D%2257%22%3ENo%3C%2Ftext%3E%3Ctext%20x%3D%2210.8125%22%20y%3D%2272%22%3EThumbnail%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E';
@Input() defaultImage? = 'data:image/svg+xml;charset=UTF-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%2293%22%20height%3D%22120%22%20viewBox%3D%220%200%2093%20120%22%20preserveAspectRatio%3D%22none%22%3E%3C!--%0ASource%20URL%3A%20holder.js%2F93x120%3Ftext%3DNo%20Thumbnail%0ACreated%20with%20Holder.js%202.8.2.%0ALearn%20more%20at%20http%3A%2F%2Fholderjs.com%0A(c)%202012-2015%20Ivan%20Malopinsky%20-%20http%3A%2F%2Fimsky.co%0A--%3E%3Cdefs%3E%3Cstyle%20type%3D%22text%2Fcss%22%3E%3C!%5BCDATA%5B%23holder_1543e460b05%20text%20%7B%20fill%3A%23AAAAAA%3Bfont-weight%3Abold%3Bfont-family%3AArial%2C%20Helvetica%2C%20Open%20Sans%2C%20sans-serif%2C%20monospace%3Bfont-size%3A10pt%20%7D%20%5D%5D%3E%3C%2Fstyle%3E%3C%2Fdefs%3E%3Cg%20id%3D%22holder_1543e460b05%22%3E%3Crect%20width%3D%2293%22%20height%3D%22120%22%20fill%3D%22%23FFFFFF%22%2F%3E%3Cg%3E%3Ctext%20x%3D%2235.6171875%22%20y%3D%2257%22%3ENo%3C%2Ftext%3E%3Ctext%20x%3D%2210.8125%22%20y%3D%2272%22%3EThumbnail%3C%2Ftext%3E%3C%2Fg%3E%3C%2Fg%3E%3C%2Fsvg%3E';
errorHandler(event) {
event.currentTarget.src = this.defaultImage;

View File

@@ -8,6 +8,7 @@ import { FormConfig } from './form-config.interfaces';
import {LangConfig} from './lang-config.interface';
import { BrowseByConfig } from './browse-by-config.interface';
import { ItemPageConfig } from './item-page-config.interface';
import { Theme } from './theme.inferface';
export interface GlobalConfig extends Config {
ui: ServerConfig;
@@ -25,4 +26,5 @@ export interface GlobalConfig extends Config {
languages: LangConfig[];
browseBy: BrowseByConfig;
item: ItemPageConfig;
themes: Theme[];
}

View File

@@ -0,0 +1,6 @@
import { Config } from './config.interface';
export interface Theme extends Config {
name: string;
cssClass: string;
}

View File

@@ -20,9 +20,9 @@ $sidebar-z-index: 20;
$header-logo-height: 80px;
$header-logo-height-xs: 50px;
$admin-sidebar-bg: $dark;
$admin-sidebar-active-bg: darken($dark, 3%);
$admin-sidebar-header-bg: darken($dark, 7%);
$admin-sidebar-bg: darken(#2B4E72, 17%);
$admin-sidebar-active-bg: darken($admin-sidebar-bg, 3%);
$admin-sidebar-header-bg: darken($admin-sidebar-bg, 7%);
$dark-scrollbar-background: $admin-sidebar-active-bg;
$dark-scrollbar-foreground: #47495d;
@@ -32,3 +32,5 @@ $submission-sections-margin-bottom: .5rem !default;
$edit-item-button-min-width: 100px;
$edit-item-metadata-field-width: 190px;
$edit-item-language-field-width: 43px;
$thumbnail-max-width: 175px;

View File

@@ -1,5 +1,7 @@
@import '_functions.scss';
@import '../../node_modules/bootstrap/scss/functions.scss';
@import 'themes/bootstrap_variables.mantis.scss';
@import 'bootstrap_variables.scss';
@import '../../node_modules/bootstrap/scss/variables.scss';
@import 'themes/custom_variables.mantis.scss';
@import 'custom_variables.scss';

View File

@@ -0,0 +1,19 @@
@import url('https://fonts.googleapis.com/css?family=Source+Sans+Pro:200,200i,300,300i,400,400i,600,600i,700,700i,900,900i&subset=cyrillic,cyrillic-ext,greek,greek-ext,latin-ext,vietnamese');
$font-family-sans-serif: 'Source Sans Pro', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
$gray-100: #e8ebf3 !default; // #eee
$gray-800: #444444 !default; // #444
$navbar-dark-color: #FFFFFF;
/* Reassign color vars to semantic color scheme */
$blue: #43515f !default;
$green: #92C642 !default;
$cyan: #2e80a3 !default;
$yellow: #ec9433 !default;
$red: #CF4444 !default;
$dark: #43515f !default;
$body-color: $gray-800 !default;
$yiq-contrasted-threshold: 170 !default;

View File

@@ -0,0 +1,2 @@
$banner-text-background: rgba(0, 0, 0, 0.45);
$banner-background-gradient-width: 300px;

View File

@@ -22,10 +22,11 @@ module.exports = {
module: "empty"
},
module: {
rules: [{
test: /\.ts$/,
loader: '@ngtools/webpack'
},
rules: [
{
test: /\.ts$/,
loader: '@ngtools/webpack'
},
{
test: /\.css$/,
use: [{
@@ -52,19 +53,20 @@ module.exports = {
{
test: /\.scss$/,
exclude: [/node_modules/,
path.resolve(__dirname, '..', 'src/styles/_exposed_variables.scss')
path.resolve(__dirname, '..', 'src/styles/_exposed_variables.scss')
],
use: [{
loader: 'to-string-loader',
options: {
sourceMap: true
}
}, {
loader: 'raw-loader',
options: {
sourceMap: true
}
},
use: [
{
loader: 'to-string-loader',
options: {
sourceMap: true
}
}, {
loader: 'raw-loader',
options: {
sourceMap: true
}
},
{
loader: 'resolve-url-loader',
options: {
@@ -76,7 +78,8 @@ module.exports = {
options: {
sourceMap: true
}
}
},
'webpack-import-glob-loader'
]
},
{

View File

@@ -165,7 +165,8 @@ module.exports = function (options) {
options: {
sourceMap: true
}
}
},
'webpack-import-glob-loader'
],
exclude: [root('src/index.html')]
},

View File

@@ -10939,6 +10939,12 @@ webpack-dev-server@^3.1.5:
webpack-log "^2.0.0"
yargs "12.0.1"
webpack-import-glob-loader@^1.6.3:
version "1.6.3"
resolved "https://registry.yarnpkg.com/webpack-import-glob-loader/-/webpack-import-glob-loader-1.6.3.tgz#1b1de573f49c2c2afdb814dc13b44b2111b2ea7b"
dependencies:
glob "^5.0.15"
webpack-log@^1.0.1:
version "1.2.0"
resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-1.2.0.tgz#a4b34cda6b22b518dbb0ab32e567962d5c72a43d"