mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 18:14:17 +00:00
Merge branch 'master' into w2p-44988_search-sidebar
Conflicts: resources/i18n/en.json src/app/+search-page/search-page.component.html
This commit is contained in:
@@ -7,9 +7,9 @@ describe('protractor App', () => {
|
||||
page = new ProtractorPage();
|
||||
});
|
||||
|
||||
it('should display title "DSpace"', () => {
|
||||
it('should display translated title "DSpace Angular :: Home"', () => {
|
||||
page.navigateTo();
|
||||
expect<any>(page.getPageTitleText()).toEqual('DSpace');
|
||||
expect<any>(page.getPageTitleText()).toEqual('DSpace Angular :: Home');
|
||||
});
|
||||
|
||||
it('should display header "Welcome to DSpace"', () => {
|
||||
|
@@ -27,18 +27,18 @@ module.exports = function (config) {
|
||||
frameworks: ['jasmine'],
|
||||
|
||||
plugins: [
|
||||
require('karma-webpack'),
|
||||
require('karma-jasmine'),
|
||||
require("istanbul-instrumenter-loader"),
|
||||
require('karma-chrome-launcher'),
|
||||
require('karma-phantomjs-launcher'),
|
||||
require('karma-webdriver-launcher'),
|
||||
require('karma-coverage'),
|
||||
require('karma-remap-coverage'),
|
||||
require("karma-istanbul-preprocessor"),
|
||||
require('karma-jasmine'),
|
||||
require('karma-mocha-reporter'),
|
||||
require('karma-phantomjs-launcher'),
|
||||
require('karma-remap-coverage'),
|
||||
require('karma-remap-istanbul'),
|
||||
require('karma-sourcemap-loader'),
|
||||
require("istanbul-instrumenter-loader"),
|
||||
require("karma-istanbul-preprocessor")
|
||||
require('karma-webdriver-launcher'),
|
||||
require('karma-webpack')
|
||||
],
|
||||
|
||||
// list of files to exclude
|
||||
@@ -59,7 +59,11 @@ module.exports = function (config) {
|
||||
* available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
|
||||
*/
|
||||
preprocessors: {
|
||||
'./spec-bundle.js': ['istanbul', 'webpack', 'sourcemap']
|
||||
'./spec-bundle.js': [
|
||||
'istanbul',
|
||||
'webpack',
|
||||
'sourcemap'
|
||||
]
|
||||
},
|
||||
|
||||
// Webpack Config at ./webpack.test.js
|
||||
@@ -79,9 +83,9 @@ module.exports = function (config) {
|
||||
remapIstanbulReporter: {
|
||||
remapOptions: {}, //additional remap options
|
||||
reports: {
|
||||
json: 'coverage/coverage.json',
|
||||
lcovonly: 'coverage/lcov.info',
|
||||
html: 'coverage/html/',
|
||||
json: './coverage/coverage.json',
|
||||
lcovonly: './coverage/lcov.info',
|
||||
html: './coverage/html/',
|
||||
}
|
||||
},
|
||||
|
||||
@@ -111,7 +115,12 @@ module.exports = function (config) {
|
||||
* possible values: 'dots', 'progress'
|
||||
* available reporters: https://npmjs.org/browse/keyword/karma-reporter
|
||||
*/
|
||||
reporters: ['mocha', 'coverage', 'remap-coverage', 'karma-remap-istanbul'],
|
||||
reporters: [
|
||||
'mocha',
|
||||
'coverage',
|
||||
'remap-coverage',
|
||||
'karma-remap-istanbul'
|
||||
],
|
||||
|
||||
// Karma web server port
|
||||
port: 9876,
|
||||
|
50
package.json
50
package.json
@@ -68,15 +68,15 @@
|
||||
"coverage": "http-server -c-1 -o -p 9875 ./coverage"
|
||||
},
|
||||
"dependencies": {
|
||||
"@angular/animations": "4.4.4",
|
||||
"@angular/common": "4.4.4",
|
||||
"@angular/core": "4.4.4",
|
||||
"@angular/forms": "4.4.4",
|
||||
"@angular/http": "4.4.4",
|
||||
"@angular/platform-browser": "4.4.4",
|
||||
"@angular/platform-browser-dynamic": "4.4.4",
|
||||
"@angular/platform-server": "4.4.4",
|
||||
"@angular/router": "4.4.4",
|
||||
"@angular/animations": "4.4.5",
|
||||
"@angular/common": "4.4.5",
|
||||
"@angular/core": "4.4.5",
|
||||
"@angular/forms": "4.4.5",
|
||||
"@angular/http": "4.4.5",
|
||||
"@angular/platform-browser": "4.4.5",
|
||||
"@angular/platform-browser-dynamic": "4.4.5",
|
||||
"@angular/platform-server": "4.4.5",
|
||||
"@angular/router": "4.4.5",
|
||||
"@angularclass/bootloader": "1.0.1",
|
||||
"@angularclass/idle-preload": "1.0.4",
|
||||
"@ng-bootstrap/ng-bootstrap": "1.0.0-beta.5",
|
||||
@@ -88,11 +88,11 @@
|
||||
"@ngx-translate/http-loader": "2.0.0",
|
||||
"body-parser": "1.18.2",
|
||||
"bootstrap": "v4.0.0-beta",
|
||||
"cerialize": "0.1.16",
|
||||
"cerialize": "0.1.18",
|
||||
"compression": "1.7.1",
|
||||
"cookie-parser": "1.4.3",
|
||||
"core-js": "2.5.1",
|
||||
"express": "4.16.1",
|
||||
"express": "4.16.2",
|
||||
"express-session": "1.15.6",
|
||||
"font-awesome": "4.7.0",
|
||||
"http-server": "0.10.0",
|
||||
@@ -102,7 +102,7 @@
|
||||
"methods": "1.1.2",
|
||||
"morgan": "1.9.0",
|
||||
"ngx-pagination": "3.0.1",
|
||||
"pem": "1.12.0",
|
||||
"pem": "1.12.3",
|
||||
"reflect-metadata": "0.1.10",
|
||||
"rxjs": "5.4.3",
|
||||
"ts-md5": "1.2.2",
|
||||
@@ -110,10 +110,10 @@
|
||||
"zone.js": "0.8.18"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@angular/compiler": "4.4.4",
|
||||
"@angular/compiler-cli": "4.4.4",
|
||||
"@angular/compiler": "4.4.5",
|
||||
"@angular/compiler-cli": "4.4.5",
|
||||
"@ngrx/store-devtools": "4.0.0",
|
||||
"@ngtools/webpack": "1.7.2",
|
||||
"@ngtools/webpack": "1.7.4",
|
||||
"@types/cookie-parser": "1.4.1",
|
||||
"@types/deep-freeze": "0.1.1",
|
||||
"@types/express": "4.0.37",
|
||||
@@ -122,19 +122,19 @@
|
||||
"@types/jasmine": "2.6.0",
|
||||
"@types/memory-cache": "0.0.31",
|
||||
"@types/mime": "2.0.0",
|
||||
"@types/node": "8.0.26",
|
||||
"@types/node": "8.0.34",
|
||||
"@types/serve-static": "1.7.32",
|
||||
"@types/source-map": "0.5.1",
|
||||
"@types/webfontloader": "1.6.29",
|
||||
"ajv": "5.2.3",
|
||||
"ajv-keywords": "2.1.0",
|
||||
"angular2-template-loader": "0.6.2",
|
||||
"autoprefixer": "7.1.4",
|
||||
"autoprefixer": "7.1.5",
|
||||
"awesome-typescript-loader": "3.2.3",
|
||||
"caniuse-lite": "1.0.30000697",
|
||||
"codelyzer": "3.2.0",
|
||||
"codelyzer": "3.2.1",
|
||||
"compression-webpack-plugin": "1.0.1",
|
||||
"copy-webpack-plugin": "4.1.0",
|
||||
"copy-webpack-plugin": "4.1.1",
|
||||
"coveralls": "3.0.0",
|
||||
"css-loader": "0.28.7",
|
||||
"deep-freeze": "0.0.1",
|
||||
@@ -143,7 +143,7 @@
|
||||
"imports-loader": "0.7.1",
|
||||
"istanbul-instrumenter-loader": "3.0.0",
|
||||
"jasmine-core": "2.8.0",
|
||||
"jasmine-marbles": "0.1.0",
|
||||
"jasmine-marbles": "0.2.0",
|
||||
"jasmine-spec-reporter": "4.2.1",
|
||||
"json-loader": "0.5.7",
|
||||
"karma": "1.7.1",
|
||||
@@ -158,7 +158,7 @@
|
||||
"karma-remap-istanbul": "0.6.0",
|
||||
"karma-sourcemap-loader": "0.3.7",
|
||||
"karma-webdriver-launcher": "1.0.5",
|
||||
"karma-webpack": "2.0.4",
|
||||
"karma-webpack": "2.0.5",
|
||||
"ngrx-store-freeze": "0.2.0",
|
||||
"node-sass": "4.5.3",
|
||||
"nodemon": "1.12.1",
|
||||
@@ -167,13 +167,13 @@
|
||||
"postcss-apply": "0.8.0",
|
||||
"postcss-cli": "4.1.1",
|
||||
"postcss-cssnext": "3.0.2",
|
||||
"postcss-loader": "2.0.6",
|
||||
"postcss-loader": "2.0.7",
|
||||
"postcss-responsive-type": "1.0.0",
|
||||
"postcss-smart-import": "0.7.5",
|
||||
"protractor": "5.1.2",
|
||||
"protractor-istanbul-plugin": "2.0.0",
|
||||
"raw-loader": "0.5.1",
|
||||
"resolve-url-loader": "2.1.0",
|
||||
"resolve-url-loader": "2.1.1",
|
||||
"rimraf": "2.6.2",
|
||||
"rollup": "0.50.0",
|
||||
"rollup-plugin-commonjs": "8.2.1",
|
||||
@@ -188,9 +188,9 @@
|
||||
"ts-helpers": "1.1.2",
|
||||
"ts-node": "3.3.0",
|
||||
"tslint": "5.7.0",
|
||||
"typedoc": "0.8.0",
|
||||
"typedoc": "0.9.0",
|
||||
"typescript": "2.5.3",
|
||||
"webpack": "3.6.0",
|
||||
"webpack": "3.7.1",
|
||||
"webpack-bundle-analyzer": "2.9.0",
|
||||
"webpack-dev-middleware": "1.12.0",
|
||||
"webpack-dev-server": "2.9.1",
|
||||
|
@@ -65,12 +65,16 @@
|
||||
}
|
||||
},
|
||||
"home": {
|
||||
"title": "DSpace Angular :: Home",
|
||||
"description": "",
|
||||
"top-level-communities": {
|
||||
"head": "Communities in DSpace",
|
||||
"help": "Select a community to browse its collections."
|
||||
}
|
||||
},
|
||||
"search": {
|
||||
"title": "DSpace Angular :: Search",
|
||||
"description": "",
|
||||
"form": {
|
||||
"search": "Search",
|
||||
"search_dspace": "Search DSpace"
|
||||
@@ -82,6 +86,10 @@
|
||||
"close": "Back to results",
|
||||
"open": "Search Tools",
|
||||
"results": "results"
|
||||
},
|
||||
"view-switch": {
|
||||
"show-list": "Show as list",
|
||||
"show-grid": "Show as grid"
|
||||
}
|
||||
},
|
||||
"loading": {
|
||||
|
@@ -38,25 +38,11 @@ testing.TestBed.initTestEnvironment(
|
||||
browser.platformBrowserDynamicTesting()
|
||||
);
|
||||
|
||||
/*
|
||||
* Ok, this is kinda crazy. We can use the context method on
|
||||
* require that webpack created in order to tell webpack
|
||||
* what files we actually want to require or import.
|
||||
* Below, context will be a function/object with file names as keys.
|
||||
* Using that regex we are saying look in ../src then find
|
||||
* any file that ends with spec.ts and get its path. By passing in true
|
||||
* we say do this recursively
|
||||
*/
|
||||
var testContext = require.context('./src', true, /\.spec\.ts/);
|
||||
var tests = require.context('./src', true, /\.spec\.ts$/);
|
||||
|
||||
/*
|
||||
* get all the files, for each file, call the context function
|
||||
* that will require the file and load it up here. Context will
|
||||
* loop and require those spec files here
|
||||
*/
|
||||
function requireAll(requireContext) {
|
||||
return requireContext.keys().map(requireContext);
|
||||
}
|
||||
tests.keys().forEach(tests);
|
||||
|
||||
// requires and returns all modules that match
|
||||
var modules = requireAll(testContext);
|
||||
// includes all modules into test coverage
|
||||
const modules = require.context('./src/app', true, /\.module\.ts$/);
|
||||
|
||||
modules.keys().forEach(modules);
|
||||
|
@@ -10,4 +10,6 @@ import { CollectionPageComponent } from './collection-page.component';
|
||||
])
|
||||
]
|
||||
})
|
||||
export class CollectionPageRoutingModule { }
|
||||
export class CollectionPageRoutingModule {
|
||||
|
||||
}
|
||||
|
@@ -7,6 +7,8 @@ import {
|
||||
} from '@angular/core';
|
||||
import { ActivatedRoute, Params } from '@angular/router';
|
||||
|
||||
import { PageInfo } from '../core/shared/page-info.model';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
|
||||
import { Collection } from '../core/shared/collection.model';
|
||||
@@ -18,8 +20,8 @@ import { Item } from '../core/shared/item.model';
|
||||
import { SortOptions, SortDirection } from '../core/cache/models/sort-options.model';
|
||||
import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model';
|
||||
import { hasValue, isNotEmpty, isUndefined } from '../shared/empty.util';
|
||||
import { PageInfo } from '../core/shared/page-info.model';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
import { MetadataService } from '../core/metadata/metadata.service';
|
||||
|
||||
import { fadeIn, fadeInOut } from '../shared/animations/fade';
|
||||
|
||||
@@ -41,9 +43,12 @@ export class CollectionPageComponent implements OnInit, OnDestroy {
|
||||
private subs: Subscription[] = [];
|
||||
private collectionId: string;
|
||||
|
||||
constructor(private collectionDataService: CollectionDataService,
|
||||
constructor(
|
||||
private collectionDataService: CollectionDataService,
|
||||
private itemDataService: ItemDataService,
|
||||
private route: ActivatedRoute) {
|
||||
private metadata: MetadataService,
|
||||
private route: ActivatedRoute
|
||||
) {
|
||||
this.paginationConfig = new PaginationComponentOptions();
|
||||
this.paginationConfig.id = 'collection-page-pagination';
|
||||
this.paginationConfig.pageSizeOptions = [4];
|
||||
@@ -63,6 +68,7 @@ export class CollectionPageComponent implements OnInit, OnDestroy {
|
||||
.subscribe((params) => {
|
||||
this.collectionId = params.id;
|
||||
this.collectionData = this.collectionDataService.findById(this.collectionId);
|
||||
this.metadata.processRemoteData(this.collectionData);
|
||||
this.subs.push(this.collectionData.payload.subscribe((collection) => this.logoData = collection.logo));
|
||||
|
||||
const page = +params.page || this.paginationConfig.currentPage;
|
||||
|
@@ -10,4 +10,6 @@ import { CommunityPageComponent } from './community-page.component';
|
||||
])
|
||||
]
|
||||
})
|
||||
export class CommunityPageRoutingModule { }
|
||||
export class CommunityPageRoutingModule {
|
||||
|
||||
}
|
||||
|
@@ -9,6 +9,8 @@ import { RemoteData } from '../core/data/remote-data';
|
||||
import { CommunityDataService } from '../core/data/community-data.service';
|
||||
import { hasValue } from '../shared/empty.util';
|
||||
|
||||
import { MetadataService } from '../core/metadata/metadata.service';
|
||||
|
||||
import { fadeInOut } from '../shared/animations/fade';
|
||||
|
||||
@Component({
|
||||
@@ -24,6 +26,7 @@ export class CommunityPageComponent implements OnInit, OnDestroy {
|
||||
|
||||
constructor(
|
||||
private communityDataService: CommunityDataService,
|
||||
private metadata: MetadataService,
|
||||
private route: ActivatedRoute
|
||||
) {
|
||||
|
||||
@@ -32,15 +35,13 @@ export class CommunityPageComponent implements OnInit, OnDestroy {
|
||||
ngOnInit(): void {
|
||||
this.route.params.subscribe((params: Params) => {
|
||||
this.communityData = this.communityDataService.findById(params.id);
|
||||
this.subs.push(this.communityData.payload
|
||||
.subscribe((community) => this.logoData = community.logo));
|
||||
this.metadata.processRemoteData(this.communityData);
|
||||
this.subs.push(this.communityData.payload.subscribe((community) => this.logoData = community.logo));
|
||||
});
|
||||
}
|
||||
|
||||
ngOnDestroy(): void {
|
||||
this.subs
|
||||
.filter((sub) => hasValue(sub))
|
||||
.forEach((sub) => sub.unsubscribe());
|
||||
this.subs.filter((sub) => hasValue(sub)).forEach((sub) => sub.unsubscribe());
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -6,7 +6,7 @@ import { HomePageComponent } from './home-page.component';
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild([
|
||||
{ path: '', component: HomePageComponent, pathMatch: 'full' }
|
||||
{ path: '', component: HomePageComponent, pathMatch: 'full', data: { title: 'home.title' } }
|
||||
])
|
||||
]
|
||||
})
|
||||
|
@@ -1,15 +1,17 @@
|
||||
import { Component, OnInit } from '@angular/core';
|
||||
import { animate, state, transition, trigger, style, keyframes } from '@angular/animations';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
import { ItemPageComponent } from '../simple/item-page.component';
|
||||
import { Metadatum } from '../../core/shared/metadatum.model';
|
||||
import { ItemDataService } from '../../core/data/item-data.service';
|
||||
import { ActivatedRoute } from '@angular/router';
|
||||
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { Item } from '../../core/shared/item.model';
|
||||
|
||||
import { MetadataService } from '../../core/metadata/metadata.service';
|
||||
|
||||
import { fadeInOut } from '../../shared/animations/fade';
|
||||
|
||||
/**
|
||||
@@ -30,8 +32,8 @@ export class FullItemPageComponent extends ItemPageComponent implements OnInit {
|
||||
|
||||
metadata: Observable<Metadatum[]>;
|
||||
|
||||
constructor(route: ActivatedRoute, items: ItemDataService) {
|
||||
super(route, items);
|
||||
constructor(route: ActivatedRoute, items: ItemDataService, metadataService: MetadataService) {
|
||||
super(route, items, metadataService);
|
||||
}
|
||||
|
||||
/*** AoT inheritance fix, will hopefully be resolved in the near future **/
|
||||
|
@@ -8,6 +8,8 @@ import { ItemDataService } from '../../core/data/item-data.service';
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { Bitstream } from '../../core/shared/bitstream.model';
|
||||
|
||||
import { MetadataService } from '../../core/metadata/metadata.service';
|
||||
|
||||
import { fadeInOut } from '../../shared/animations/fade';
|
||||
|
||||
/**
|
||||
@@ -31,7 +33,11 @@ export class ItemPageComponent implements OnInit {
|
||||
|
||||
thumbnail: Observable<Bitstream>;
|
||||
|
||||
constructor(private route: ActivatedRoute, private items: ItemDataService) {
|
||||
constructor(
|
||||
private route: ActivatedRoute,
|
||||
private items: ItemDataService,
|
||||
private metadataService: MetadataService
|
||||
) {
|
||||
|
||||
}
|
||||
|
||||
@@ -44,6 +50,7 @@ export class ItemPageComponent implements OnInit {
|
||||
initialize(params) {
|
||||
this.id = +params.id;
|
||||
this.item = this.items.findById(params.id);
|
||||
this.metadataService.processRemoteData(this.item);
|
||||
this.thumbnail = this.item.payload.flatMap((i) => i.getThumbnail());
|
||||
}
|
||||
|
||||
|
@@ -1,7 +1,13 @@
|
||||
import { SortOptions } from '../core/cache/models/sort-options.model';
|
||||
import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model';
|
||||
|
||||
export enum ViewMode {
|
||||
List = 'list',
|
||||
Grid = 'grid'
|
||||
}
|
||||
|
||||
export class SearchOptions {
|
||||
pagination?: PaginationComponentOptions;
|
||||
sort?: SortOptions;
|
||||
view?: ViewMode = ViewMode.List;
|
||||
}
|
||||
|
@@ -6,7 +6,7 @@ import { SearchPageComponent } from './search-page.component';
|
||||
@NgModule({
|
||||
imports: [
|
||||
RouterModule.forChild([
|
||||
{ path: '', component: SearchPageComponent }
|
||||
{ path: '', component: SearchPageComponent, data: { title: 'search.title' } }
|
||||
])
|
||||
]
|
||||
})
|
||||
|
@@ -3,6 +3,8 @@
|
||||
<ds-layout-controls class="col-md-3 d-none d-md-block sidebar-md-fixed"
|
||||
[isList]="isListView"
|
||||
(toggleList)="setListView($event)"></ds-layout-controls>
|
||||
|
||||
<ds-view-mode-switch></ds-view-mode-switch>
|
||||
<ds-search-form id="search-form" class="col-12 col-md-9 ml-md-auto"
|
||||
[query]="query"
|
||||
[scope]="scopeObject?.payload | async"
|
||||
@@ -17,6 +19,8 @@
|
||||
(toggleSidebar)="setSidebarActive($event)"></ds-search-sidebar>
|
||||
<div id="search-content" class="col-12 col-md-9 ml-md-auto">
|
||||
<div class="d-block d-md-none search-controls clearfix">
|
||||
|
||||
<ds-view-mode-switch></ds-view-mode-switch>
|
||||
<ds-layout-controls [isList]="isListView"
|
||||
(toggleList)="setListView($event)"></ds-layout-controls>
|
||||
<button (click)="setSidebarActive(true)" aria-controls="#search-body"
|
||||
|
@@ -6,6 +6,7 @@ import { SearchResult } from './search-result.model';
|
||||
import { DSpaceObject } from '../core/shared/dspace-object.model';
|
||||
import { SortOptions } from '../core/cache/models/sort-options.model';
|
||||
import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model';
|
||||
import { ViewModeSwitchComponent } from '../shared/view-mode-switch/view-mode-switch.component';
|
||||
import { SearchOptions } from './search-options.model';
|
||||
import { CommunityDataService } from '../core/data/community-data.service';
|
||||
import { isNotEmpty } from '../shared/empty.util';
|
||||
|
56
src/app/+search-page/search-service/search.service.spec.ts
Normal file
56
src/app/+search-page/search-service/search.service.spec.ts
Normal file
@@ -0,0 +1,56 @@
|
||||
import { TestBed, fakeAsync, tick } from '@angular/core/testing';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
|
||||
import { CommonModule } from '@angular/common';
|
||||
import { Component } from '@angular/core';
|
||||
import { Router } from '@angular/router';
|
||||
|
||||
import { SearchService } from './search.service';
|
||||
import { ItemDataService } from './../../core/data/item-data.service';
|
||||
import { ViewMode } from '../../+search-page/search-options.model';
|
||||
|
||||
@Component({ template: '' })
|
||||
class DummyComponent { }
|
||||
|
||||
describe('SearchService', () => {
|
||||
let searchService: SearchService;
|
||||
|
||||
beforeEach(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
RouterTestingModule.withRoutes([
|
||||
{ path: 'search', component: DummyComponent, pathMatch: 'full' },
|
||||
])
|
||||
],
|
||||
declarations: [
|
||||
DummyComponent
|
||||
],
|
||||
providers: [
|
||||
{ provide: ItemDataService, useValue: {} },
|
||||
SearchService
|
||||
],
|
||||
});
|
||||
searchService = TestBed.get(SearchService);
|
||||
});
|
||||
|
||||
it('should return list view mode by default', () => {
|
||||
searchService.getViewMode().subscribe((viewMode) => {
|
||||
expect(viewMode).toBe(ViewMode.List);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return the view mode set through setViewMode', fakeAsync(() => {
|
||||
searchService.setViewMode(ViewMode.Grid)
|
||||
tick();
|
||||
let viewMode = ViewMode.List;
|
||||
searchService.getViewMode().subscribe((mode) => viewMode = mode);
|
||||
expect(viewMode).toBe(ViewMode.Grid);
|
||||
|
||||
searchService.setViewMode(ViewMode.List)
|
||||
tick();
|
||||
searchService.getViewMode().subscribe((mode) => viewMode = mode);
|
||||
expect(viewMode).toBe(ViewMode.List);
|
||||
}));
|
||||
|
||||
});
|
@@ -13,6 +13,8 @@ import { ItemSearchResult } from '../../object-list/search-result-list-element/i
|
||||
import { SearchFilterConfig } from './search-filter-config.model';
|
||||
import { FilterType } from './filter-type.model';
|
||||
import { FacetValue } from './facet-value.model';
|
||||
import { ViewMode } from '../../+search-page/search-options.model';
|
||||
import { Router, NavigationExtras, ActivatedRoute } from '@angular/router';
|
||||
|
||||
function shuffle(array: any[]) {
|
||||
let i = 0;
|
||||
@@ -76,7 +78,10 @@ export class SearchService {
|
||||
})
|
||||
];
|
||||
|
||||
constructor(private itemDataService: ItemDataService) {
|
||||
constructor(
|
||||
private itemDataService: ItemDataService,
|
||||
private route: ActivatedRoute,
|
||||
private router: Router) {
|
||||
|
||||
}
|
||||
|
||||
@@ -192,4 +197,23 @@ export class SearchService {
|
||||
Observable.of(values)
|
||||
);
|
||||
}
|
||||
|
||||
getViewMode(): Observable<ViewMode> {
|
||||
return this.route.queryParams.map((params) => {
|
||||
if (isNotEmpty(params.view) && hasValue(params.view)) {
|
||||
return params.view;
|
||||
} else {
|
||||
return ViewMode.List;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
setViewMode(viewMode: ViewMode) {
|
||||
const navigationExtras: NavigationExtras = {
|
||||
queryParams: {view: viewMode},
|
||||
queryParamsHandling: 'merge'
|
||||
};
|
||||
|
||||
this.router.navigate(['/search'], navigationExtras);
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,3 @@
|
||||
// ... test imports
|
||||
import {
|
||||
async,
|
||||
ComponentFixture,
|
||||
@@ -23,14 +22,18 @@ import { AppComponent } from './app.component';
|
||||
|
||||
import { HostWindowState } from './shared/host-window.reducer';
|
||||
import { HostWindowResizeAction } from './shared/host-window.actions';
|
||||
import { MockTranslateLoader } from './shared/testing/mock-translate-loader';
|
||||
|
||||
import { BrowserTransferStateModule } from '../modules/transfer-state/browser-transfer-state.module';
|
||||
import { BrowserTransferStoreModule } from '../modules/transfer-store/browser-transfer-store.module';
|
||||
|
||||
import { MetadataService } from './core/metadata/metadata.service';
|
||||
|
||||
import { GLOBAL_CONFIG, ENV_CONFIG } from '../config';
|
||||
import { NativeWindowRef, NativeWindowService } from './shared/window.service';
|
||||
|
||||
import { MockTranslateLoader } from './shared/mocks/mock-translate-loader';
|
||||
import { MockMetadataService } from './shared/mocks/mock-metadata-service';
|
||||
|
||||
let comp: AppComponent;
|
||||
let fixture: ComponentFixture<AppComponent>;
|
||||
let de: DebugElement;
|
||||
@@ -57,6 +60,7 @@ describe('App component', () => {
|
||||
providers: [
|
||||
{ provide: GLOBAL_CONFIG, useValue: ENV_CONFIG },
|
||||
{ provide: NativeWindowService, useValue: new NativeWindowRef() },
|
||||
{ provide: MetadataService, useValue: new MockMetadataService() },
|
||||
AppComponent
|
||||
],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
|
@@ -12,12 +12,10 @@ import { TranslateService } from '@ngx-translate/core';
|
||||
import { Store } from '@ngrx/store';
|
||||
|
||||
import { TransferState } from '../modules/transfer-state/transfer-state';
|
||||
|
||||
import { HostWindowState } from './shared/host-window.reducer';
|
||||
|
||||
import { HostWindowResizeAction } from './shared/host-window.actions';
|
||||
|
||||
import { NativeWindowRef, NativeWindowService } from './shared/window.service';
|
||||
import { MetadataService } from './core/metadata/metadata.service';
|
||||
|
||||
import { GLOBAL_CONFIG, GlobalConfig } from '../config';
|
||||
|
||||
@@ -35,13 +33,16 @@ export class AppComponent implements OnInit {
|
||||
@Inject(NativeWindowService) private _window: NativeWindowRef,
|
||||
private translate: TranslateService,
|
||||
private cache: TransferState,
|
||||
private store: Store<HostWindowState>
|
||||
private store: Store<HostWindowState>,
|
||||
private metadata: MetadataService
|
||||
) {
|
||||
// this language will be used as a fallback when a translation isn't found in the current language
|
||||
translate.setDefaultLang('en');
|
||||
// the lang to use, if the lang isn't available, it will use the current loader to get them
|
||||
translate.use('en');
|
||||
|
||||
metadata.listenForRouteChange();
|
||||
|
||||
if (config.debug) {
|
||||
console.info(config);
|
||||
}
|
||||
|
@@ -1,13 +1,30 @@
|
||||
import { inheritSerialization } from 'cerialize';
|
||||
import { inheritSerialization, autoserialize } from 'cerialize';
|
||||
|
||||
import { mapsTo } from '../builders/build-decorators';
|
||||
|
||||
import { BitstreamFormat } from '../../shared/bitstream-format.model';
|
||||
import { NormalizedObject } from './normalized-object.model';
|
||||
|
||||
@mapsTo(BitstreamFormat)
|
||||
@inheritSerialization(NormalizedObject)
|
||||
export class NormalizedBitstreamFormat extends NormalizedObject {
|
||||
// TODO: this class was created as a placeholder when we connected to the live rest api
|
||||
|
||||
get uuid(): string {
|
||||
return this.self;
|
||||
}
|
||||
@autoserialize
|
||||
shortDescription: string;
|
||||
|
||||
@autoserialize
|
||||
description: string;
|
||||
|
||||
@autoserialize
|
||||
mimetype: string;
|
||||
|
||||
@autoserialize
|
||||
supportLevel: number;
|
||||
|
||||
@autoserialize
|
||||
internal: boolean;
|
||||
|
||||
@autoserialize
|
||||
extensions: string;
|
||||
|
||||
}
|
||||
|
@@ -21,16 +21,11 @@ export class NormalizedBitstream extends NormalizedDSpaceObject {
|
||||
@autoserialize
|
||||
content: string;
|
||||
|
||||
/**
|
||||
* The mime type of this Bitstream
|
||||
*/
|
||||
@autoserialize
|
||||
mimetype: string;
|
||||
|
||||
/**
|
||||
* The format of this Bitstream
|
||||
*/
|
||||
@autoserialize
|
||||
@relationship(ResourceType.BitstreamFormat, false)
|
||||
format: string;
|
||||
|
||||
/**
|
||||
|
@@ -15,11 +15,9 @@ export class NormalizedObjectFactory {
|
||||
case ResourceType.Bitstream: {
|
||||
return NormalizedBitstream
|
||||
}
|
||||
// commented out for now, bitstreamformats aren't used in the UI yet
|
||||
// and slow things down noticeably
|
||||
// case ResourceType.BitstreamFormat: {
|
||||
// return NormalizedBitstreamFormat
|
||||
// }
|
||||
case ResourceType.BitstreamFormat: {
|
||||
return NormalizedBitstreamFormat
|
||||
}
|
||||
case ResourceType.Bundle: {
|
||||
return NormalizedBundle
|
||||
}
|
||||
|
@@ -1,29 +1,35 @@
|
||||
import { NgModule, Optional, SkipSelf, ModuleWithProviders } from '@angular/core';
|
||||
import {
|
||||
NgModule,
|
||||
Optional,
|
||||
SkipSelf,
|
||||
ModuleWithProviders
|
||||
} from '@angular/core';
|
||||
import { CommonModule } from '@angular/common';
|
||||
|
||||
import { isNotEmpty } from '../shared/empty.util';
|
||||
import { DSpaceRESTv2Service } from './dspace-rest-v2/dspace-rest-v2.service';
|
||||
import { ObjectCacheService } from './cache/object-cache.service';
|
||||
import { ResponseCacheService } from './cache/response-cache.service';
|
||||
import { CollectionDataService } from './data/collection-data.service';
|
||||
import { ItemDataService } from './data/item-data.service';
|
||||
import { RequestService } from './data/request.service';
|
||||
import { RemoteDataBuildService } from './cache/builders/remote-data-build.service';
|
||||
import { CommunityDataService } from './data/community-data.service';
|
||||
import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model';
|
||||
import { coreEffects } from './core.effects';
|
||||
import { EffectsModule } from '@ngrx/effects';
|
||||
import { StoreModule } from '@ngrx/store';
|
||||
import { EffectsModule } from '@ngrx/effects';
|
||||
|
||||
import { coreEffects } from './core.effects';
|
||||
import { coreReducers } from './core.reducers';
|
||||
import { DSOResponseParsingService } from './data/dso-response-parsing.service';
|
||||
import { RootResponseParsingService } from './data/root-response-parsing.service';
|
||||
|
||||
import { isNotEmpty } from '../shared/empty.util';
|
||||
|
||||
import { ApiService } from '../shared/api.service';
|
||||
|
||||
import { CollectionDataService } from './data/collection-data.service';
|
||||
import { CommunityDataService } from './data/community-data.service';
|
||||
import { DSOResponseParsingService } from './data/dso-response-parsing.service';
|
||||
import { DSpaceRESTv2Service } from './dspace-rest-v2/dspace-rest-v2.service';
|
||||
import { HostWindowService } from '../shared/host-window.service';
|
||||
import { NativeWindowFactory, NativeWindowService } from '../shared/window.service';
|
||||
|
||||
import { ItemDataService } from './data/item-data.service';
|
||||
import { MetadataService } from './metadata/metadata.service';
|
||||
import { ObjectCacheService } from './cache/object-cache.service';
|
||||
import { PaginationComponentOptions } from '../shared/pagination/pagination-component-options.model';
|
||||
import { RemoteDataBuildService } from './cache/builders/remote-data-build.service';
|
||||
import { RequestService } from './data/request.service';
|
||||
import { ResponseCacheService } from './cache/response-cache.service';
|
||||
import { RootResponseParsingService } from './data/root-response-parsing.service';
|
||||
import { ServerResponseService } from '../shared/server-response.service';
|
||||
import { NativeWindowFactory, NativeWindowService } from '../shared/window.service';
|
||||
|
||||
const IMPORTS = [
|
||||
CommonModule,
|
||||
@@ -47,6 +53,7 @@ const PROVIDERS = [
|
||||
DSpaceRESTv2Service,
|
||||
HostWindowService,
|
||||
ItemDataService,
|
||||
MetadataService,
|
||||
ObjectCacheService,
|
||||
PaginationComponentOptions,
|
||||
RemoteDataBuildService,
|
||||
|
@@ -3,7 +3,10 @@ import { CacheableObject } from '../cache/object-cache.reducer';
|
||||
import { hasValue, isNotEmpty } from '../../shared/empty.util';
|
||||
import { RemoteData } from './remote-data';
|
||||
import {
|
||||
FindAllOptions, FindAllRequest, FindByIDRequest, RestRequest,
|
||||
FindAllOptions,
|
||||
FindAllRequest,
|
||||
FindByIDRequest,
|
||||
RestRequest,
|
||||
RootEndpointRequest
|
||||
} from './request.models';
|
||||
import { Store } from '@ngrx/store';
|
||||
|
226
src/app/core/metadata/metadata.service.spec.ts
Normal file
226
src/app/core/metadata/metadata.service.spec.ts
Normal file
@@ -0,0 +1,226 @@
|
||||
import { ComponentFixture, TestBed, async, fakeAsync, inject, tick } from '@angular/core/testing';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
|
||||
import { Location, CommonModule } from '@angular/common';
|
||||
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
|
||||
import { By, Meta, MetaDefinition, Title } from '@angular/platform-browser';
|
||||
import { ActivatedRoute, Router } from '@angular/router';
|
||||
|
||||
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
|
||||
|
||||
import { Store, StoreModule } from '@ngrx/store';
|
||||
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
import { MetadataService } from './metadata.service';
|
||||
|
||||
import { CoreState } from '../core.reducers';
|
||||
|
||||
import { GlobalConfig } from '../../../config/global-config.interface';
|
||||
import { ENV_CONFIG, GLOBAL_CONFIG } from '../../../config';
|
||||
|
||||
import { ItemDataService } from '../data/item-data.service';
|
||||
import { ObjectCacheService } from '../cache/object-cache.service';
|
||||
import { RemoteDataBuildService } from '../cache/builders/remote-data-build.service';
|
||||
import { RequestService } from '../data/request.service';
|
||||
import { ResponseCacheService } from '../cache/response-cache.service';
|
||||
|
||||
import { RemoteData } from '../../core/data/remote-data';
|
||||
import { Item } from '../../core/shared/item.model';
|
||||
|
||||
import { MockItem } from '../../shared/mocks/mock-item';
|
||||
import { MockTranslateLoader } from '../../shared/mocks/mock-translate-loader';
|
||||
|
||||
/* tslint:disable:max-classes-per-file */
|
||||
@Component({
|
||||
template: `<router-outlet></router-outlet>`
|
||||
})
|
||||
class TestComponent {
|
||||
constructor(private metadata: MetadataService) {
|
||||
metadata.listenForRouteChange();
|
||||
}
|
||||
}
|
||||
|
||||
@Component({ template: '' }) class DummyItemComponent {
|
||||
constructor(private route: ActivatedRoute, private items: ItemDataService, private metadata: MetadataService) {
|
||||
this.route.params.subscribe((params) => {
|
||||
this.metadata.processRemoteData(this.items.findById(params.id));
|
||||
});
|
||||
}
|
||||
}
|
||||
/* tslint:enable:max-classes-per-file */
|
||||
|
||||
describe('MetadataService', () => {
|
||||
let metadataService: MetadataService;
|
||||
|
||||
let meta: Meta;
|
||||
|
||||
let title: Title;
|
||||
|
||||
let store: Store<CoreState>;
|
||||
|
||||
let objectCacheService: ObjectCacheService;
|
||||
let responseCacheService: ResponseCacheService;
|
||||
let requestService: RequestService;
|
||||
let remoteDataBuildService: RemoteDataBuildService;
|
||||
let itemDataService: ItemDataService;
|
||||
|
||||
let location: Location;
|
||||
let router: Router;
|
||||
let fixture: ComponentFixture<TestComponent>;
|
||||
|
||||
let tagStore: Map<string, MetaDefinition[]>;
|
||||
|
||||
let envConfig: GlobalConfig;
|
||||
|
||||
beforeEach(() => {
|
||||
|
||||
store = new Store<CoreState>(undefined, undefined, undefined);
|
||||
spyOn(store, 'dispatch');
|
||||
|
||||
objectCacheService = new ObjectCacheService(store);
|
||||
responseCacheService = new ResponseCacheService(store);
|
||||
requestService = new RequestService(objectCacheService, responseCacheService, store);
|
||||
remoteDataBuildService = new RemoteDataBuildService(objectCacheService, responseCacheService, requestService);
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
StoreModule.forRoot({}),
|
||||
TranslateModule.forRoot({
|
||||
loader: {
|
||||
provide: TranslateLoader,
|
||||
useClass: MockTranslateLoader
|
||||
}
|
||||
}),
|
||||
RouterTestingModule.withRoutes([
|
||||
{ path: 'items/:id', component: DummyItemComponent, pathMatch: 'full' },
|
||||
{ path: 'other', component: DummyItemComponent, pathMatch: 'full', data: { title: 'Dummy Title', description: 'This is a dummy item component for testing!' } }
|
||||
])
|
||||
],
|
||||
declarations: [
|
||||
TestComponent,
|
||||
DummyItemComponent
|
||||
],
|
||||
providers: [
|
||||
{ provide: ObjectCacheService, useValue: objectCacheService },
|
||||
{ provide: ResponseCacheService, useValue: responseCacheService },
|
||||
{ provide: RequestService, useValue: requestService },
|
||||
{ provide: RemoteDataBuildService, useValue: remoteDataBuildService },
|
||||
{ provide: GLOBAL_CONFIG, useValue: ENV_CONFIG },
|
||||
Meta,
|
||||
Title,
|
||||
ItemDataService,
|
||||
MetadataService
|
||||
],
|
||||
schemas: [CUSTOM_ELEMENTS_SCHEMA]
|
||||
});
|
||||
meta = TestBed.get(Meta);
|
||||
title = TestBed.get(Title);
|
||||
itemDataService = TestBed.get(ItemDataService);
|
||||
metadataService = TestBed.get(MetadataService);
|
||||
|
||||
envConfig = TestBed.get(GLOBAL_CONFIG);
|
||||
|
||||
router = TestBed.get(Router);
|
||||
location = TestBed.get(Location);
|
||||
|
||||
fixture = TestBed.createComponent(TestComponent);
|
||||
|
||||
tagStore = metadataService.getTagStore();
|
||||
});
|
||||
|
||||
it('items page should set meta tags', fakeAsync(() => {
|
||||
spyOn(itemDataService, 'findById').and.returnValue(mockRemoteData(MockItem));
|
||||
router.navigate(['/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357']);
|
||||
tick();
|
||||
expect(title.getTitle()).toEqual('Test PowerPoint Document');
|
||||
expect(tagStore.get('citation_title')[0].content).toEqual('Test PowerPoint Document');
|
||||
expect(tagStore.get('citation_author')[0].content).toEqual('Doe, Jane');
|
||||
expect(tagStore.get('citation_date')[0].content).toEqual('1650-06-26T19:58:25Z');
|
||||
expect(tagStore.get('citation_issn')[0].content).toEqual('123456789');
|
||||
expect(tagStore.get('citation_language')[0].content).toEqual('en');
|
||||
expect(tagStore.get('citation_keywords')[0].content).toEqual('keyword1; keyword2; keyword3');
|
||||
}));
|
||||
|
||||
it('items page should set meta tags as published Thesis', fakeAsync(() => {
|
||||
spyOn(itemDataService, 'findById').and.returnValue(mockRemoteData(mockPublisher(mockType(MockItem, 'Thesis'))));
|
||||
router.navigate(['/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357']);
|
||||
tick();
|
||||
expect(tagStore.get('citation_dissertation_name')[0].content).toEqual('Test PowerPoint Document');
|
||||
expect(tagStore.get('citation_dissertation_institution')[0].content).toEqual('Mock Publisher');
|
||||
expect(tagStore.get('citation_abstract_html_url')[0].content).toEqual([envConfig.ui.baseUrl, router.url].join(''));
|
||||
expect(tagStore.get('citation_pdf_url')[0].content).toEqual('https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/99b00f3c-1cc6-4689-8158-91965bee6b28/content');
|
||||
}));
|
||||
|
||||
it('items page should set meta tags as published Technical Report', fakeAsync(() => {
|
||||
spyOn(itemDataService, 'findById').and.returnValue(mockRemoteData(mockPublisher(mockType(MockItem, 'Technical Report'))));
|
||||
router.navigate(['/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357']);
|
||||
tick();
|
||||
expect(tagStore.get('citation_technical_report_institution')[0].content).toEqual('Mock Publisher');
|
||||
}));
|
||||
|
||||
it('other navigation should title and description', fakeAsync(() => {
|
||||
spyOn(itemDataService, 'findById').and.returnValue(mockRemoteData(MockItem));
|
||||
router.navigate(['/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357']);
|
||||
tick();
|
||||
expect(tagStore.size).toBeGreaterThan(0)
|
||||
router.navigate(['/other']);
|
||||
tick();
|
||||
expect(tagStore.size).toEqual(2);
|
||||
expect(title.getTitle()).toEqual('Dummy Title');
|
||||
expect(tagStore.get('title')[0].content).toEqual('Dummy Title');
|
||||
expect(tagStore.get('description')[0].content).toEqual('This is a dummy item component for testing!');
|
||||
}));
|
||||
|
||||
const mockRemoteData = (mockItem: Item): RemoteData<Item> => {
|
||||
return new RemoteData<Item>(
|
||||
Observable.create((observer) => {
|
||||
observer.next('');
|
||||
}),
|
||||
Observable.create((observer) => {
|
||||
observer.next(false);
|
||||
}),
|
||||
Observable.create((observer) => {
|
||||
observer.next(false);
|
||||
}),
|
||||
Observable.create((observer) => {
|
||||
observer.next(true);
|
||||
}),
|
||||
Observable.create((observer) => {
|
||||
observer.next('');
|
||||
}),
|
||||
Observable.create((observer) => {
|
||||
observer.next(200);
|
||||
}),
|
||||
Observable.create((observer) => {
|
||||
observer.next({});
|
||||
}),
|
||||
Observable.create((observer) => {
|
||||
observer.next(MockItem);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
const mockType = (mockItem: Item, type: string): Item => {
|
||||
const typedMockItem = Object.assign(new Item(), mockItem) as Item;
|
||||
for (const metadatum of typedMockItem.metadata) {
|
||||
if (metadatum.key === 'dc.type') {
|
||||
metadatum.value = type;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return typedMockItem;
|
||||
}
|
||||
|
||||
const mockPublisher = (mockItem: Item): Item => {
|
||||
const publishedMockItem = Object.assign(new Item(), mockItem) as Item;
|
||||
publishedMockItem.metadata.push({
|
||||
key: 'dc.publisher',
|
||||
language: 'en_US',
|
||||
value: 'Mock Publisher'
|
||||
});
|
||||
return publishedMockItem;
|
||||
}
|
||||
|
||||
});
|
400
src/app/core/metadata/metadata.service.ts
Normal file
400
src/app/core/metadata/metadata.service.ts
Normal file
@@ -0,0 +1,400 @@
|
||||
import 'rxjs/add/operator/first'
|
||||
import 'rxjs/add/operator/take'
|
||||
|
||||
import { Inject, Injectable } from '@angular/core';
|
||||
import {
|
||||
ActivatedRoute,
|
||||
Event,
|
||||
NavigationEnd,
|
||||
Params,
|
||||
Router
|
||||
} from '@angular/router';
|
||||
|
||||
import { Meta, MetaDefinition, Title } from '@angular/platform-browser';
|
||||
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
import { RemoteData } from '../data/remote-data';
|
||||
import { Bitstream } from '../shared/bitstream.model';
|
||||
import { CacheableObject } from '../cache/object-cache.reducer';
|
||||
import { DSpaceObject } from '../shared/dspace-object.model';
|
||||
import { Item } from '../shared/item.model';
|
||||
import { Metadatum } from '../shared/metadatum.model';
|
||||
|
||||
import { GLOBAL_CONFIG, GlobalConfig } from '../../../config';
|
||||
|
||||
@Injectable()
|
||||
export class MetadataService {
|
||||
|
||||
private initialized: boolean;
|
||||
|
||||
private tagStore: Map<string, MetaDefinition[]>;
|
||||
|
||||
private currentObject: BehaviorSubject<DSpaceObject>;
|
||||
|
||||
constructor(
|
||||
private router: Router,
|
||||
private translate: TranslateService,
|
||||
private meta: Meta,
|
||||
private title: Title,
|
||||
@Inject(GLOBAL_CONFIG) private envConfig: GlobalConfig
|
||||
) {
|
||||
// TODO: determine what open graph meta tags are needed and whether
|
||||
// the differ per route. potentially add image based on DSpaceObject
|
||||
this.meta.addTags([
|
||||
{ property: 'og:title', content: 'DSpace Angular Universal' },
|
||||
{ property: 'og:description', content: 'The modern front-end for DSpace 7.' }
|
||||
]);
|
||||
this.initialized = false;
|
||||
this.tagStore = new Map<string, MetaDefinition[]>();
|
||||
}
|
||||
|
||||
public listenForRouteChange(): void {
|
||||
this.router.events
|
||||
.filter((event) => event instanceof NavigationEnd)
|
||||
.map(() => this.router.routerState.root)
|
||||
.map((route: ActivatedRoute) => {
|
||||
route = this.getCurrentRoute(route);
|
||||
return { params: route.params, data: route.data };
|
||||
}).subscribe((routeInfo: any) => {
|
||||
this.processRouteChange(routeInfo);
|
||||
});
|
||||
}
|
||||
|
||||
public processRemoteData(remoteData: RemoteData<CacheableObject>): void {
|
||||
remoteData.payload.take(1).subscribe((dspaceObject: DSpaceObject) => {
|
||||
if (!this.initialized) {
|
||||
this.initialize(dspaceObject);
|
||||
}
|
||||
this.currentObject.next(dspaceObject);
|
||||
});
|
||||
}
|
||||
|
||||
private processRouteChange(routeInfo: any): void {
|
||||
if (routeInfo.params.value.id === undefined) {
|
||||
this.clearMetaTags();
|
||||
}
|
||||
if (routeInfo.data.value.title) {
|
||||
this.translate.get(routeInfo.data.value.title).take(1).subscribe((translatedTitle: string) => {
|
||||
this.addMetaTag('title', translatedTitle);
|
||||
this.title.setTitle(translatedTitle);
|
||||
});
|
||||
}
|
||||
if (routeInfo.data.value.description) {
|
||||
this.translate.get(routeInfo.data.value.description).take(1).subscribe((translatedDescription: string) => {
|
||||
this.addMetaTag('description', translatedDescription);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private initialize(dspaceObject: DSpaceObject): void {
|
||||
this.currentObject = new BehaviorSubject<DSpaceObject>(dspaceObject);
|
||||
this.currentObject.asObservable().distinctUntilKeyChanged('uuid').subscribe(() => {
|
||||
this.setMetaTags();
|
||||
});
|
||||
this.initialized = true;
|
||||
}
|
||||
|
||||
private getCurrentRoute(route: ActivatedRoute): ActivatedRoute {
|
||||
while (route.firstChild) {
|
||||
route = route.firstChild;
|
||||
}
|
||||
return route;
|
||||
}
|
||||
|
||||
private setMetaTags(): void {
|
||||
|
||||
this.clearMetaTags();
|
||||
|
||||
this.setTitleTag();
|
||||
this.setDescriptionTag();
|
||||
|
||||
this.setCitationTitleTag();
|
||||
this.setCitationAuthorTags();
|
||||
this.setCitationDateTag();
|
||||
this.setCitationISSNTag();
|
||||
this.setCitationISBNTag();
|
||||
|
||||
this.setCitationLanguageTag();
|
||||
this.setCitationKeywordsTag();
|
||||
|
||||
this.setCitationAbstractUrlTag();
|
||||
this.setCitationPdfUrlTag();
|
||||
|
||||
if (this.isDissertation()) {
|
||||
this.setCitationDissertationNameTag();
|
||||
this.setCitationDissertationInstitutionTag();
|
||||
}
|
||||
|
||||
if (this.isTechReport()) {
|
||||
this.setCitationTechReportInstitutionTag();
|
||||
}
|
||||
|
||||
// this.setCitationJournalTitleTag();
|
||||
// this.setCitationVolumeTag();
|
||||
// this.setCitationIssueTag();
|
||||
// this.setCitationFirstPageTag();
|
||||
// this.setCitationLastPageTag();
|
||||
// this.setCitationDOITag();
|
||||
// this.setCitationPMIDTag();
|
||||
|
||||
// this.setCitationFullTextTag();
|
||||
|
||||
// this.setCitationConferenceTag();
|
||||
|
||||
// this.setCitationPatentCountryTag();
|
||||
// this.setCitationPatentNumberTag();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add <meta name="title" ... > to the <head>
|
||||
*/
|
||||
private setTitleTag(): void {
|
||||
const value = this.getMetaTagValue('dc.title');
|
||||
this.addMetaTag('title', value);
|
||||
this.title.setTitle(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add <meta name="description" ... > to the <head>
|
||||
*/
|
||||
private setDescriptionTag(): void {
|
||||
// TODO: truncate abstract
|
||||
const value = this.getMetaTagValue('dc.description.abstract');
|
||||
this.addMetaTag('desciption', value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add <meta name="citation_title" ... > to the <head>
|
||||
*/
|
||||
private setCitationTitleTag(): void {
|
||||
const value = this.getMetaTagValue('dc.title');
|
||||
this.addMetaTag('citation_title', value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add <meta name="citation_author" ... > to the <head>
|
||||
*/
|
||||
private setCitationAuthorTags(): void {
|
||||
const values: string[] = this.getMetaTagValues(['dc.author', 'dc.contributor.author', 'dc.creator']);
|
||||
this.addMetaTags('citation_author', values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add <meta name="citation_date" ... > to the <head>
|
||||
*/
|
||||
private setCitationDateTag(): void {
|
||||
const value = this.getFirstMetaTagValue(['dc.date.copyright', 'dc.date.issued', 'dc.date.available', 'dc.date.accessioned']);
|
||||
this.addMetaTag('citation_date', value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add <meta name="citation_issn" ... > to the <head>
|
||||
*/
|
||||
private setCitationISSNTag(): void {
|
||||
const value = this.getMetaTagValue('dc.identifier.issn');
|
||||
this.addMetaTag('citation_issn', value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add <meta name="citation_isbn" ... > to the <head>
|
||||
*/
|
||||
private setCitationISBNTag(): void {
|
||||
const value = this.getMetaTagValue('dc.identifier.isbn');
|
||||
this.addMetaTag('citation_isbn', value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add <meta name="citation_language" ... > to the <head>
|
||||
*/
|
||||
private setCitationLanguageTag(): void {
|
||||
const value = this.getFirstMetaTagValue(['dc.language', 'dc.language.iso']);
|
||||
this.addMetaTag('citation_language', value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add <meta name="citation_dissertation_name" ... > to the <head>
|
||||
*/
|
||||
private setCitationDissertationNameTag(): void {
|
||||
const value = this.getMetaTagValue('dc.title');
|
||||
this.addMetaTag('citation_dissertation_name', value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add <meta name="citation_dissertation_institution" ... > to the <head>
|
||||
*/
|
||||
private setCitationDissertationInstitutionTag(): void {
|
||||
const value = this.getMetaTagValue('dc.publisher');
|
||||
this.addMetaTag('citation_dissertation_institution', value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add <meta name="citation_technical_report_institution" ... > to the <head>
|
||||
*/
|
||||
private setCitationTechReportInstitutionTag(): void {
|
||||
const value = this.getMetaTagValue('dc.publisher');
|
||||
this.addMetaTag('citation_technical_report_institution', value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add <meta name="citation_keywords" ... > to the <head>
|
||||
*/
|
||||
private setCitationKeywordsTag(): void {
|
||||
const value = this.getMetaTagValuesAndCombine('dc.subject');
|
||||
this.addMetaTag('citation_keywords', value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add <meta name="citation_abstract_html_url" ... > to the <head>
|
||||
*/
|
||||
private setCitationAbstractUrlTag(): void {
|
||||
if (this.currentObject.value instanceof Item) {
|
||||
const value = [this.envConfig.ui.baseUrl, this.router.url].join('');
|
||||
this.addMetaTag('citation_abstract_html_url', value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add <meta name="citation_pdf_url" ... > to the <head>
|
||||
*/
|
||||
private setCitationPdfUrlTag(): void {
|
||||
if (this.currentObject.value instanceof Item) {
|
||||
const item = this.currentObject.value as Item;
|
||||
// NOTE: Observable resolves many times with same data
|
||||
// taking only two, fist one is empty array
|
||||
item.getFiles().take(2).subscribe((bitstreams: Bitstream[]) => {
|
||||
for (const bitstream of bitstreams) {
|
||||
bitstream.format.payload.take(1).subscribe((format) => {
|
||||
if (format.mimetype === 'application/pdf') {
|
||||
this.addMetaTag('citation_pdf_url', bitstream.content);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this._item is a dissertation
|
||||
*
|
||||
* @returns {boolean}
|
||||
* true if this._item has a dc.type equal to 'Thesis'
|
||||
*/
|
||||
private isDissertation(): boolean {
|
||||
let isDissertation = false;
|
||||
for (const metadatum of this.currentObject.value.metadata) {
|
||||
if (metadatum.key === 'dc.type') {
|
||||
isDissertation = metadatum.value.toLowerCase() === 'thesis';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return isDissertation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this._item is a technical report
|
||||
*
|
||||
* @returns {boolean}
|
||||
* true if this._item has a dc.type equal to 'Technical Report'
|
||||
*/
|
||||
private isTechReport(): boolean {
|
||||
let isTechReport = false;
|
||||
for (const metadatum of this.currentObject.value.metadata) {
|
||||
if (metadatum.key === 'dc.type') {
|
||||
isTechReport = metadatum.value.toLowerCase() === 'technical report';
|
||||
break;
|
||||
}
|
||||
}
|
||||
return isTechReport;
|
||||
}
|
||||
|
||||
private getMetaTagValue(key: string): string {
|
||||
let value: string;
|
||||
for (const metadatum of this.currentObject.value.metadata) {
|
||||
if (metadatum.key === key) {
|
||||
value = metadatum.value;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private getFirstMetaTagValue(keys: string[]): string {
|
||||
let value: string;
|
||||
for (const metadatum of this.currentObject.value.metadata) {
|
||||
for (const key of keys) {
|
||||
if (key === metadatum.key) {
|
||||
value = metadatum.value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (value !== undefined) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
private getMetaTagValuesAndCombine(key: string): string {
|
||||
return this.getMetaTagValues([key]).join('; ');
|
||||
}
|
||||
|
||||
private getMetaTagValues(keys: string[]): string[] {
|
||||
const values: string[] = [];
|
||||
for (const metadatum of this.currentObject.value.metadata) {
|
||||
for (const key of keys) {
|
||||
if (key === metadatum.key) {
|
||||
values.push(metadatum.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
return values;
|
||||
}
|
||||
|
||||
private addMetaTag(property: string, content: string): void {
|
||||
if (content) {
|
||||
const tag = { property, content } as MetaDefinition;
|
||||
this.meta.addTag(tag);
|
||||
this.storeTag(property, tag);
|
||||
}
|
||||
}
|
||||
|
||||
private addMetaTags(property: string, content: string[]): void {
|
||||
for (const value of content) {
|
||||
this.addMetaTag(property, value);
|
||||
}
|
||||
}
|
||||
|
||||
private storeTag(key: string, tag: MetaDefinition): void {
|
||||
const tags: MetaDefinition[] = this.getTags(key);
|
||||
tags.push(tag);
|
||||
this.setTags(key, tags);
|
||||
}
|
||||
|
||||
private getTags(key: string): MetaDefinition[] {
|
||||
let tags: MetaDefinition[] = this.tagStore.get(key);
|
||||
if (tags === undefined) {
|
||||
tags = [];
|
||||
}
|
||||
return tags;
|
||||
}
|
||||
|
||||
private setTags(key: string, tags: MetaDefinition[]): void {
|
||||
this.tagStore.set(key, tags);
|
||||
}
|
||||
|
||||
public clearMetaTags() {
|
||||
this.tagStore.forEach((tags: MetaDefinition[], property: string) => {
|
||||
this.meta.removeTag("property='" + property + "'");
|
||||
});
|
||||
this.tagStore.clear();
|
||||
}
|
||||
|
||||
public getTagStore(): Map<string, MetaDefinition[]> {
|
||||
return this.tagStore;
|
||||
}
|
||||
|
||||
}
|
17
src/app/core/shared/bitstream-format.model.ts
Normal file
17
src/app/core/shared/bitstream-format.model.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { DSpaceObject } from './dspace-object.model';
|
||||
|
||||
export class BitstreamFormat extends DSpaceObject {
|
||||
|
||||
shortDescription: string;
|
||||
|
||||
description: string;
|
||||
|
||||
mimetype: string;
|
||||
|
||||
supportLevel: number;
|
||||
|
||||
internal: boolean;
|
||||
|
||||
extensions: string;
|
||||
|
||||
}
|
@@ -1,6 +1,7 @@
|
||||
import { DSpaceObject } from './dspace-object.model';
|
||||
import { RemoteData } from '../data/remote-data';
|
||||
import { Item } from './item.model';
|
||||
import { BitstreamFormat } from './bitstream-format.model';
|
||||
|
||||
export class Bitstream extends DSpaceObject {
|
||||
|
||||
@@ -9,11 +10,6 @@ export class Bitstream extends DSpaceObject {
|
||||
*/
|
||||
sizeBytes: number;
|
||||
|
||||
/**
|
||||
* The mime type of this Bitstream
|
||||
*/
|
||||
mimetype: string;
|
||||
|
||||
/**
|
||||
* The description of this Bitstream
|
||||
*/
|
||||
@@ -24,6 +20,11 @@ export class Bitstream extends DSpaceObject {
|
||||
*/
|
||||
bundleName: string;
|
||||
|
||||
/**
|
||||
* An array of Bitstream Format of this Bitstream
|
||||
*/
|
||||
format: RemoteData<BitstreamFormat>;
|
||||
|
||||
/**
|
||||
* An array of Items that are direct parents of this Bitstream
|
||||
*/
|
||||
|
@@ -21,7 +21,7 @@ import { Store, StoreModule } from '@ngrx/store';
|
||||
// Load the implementations that should be tested
|
||||
import { FooterComponent } from './footer.component';
|
||||
|
||||
import { MockTranslateLoader } from '../shared/testing/mock-translate-loader';
|
||||
import { MockTranslateLoader } from '../shared/mocks/mock-translate-loader';
|
||||
|
||||
let comp: FooterComponent;
|
||||
let fixture: ComponentFixture<FooterComponent>;
|
||||
|
@@ -4,7 +4,7 @@ import { DebugElement } from '@angular/core';
|
||||
|
||||
import { TranslateModule, TranslateLoader, TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { MockTranslateLoader } from '../testing/mock-translate-loader';
|
||||
import { MockTranslateLoader } from '../mocks/mock-translate-loader';
|
||||
|
||||
import { ErrorComponent } from './error.component';
|
||||
|
||||
|
@@ -4,7 +4,7 @@ import { DebugElement } from '@angular/core';
|
||||
|
||||
import { TranslateModule, TranslateLoader, TranslateService } from '@ngx-translate/core';
|
||||
|
||||
import { MockTranslateLoader } from '../testing/mock-translate-loader';
|
||||
import { MockTranslateLoader } from '../mocks/mock-translate-loader';
|
||||
|
||||
import { LoadingComponent } from './loading.component';
|
||||
|
||||
|
6
src/app/shared/mocks/mock-action.ts
Normal file
6
src/app/shared/mocks/mock-action.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { Action } from '@ngrx/store';
|
||||
|
||||
export class MockAction implements Action {
|
||||
type = null;
|
||||
payload: {};
|
||||
}
|
34
src/app/shared/mocks/mock-active-router.ts
Normal file
34
src/app/shared/mocks/mock-active-router.ts
Normal file
@@ -0,0 +1,34 @@
|
||||
import { Params } from '@angular/router';
|
||||
|
||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||
|
||||
export class MockActivatedRoute {
|
||||
|
||||
private _testParams?: any;
|
||||
|
||||
// ActivatedRoute.params is Observable
|
||||
private subject?: BehaviorSubject<any> = new BehaviorSubject(this.testParams);
|
||||
|
||||
params = this.subject.asObservable();
|
||||
queryParams = this.subject.asObservable();
|
||||
|
||||
constructor(params?: Params) {
|
||||
if (params) {
|
||||
this.testParams = params;
|
||||
} else {
|
||||
this.testParams = {};
|
||||
}
|
||||
}
|
||||
|
||||
// Test parameters
|
||||
get testParams() { return this._testParams; }
|
||||
set testParams(params: {}) {
|
||||
this._testParams = params;
|
||||
this.subject.next(params);
|
||||
}
|
||||
|
||||
// ActivatedRoute.snapshot.params
|
||||
get snapshot() {
|
||||
return { params: this.testParams };
|
||||
}
|
||||
}
|
19
src/app/shared/mocks/mock-host-window-service.ts
Normal file
19
src/app/shared/mocks/mock-host-window-service.ts
Normal file
@@ -0,0 +1,19 @@
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
// declare a stub service
|
||||
export class MockHostWindowService {
|
||||
|
||||
private width: number;
|
||||
|
||||
constructor(width) {
|
||||
this.setWidth(width);
|
||||
}
|
||||
|
||||
setWidth(width) {
|
||||
this.width = width;
|
||||
}
|
||||
|
||||
isXs(): Observable<boolean> {
|
||||
return Observable.of(this.width < 576);
|
||||
}
|
||||
}
|
273
src/app/shared/mocks/mock-item.ts
Normal file
273
src/app/shared/mocks/mock-item.ts
Normal file
@@ -0,0 +1,273 @@
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
import { Item } from '../../core/shared/item.model';
|
||||
|
||||
/* tslint:disable:no-shadowed-variable */
|
||||
export const MockItem: Item = Object.assign(new Item(), {
|
||||
handle: '10673/6',
|
||||
lastModified: '2017-04-24T19:44:08.178+0000',
|
||||
isArchived: true,
|
||||
isDiscoverable: true,
|
||||
isWithdrawn: false,
|
||||
bitstreams: {
|
||||
self: {
|
||||
_isScalar: true,
|
||||
value: '1507836003548',
|
||||
scheduler: null
|
||||
},
|
||||
requestPending: Observable.create((observer) => {
|
||||
observer.next(false);
|
||||
}),
|
||||
responsePending: Observable.create((observer) => {
|
||||
observer.next(false);
|
||||
}),
|
||||
isSuccessFul: Observable.create((observer) => {
|
||||
observer.next(true);
|
||||
}),
|
||||
errorMessage: Observable.create((observer) => {
|
||||
observer.next('');
|
||||
}),
|
||||
statusCode: Observable.create((observer) => {
|
||||
observer.next(202);
|
||||
}),
|
||||
pageInfo: Observable.create((observer) => {
|
||||
observer.next({});
|
||||
}),
|
||||
payload: Observable.create((observer) => {
|
||||
observer.next([
|
||||
{
|
||||
sizeBytes: 10201,
|
||||
content: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/cf9b0c8e-a1eb-4b65-afd0-567366448713/content',
|
||||
format: {
|
||||
self: {
|
||||
_isScalar: true,
|
||||
value: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreamformats/10',
|
||||
scheduler: null
|
||||
},
|
||||
requestPending: Observable.create((observer) => {
|
||||
observer.next(false);
|
||||
}),
|
||||
responsePending: Observable.create((observer) => {
|
||||
observer.next(false);
|
||||
}),
|
||||
isSuccessFul: Observable.create((observer) => {
|
||||
observer.next(true);
|
||||
}),
|
||||
errorMessage: Observable.create((observer) => {
|
||||
observer.next('');
|
||||
}),
|
||||
statusCode: Observable.create((observer) => {
|
||||
observer.next(202);
|
||||
}),
|
||||
pageInfo: Observable.create((observer) => {
|
||||
observer.next({});
|
||||
}),
|
||||
payload: Observable.create((observer) => {
|
||||
observer.next({
|
||||
shortDescription: 'Microsoft Word XML',
|
||||
description: 'Microsoft Word XML',
|
||||
mimetype: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||
supportLevel: 0,
|
||||
internal: false,
|
||||
extensions: null,
|
||||
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreamformats/10'
|
||||
});
|
||||
})
|
||||
},
|
||||
bundleName: 'ORIGINAL',
|
||||
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/cf9b0c8e-a1eb-4b65-afd0-567366448713',
|
||||
id: 'cf9b0c8e-a1eb-4b65-afd0-567366448713',
|
||||
uuid: 'cf9b0c8e-a1eb-4b65-afd0-567366448713',
|
||||
type: 'bitstream',
|
||||
name: 'test_word.docx',
|
||||
metadata: [
|
||||
{
|
||||
key: 'dc.title',
|
||||
language: null,
|
||||
value: 'test_word.docx'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
sizeBytes: 31302,
|
||||
content: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/99b00f3c-1cc6-4689-8158-91965bee6b28/content',
|
||||
format: {
|
||||
self: {
|
||||
_isScalar: true,
|
||||
value: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreamformats/4',
|
||||
scheduler: null
|
||||
},
|
||||
requestPending: Observable.create((observer) => {
|
||||
observer.next(false);
|
||||
}),
|
||||
responsePending: Observable.create((observer) => {
|
||||
observer.next(false);
|
||||
}),
|
||||
isSuccessFul: Observable.create((observer) => {
|
||||
observer.next(true);
|
||||
}),
|
||||
errorMessage: Observable.create((observer) => {
|
||||
observer.next('');
|
||||
}),
|
||||
statusCode: Observable.create((observer) => {
|
||||
observer.next(202);
|
||||
}),
|
||||
pageInfo: Observable.create((observer) => {
|
||||
observer.next({});
|
||||
}),
|
||||
payload: Observable.create((observer) => {
|
||||
observer.next({
|
||||
shortDescription: 'Adobe PDF',
|
||||
description: 'Adobe Portable Document Format',
|
||||
mimetype: 'application/pdf',
|
||||
supportLevel: 0,
|
||||
internal: false,
|
||||
extensions: null,
|
||||
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreamformats/4'
|
||||
});
|
||||
})
|
||||
},
|
||||
bundleName: 'ORIGINAL',
|
||||
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/bitstreams/99b00f3c-1cc6-4689-8158-91965bee6b28',
|
||||
id: '99b00f3c-1cc6-4689-8158-91965bee6b28',
|
||||
uuid: '99b00f3c-1cc6-4689-8158-91965bee6b28',
|
||||
type: 'bitstream',
|
||||
name: 'test_pdf.pdf',
|
||||
metadata: [
|
||||
{
|
||||
key: 'dc.title',
|
||||
language: null,
|
||||
value: 'test_pdf.pdf'
|
||||
}
|
||||
]
|
||||
}
|
||||
]);
|
||||
})
|
||||
},
|
||||
self: 'https://dspace7.4science.it/dspace-spring-rest/api/core/items/0ec7ff22-f211-40ab-a69e-c819b0b1f357',
|
||||
id: '0ec7ff22-f211-40ab-a69e-c819b0b1f357',
|
||||
uuid: '0ec7ff22-f211-40ab-a69e-c819b0b1f357',
|
||||
type: 'item',
|
||||
name: 'Test PowerPoint Document',
|
||||
metadata: [
|
||||
{
|
||||
key: 'dc.creator',
|
||||
language: 'en_US',
|
||||
value: 'Doe, Jane'
|
||||
},
|
||||
{
|
||||
key: 'dc.date.accessioned',
|
||||
language: null,
|
||||
value: '1650-06-26T19:58:25Z'
|
||||
},
|
||||
{
|
||||
key: 'dc.date.available',
|
||||
language: null,
|
||||
value: '1650-06-26T19:58:25Z'
|
||||
},
|
||||
{
|
||||
key: 'dc.date.issued',
|
||||
language: null,
|
||||
value: '1650-06-26'
|
||||
},
|
||||
{
|
||||
key: 'dc.identifier.issn',
|
||||
language: 'en_US',
|
||||
value: '123456789'
|
||||
},
|
||||
{
|
||||
key: 'dc.identifier.uri',
|
||||
language: null,
|
||||
value: 'http://dspace7.4science.it/xmlui/handle/10673/6'
|
||||
},
|
||||
{
|
||||
key: 'dc.description.abstract',
|
||||
language: 'en_US',
|
||||
value: 'This is really just a sample abstract. If it was a real abstract it would contain useful information about this test document. Sorry though, nothing useful in this paragraph. You probably shouldn\'t have even bothered to read it!'
|
||||
},
|
||||
{
|
||||
key: 'dc.description.provenance',
|
||||
language: 'en',
|
||||
value: 'Made available in DSpace on 2012-06-26T19:58:25Z (GMT). No. of bitstreams: 2\r\ntest_ppt.ppt: 12707328 bytes, checksum: a353fc7d29b3c558c986f7463a41efd3 (MD5)\r\ntest_ppt.pptx: 12468572 bytes, checksum: 599305edb4ebee329667f2c35b14d1d6 (MD5)'
|
||||
},
|
||||
{
|
||||
key: 'dc.description.provenance',
|
||||
language: 'en',
|
||||
value: 'Restored into DSpace on 2013-06-13T09:17:34Z (GMT).'
|
||||
},
|
||||
{
|
||||
key: 'dc.description.provenance',
|
||||
language: 'en',
|
||||
value: 'Restored into DSpace on 2013-06-13T11:04:16Z (GMT).'
|
||||
},
|
||||
{
|
||||
key: 'dc.description.provenance',
|
||||
language: 'en',
|
||||
value: 'Restored into DSpace on 2017-04-24T19:44:08Z (GMT).'
|
||||
},
|
||||
{
|
||||
key: 'dc.language',
|
||||
language: 'en_US',
|
||||
value: 'en'
|
||||
},
|
||||
{
|
||||
key: 'dc.rights',
|
||||
language: 'en_US',
|
||||
value: '© Jane Doe'
|
||||
},
|
||||
{
|
||||
key: 'dc.subject',
|
||||
language: 'en_US',
|
||||
value: 'keyword1'
|
||||
},
|
||||
{
|
||||
key: 'dc.subject',
|
||||
language: 'en_US',
|
||||
value: 'keyword2'
|
||||
},
|
||||
{
|
||||
key: 'dc.subject',
|
||||
language: 'en_US',
|
||||
value: 'keyword3'
|
||||
},
|
||||
{
|
||||
key: 'dc.title',
|
||||
language: 'en_US',
|
||||
value: 'Test PowerPoint Document'
|
||||
},
|
||||
{
|
||||
key: 'dc.type',
|
||||
language: 'en_US',
|
||||
value: 'text'
|
||||
}
|
||||
],
|
||||
owningCollection: {
|
||||
self: {
|
||||
_isScalar: true,
|
||||
value: 'https://dspace7.4science.it/dspace-spring-rest/api/core/collections/1c11f3f1-ba1f-4f36-908a-3f1ea9a557eb',
|
||||
scheduler: null
|
||||
},
|
||||
requestPending: Observable.create((observer) => {
|
||||
observer.next(false);
|
||||
}),
|
||||
responsePending: Observable.create((observer) => {
|
||||
observer.next(false);
|
||||
}),
|
||||
isSuccessFul: Observable.create((observer) => {
|
||||
observer.next(true);
|
||||
}),
|
||||
errorMessage: Observable.create((observer) => {
|
||||
observer.next('');
|
||||
}),
|
||||
statusCode: Observable.create((observer) => {
|
||||
observer.next(202);
|
||||
}),
|
||||
pageInfo: Observable.create((observer) => {
|
||||
observer.next({});
|
||||
}),
|
||||
payload: Observable.create((observer) => {
|
||||
observer.next([]);
|
||||
})
|
||||
}
|
||||
})
|
||||
/* tslint:enable:no-shadowed-variable */
|
9
src/app/shared/mocks/mock-metadata-service.ts
Normal file
9
src/app/shared/mocks/mock-metadata-service.ts
Normal file
@@ -0,0 +1,9 @@
|
||||
|
||||
export class MockMetadataService {
|
||||
|
||||
// tslint:disable-next-line:no-empty
|
||||
public listenForRouteChange(): void {
|
||||
|
||||
}
|
||||
|
||||
}
|
4
src/app/shared/mocks/mock-router.ts
Normal file
4
src/app/shared/mocks/mock-router.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
export class MockRouter {
|
||||
// noinspection TypeScriptUnresolvedFunction
|
||||
navigate = jasmine.createSpy('navigate');
|
||||
}
|
23
src/app/shared/mocks/mock-store.ts
Normal file
23
src/app/shared/mocks/mock-store.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { Action } from '@ngrx/store';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||
|
||||
export class MockStore<T> extends BehaviorSubject<T> {
|
||||
|
||||
constructor(private _initialState: T) {
|
||||
super(_initialState);
|
||||
}
|
||||
|
||||
dispatch = (action: Action): void => {
|
||||
console.info();
|
||||
}
|
||||
|
||||
select = <R>(pathOrMapFn: any): Observable<T> => {
|
||||
return Observable.of(this.getValue());
|
||||
}
|
||||
|
||||
nextState(_newState: T) {
|
||||
this.next(_newState);
|
||||
}
|
||||
|
||||
}
|
8
src/app/shared/mocks/mock-translate-loader.ts
Normal file
8
src/app/shared/mocks/mock-translate-loader.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { TranslateLoader } from '@ngx-translate/core';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
export class MockTranslateLoader implements TranslateLoader {
|
||||
getTranslation(lang: string): Observable<any> {
|
||||
return Observable.of({});
|
||||
}
|
||||
}
|
@@ -34,10 +34,10 @@ import Spy = jasmine.Spy;
|
||||
import { PaginationComponent } from './pagination.component';
|
||||
import { PaginationComponentOptions } from './pagination-component-options.model';
|
||||
|
||||
import { MockTranslateLoader } from '../testing/mock-translate-loader';
|
||||
import { HostWindowServiceStub } from '../testing/host-window-service-stub';
|
||||
import { ActivatedRouteStub } from '../testing/active-router-stub';
|
||||
import { RouterStub } from '../testing/router-stub';
|
||||
import { MockTranslateLoader } from '../mocks/mock-translate-loader';
|
||||
import { MockHostWindowService } from '../mocks/mock-host-window-service';
|
||||
import { MockActivatedRoute } from '../mocks/mock-active-router';
|
||||
import { MockRouter } from '../mocks/mock-router';
|
||||
|
||||
import { HostWindowService } from '../host-window.service';
|
||||
import { EnumKeysPipe } from '../utils/enum-keys-pipe';
|
||||
@@ -123,19 +123,19 @@ describe('Pagination component', () => {
|
||||
let testFixture: ComponentFixture<TestComponent>;
|
||||
let de: DebugElement;
|
||||
let html;
|
||||
let hostWindowServiceStub: HostWindowServiceStub;
|
||||
let hostWindowServiceStub: MockHostWindowService;
|
||||
|
||||
let activatedRouteStub: ActivatedRouteStub;
|
||||
let routerStub: RouterStub;
|
||||
let activatedRouteStub: MockActivatedRoute;
|
||||
let routerStub: MockRouter;
|
||||
|
||||
// Define initial state and test state
|
||||
const _initialState = { width: 1600, height: 770 };
|
||||
|
||||
// async beforeEach
|
||||
beforeEach(async(() => {
|
||||
activatedRouteStub = new ActivatedRouteStub();
|
||||
routerStub = new RouterStub();
|
||||
hostWindowServiceStub = new HostWindowServiceStub(_initialState.width);
|
||||
activatedRouteStub = new MockActivatedRoute();
|
||||
routerStub = new MockRouter();
|
||||
hostWindowServiceStub = new MockHostWindowService(_initialState.width);
|
||||
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
|
@@ -29,6 +29,7 @@ import { ThumbnailComponent } from '../thumbnail/thumbnail.component';
|
||||
import { SearchResultListElementComponent } from '../object-list/search-result-list-element/search-result-list-element.component';
|
||||
import { SearchFormComponent } from './search-form/search-form.component';
|
||||
import { WrapperListElementComponent } from '../object-list/wrapper-list-element/wrapper-list-element.component';
|
||||
import { ViewModeSwitchComponent } from './view-mode-switch/view-mode-switch.component';
|
||||
|
||||
const MODULES = [
|
||||
// Do NOT include UniversalModule, HttpModule, or JsonpModule here
|
||||
@@ -61,7 +62,8 @@ const COMPONENTS = [
|
||||
PaginationComponent,
|
||||
SearchFormComponent,
|
||||
ThumbnailComponent,
|
||||
WrapperListElementComponent
|
||||
WrapperListElementComponent,
|
||||
ViewModeSwitchComponent
|
||||
];
|
||||
|
||||
const ENTRY_COMPONENTS = [
|
||||
|
@@ -0,0 +1,20 @@
|
||||
<div class="btn-group" data-toggle="buttons">
|
||||
<a routerLink="."
|
||||
[queryParams]="{view: 'list'}"
|
||||
queryParamsHandling="merge"
|
||||
(click)="switchViewTo(viewModeEnum.List)"
|
||||
routerLinkActive="active"
|
||||
[class.active]="currentMode === viewModeEnum.List"
|
||||
class="btn btn-secondary">
|
||||
<i class="fa fa-list" title="{{'search.view-switch.show-list' | translate}}"></i>
|
||||
</a>
|
||||
<a routerLink="."
|
||||
[queryParams]="{view: 'grid'}"
|
||||
queryParamsHandling="merge"
|
||||
(click)="switchViewTo(viewModeEnum.Grid)"
|
||||
routerLinkActive="active"
|
||||
[class.active]="currentMode !== viewModeEnum.List"
|
||||
class="btn btn-secondary">
|
||||
<i class="fa fa-th-large" title="{{'search.view-switch.show-grid' | translate}}"></i>
|
||||
</a>
|
||||
</div>
|
@@ -0,0 +1 @@
|
||||
@import '../../../styles/variables.scss';
|
@@ -0,0 +1,77 @@
|
||||
import { DebugElement } from '@angular/core';
|
||||
import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
|
||||
import { async, ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { MockTranslateLoader } from '../mocks/mock-translate-loader';
|
||||
import { RouterTestingModule } from '@angular/router/testing';
|
||||
|
||||
import { Component } from '@angular/core';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
|
||||
import { SearchService } from '../../+search-page/search-service/search.service';
|
||||
import { ItemDataService } from './../../core/data/item-data.service';
|
||||
import { ViewModeSwitchComponent } from './view-mode-switch.component';
|
||||
import { ViewMode } from '../../+search-page/search-options.model';
|
||||
|
||||
@Component({ template: '' })
|
||||
class DummyComponent { }
|
||||
|
||||
describe('ViewModeSwitchComponent', () => {
|
||||
let comp: ViewModeSwitchComponent;
|
||||
let fixture: ComponentFixture<ViewModeSwitchComponent>;
|
||||
let searchService: SearchService;
|
||||
let listButton: HTMLElement;
|
||||
let gridButton: HTMLElement;
|
||||
|
||||
beforeEach(async(() => {
|
||||
TestBed.configureTestingModule({
|
||||
imports: [
|
||||
TranslateModule.forRoot({
|
||||
loader: {
|
||||
provide: TranslateLoader,
|
||||
useClass: MockTranslateLoader
|
||||
}
|
||||
}),
|
||||
RouterTestingModule.withRoutes([
|
||||
{ path: 'search', component: DummyComponent, pathMatch: 'full' },
|
||||
])
|
||||
],
|
||||
declarations: [
|
||||
ViewModeSwitchComponent,
|
||||
DummyComponent
|
||||
],
|
||||
providers: [
|
||||
{ provide: ItemDataService, useValue: {} },
|
||||
SearchService
|
||||
],
|
||||
}).compileComponents();
|
||||
}));
|
||||
|
||||
beforeEach(() => {
|
||||
fixture = TestBed.createComponent(ViewModeSwitchComponent);
|
||||
comp = fixture.componentInstance; // ViewModeSwitchComponent test instance
|
||||
fixture.detectChanges();
|
||||
const debugElements = fixture.debugElement.queryAll(By.css('a'));
|
||||
listButton = debugElements[0].nativeElement;
|
||||
gridButton = debugElements[1].nativeElement;
|
||||
searchService = fixture.debugElement.injector.get(SearchService);
|
||||
});
|
||||
|
||||
it('should set list button as active when on list mode', fakeAsync(() => {
|
||||
searchService.setViewMode(ViewMode.List);
|
||||
tick();
|
||||
fixture.detectChanges();
|
||||
expect(comp.currentMode).toBe(ViewMode.List);
|
||||
expect(listButton.classList).toContain('active');
|
||||
expect(gridButton.classList).not.toContain('active');
|
||||
}));
|
||||
|
||||
it('should set grid button as active when on grid mode', fakeAsync(() => {
|
||||
searchService.setViewMode(ViewMode.Grid);
|
||||
tick();
|
||||
fixture.detectChanges();
|
||||
expect(comp.currentMode).toBe(ViewMode.Grid);
|
||||
expect(listButton.classList).not.toContain('active');
|
||||
expect(gridButton.classList).toContain('active');
|
||||
}));
|
||||
});
|
@@ -0,0 +1,37 @@
|
||||
import { Subscription } from 'rxjs/Subscription';
|
||||
import { Component, OnInit, OnDestroy } from '@angular/core';
|
||||
import { ViewMode } from '../../+search-page/search-options.model';
|
||||
import { SearchService } from './../../+search-page/search-service/search.service';
|
||||
|
||||
/**
|
||||
* Component to switch between list and grid views.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'ds-view-mode-switch',
|
||||
styleUrls: ['./view-mode-switch.component.scss'],
|
||||
templateUrl: './view-mode-switch.component.html'
|
||||
})
|
||||
export class ViewModeSwitchComponent implements OnInit, OnDestroy {
|
||||
currentMode: ViewMode = ViewMode.List;
|
||||
viewModeEnum = ViewMode;
|
||||
private sub: Subscription;
|
||||
|
||||
constructor(private searchService: SearchService) {
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
this.sub = this.searchService.getViewMode().subscribe((viewMode: ViewMode) => {
|
||||
this.currentMode = viewMode;
|
||||
});
|
||||
}
|
||||
|
||||
switchViewTo(viewMode: ViewMode) {
|
||||
this.searchService.setViewMode(viewMode);
|
||||
}
|
||||
|
||||
ngOnDestroy() {
|
||||
if (this.sub !== undefined) {
|
||||
this.sub.unsubscribe();
|
||||
}
|
||||
}
|
||||
}
|
@@ -7,7 +7,7 @@ import { bootloader } from '@angularclass/bootloader';
|
||||
|
||||
import { load as loadWebFont } from 'webfontloader';
|
||||
|
||||
import { BrowserAppModule } from './app/browser-app.module';
|
||||
import { BrowserAppModule } from './modules/app/browser-app.module';
|
||||
|
||||
import { ENV_CONFIG } from './config';
|
||||
|
||||
|
@@ -17,7 +17,7 @@ import { enableProdMode } from '@angular/core';
|
||||
|
||||
import { ngExpressEngine } from '@nguniversal/express-engine';
|
||||
|
||||
import { ServerAppModule } from './app/server-app.module';
|
||||
import { ServerAppModule } from './modules/app/server-app.module';
|
||||
|
||||
import { serverApi, createMockApi } from './backend/api';
|
||||
|
||||
|
@@ -11,15 +11,15 @@ import { TranslateHttpLoader } from '@ngx-translate/http-loader';
|
||||
|
||||
import { EffectsModule } from '@ngrx/effects';
|
||||
|
||||
import { TransferState } from '../modules/transfer-state/transfer-state';
|
||||
import { BrowserTransferStateModule } from '../modules/transfer-state/browser-transfer-state.module';
|
||||
import { BrowserTransferStoreEffects } from '../modules/transfer-store/browser-transfer-store.effects';
|
||||
import { BrowserTransferStoreModule } from '../modules/transfer-store/browser-transfer-store.module';
|
||||
import { TransferState } from '../transfer-state/transfer-state';
|
||||
import { BrowserTransferStateModule } from '../transfer-state/browser-transfer-state.module';
|
||||
import { BrowserTransferStoreEffects } from '../transfer-store/browser-transfer-store.effects';
|
||||
import { BrowserTransferStoreModule } from '../transfer-store/browser-transfer-store.module';
|
||||
|
||||
import { AppModule } from './app.module';
|
||||
import { CoreModule } from './core/core.module';
|
||||
import { AppModule } from '../../app/app.module';
|
||||
import { CoreModule } from '../../app/core/core.module';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { AppComponent } from '../../app/app.component';
|
||||
|
||||
export function init(cache: TransferState) {
|
||||
return () => {
|
@@ -16,21 +16,21 @@ import { TranslateModule, TranslateLoader } from '@ngx-translate/core';
|
||||
import { Store } from '@ngrx/store';
|
||||
import { EffectsModule } from '@ngrx/effects';
|
||||
|
||||
import { TranslateUniversalLoader } from '../modules/translate-universal-loader';
|
||||
import { TranslateUniversalLoader } from '../translate-universal-loader';
|
||||
|
||||
import { ServerTransferStateModule } from '../modules/transfer-state/server-transfer-state.module';
|
||||
import { TransferState } from '../modules/transfer-state/transfer-state';
|
||||
import { ServerTransferStateModule } from '../transfer-state/server-transfer-state.module';
|
||||
import { TransferState } from '../transfer-state/transfer-state';
|
||||
|
||||
import { ServerTransferStoreEffects } from '../modules/transfer-store/server-transfer-store.effects';
|
||||
import { ServerTransferStoreModule } from '../modules/transfer-store/server-transfer-store.module';
|
||||
import { ServerTransferStoreEffects } from '../transfer-store/server-transfer-store.effects';
|
||||
import { ServerTransferStoreModule } from '../transfer-store/server-transfer-store.module';
|
||||
|
||||
import { AppState } from './app.reducer';
|
||||
import { AppState } from '../../app/app.reducer';
|
||||
|
||||
import { AppModule } from './app.module';
|
||||
import { AppModule } from '../../app/app.module';
|
||||
|
||||
import { AppComponent } from './app.component';
|
||||
import { AppComponent } from '../../app/app.component';
|
||||
|
||||
import { GLOBAL_CONFIG, GlobalConfig } from '../config';
|
||||
import { GLOBAL_CONFIG, GlobalConfig } from '../../config';
|
||||
|
||||
export function boot(cache: TransferState, appRef: ApplicationRef, store: Store<AppState>, request: Request, config: GlobalConfig) {
|
||||
// authentication mechanism goes here
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"angularCompilerOptions": {
|
||||
"entryModule": "./app/browser-app.module#BrowserAppModule"
|
||||
"entryModule": "./modules/app/browser-app.module#BrowserAppModule"
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"extends": "../tsconfig.json",
|
||||
"angularCompilerOptions": {
|
||||
"entryModule": "./app/server-app.module#ServerAppModule"
|
||||
"entryModule": "./modules/app/server-app.module#ServerAppModule"
|
||||
}
|
||||
}
|
||||
|
@@ -4,6 +4,6 @@
|
||||
"sourceMap": true
|
||||
},
|
||||
"angularCompilerOptions": {
|
||||
"entryModule": "./app/browser-app.module#BrowserAppModule"
|
||||
"entryModule": "./modules/app/browser-app.module#BrowserAppModule"
|
||||
}
|
||||
}
|
||||
|
@@ -225,8 +225,7 @@ module.exports = function (options) {
|
||||
|
||||
new ContextReplacementPlugin(
|
||||
/angular(\\|\/)core(\\|\/)@angular/,
|
||||
root('./src'),
|
||||
{}
|
||||
root('./src'), {}
|
||||
),
|
||||
|
||||
/**
|
||||
|
332
yarn.lock
332
yarn.lock
@@ -2,79 +2,79 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@angular/animations@4.4.4":
|
||||
version "4.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-4.4.4.tgz#a2f9353604347abe15df98292058842f52f08bc2"
|
||||
"@angular/animations@4.4.5":
|
||||
version "4.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-4.4.5.tgz#5a5a551d757e5a5560098f6f8535c102d93954d7"
|
||||
dependencies:
|
||||
tslib "^1.7.1"
|
||||
|
||||
"@angular/common@4.4.4":
|
||||
version "4.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@angular/common/-/common-4.4.4.tgz#ae0a818aaa0c6a3f0901e7b80bd94e1c22eb9365"
|
||||
"@angular/common@4.4.5":
|
||||
version "4.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@angular/common/-/common-4.4.5.tgz#bd5179dc922adbf4c3ea6dfb19e73cb849ffdc37"
|
||||
dependencies:
|
||||
tslib "^1.7.1"
|
||||
|
||||
"@angular/compiler-cli@4.4.4":
|
||||
version "4.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-4.4.4.tgz#063080a497d9175396825050222c717da184f6cf"
|
||||
"@angular/compiler-cli@4.4.5":
|
||||
version "4.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-4.4.5.tgz#61fa0336acd1a208c5f1c5c6d4df679e99953248"
|
||||
dependencies:
|
||||
"@angular/tsc-wrapped" "4.4.4"
|
||||
"@angular/tsc-wrapped" "4.4.5"
|
||||
minimist "^1.2.0"
|
||||
reflect-metadata "^0.1.2"
|
||||
|
||||
"@angular/compiler@4.4.4":
|
||||
version "4.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-4.4.4.tgz#326eb0029d9a3541aaca124def9adc51c36f2b41"
|
||||
"@angular/compiler@4.4.5":
|
||||
version "4.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-4.4.5.tgz#8721a5910f2bb52f09e2d404cad264f35ede5902"
|
||||
dependencies:
|
||||
tslib "^1.7.1"
|
||||
|
||||
"@angular/core@4.4.4":
|
||||
version "4.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@angular/core/-/core-4.4.4.tgz#bd37ecf54158f97489996c9386bd222f80a32f5c"
|
||||
"@angular/core@4.4.5":
|
||||
version "4.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@angular/core/-/core-4.4.5.tgz#54acbcbda11719f883c786a906974abeb132f1a0"
|
||||
dependencies:
|
||||
tslib "^1.7.1"
|
||||
|
||||
"@angular/forms@4.4.4":
|
||||
version "4.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-4.4.4.tgz#4db3790509b6b10f1db8a7c1b7f52187cf64cfd4"
|
||||
"@angular/forms@4.4.5":
|
||||
version "4.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-4.4.5.tgz#e9552086232aab2ce1d08ef198b62204ea13c43b"
|
||||
dependencies:
|
||||
tslib "^1.7.1"
|
||||
|
||||
"@angular/http@4.4.4":
|
||||
version "4.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@angular/http/-/http-4.4.4.tgz#667faf616bb624168eafae6ee92e5eba23a9d1f2"
|
||||
"@angular/http@4.4.5":
|
||||
version "4.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@angular/http/-/http-4.4.5.tgz#2c735ed842401fc2356419268e288dcf2396e84f"
|
||||
dependencies:
|
||||
tslib "^1.7.1"
|
||||
|
||||
"@angular/platform-browser-dynamic@4.4.4":
|
||||
version "4.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-4.4.4.tgz#c3c9eb854a528556a07054127932e527fa932e14"
|
||||
"@angular/platform-browser-dynamic@4.4.5":
|
||||
version "4.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-4.4.5.tgz#774dbdc1d90f775dbf1e319f6ed42b260623b61f"
|
||||
dependencies:
|
||||
tslib "^1.7.1"
|
||||
|
||||
"@angular/platform-browser@4.4.4":
|
||||
version "4.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-4.4.4.tgz#a3898e2e7ba9d84ffa0d47144c6971179c75aee6"
|
||||
"@angular/platform-browser@4.4.5":
|
||||
version "4.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-4.4.5.tgz#74eb91c0b758126f26d53ee56c7cf4668bd9cac5"
|
||||
dependencies:
|
||||
tslib "^1.7.1"
|
||||
|
||||
"@angular/platform-server@4.4.4":
|
||||
version "4.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@angular/platform-server/-/platform-server-4.4.4.tgz#73ee41fa1cec8628fcc03174727b27cb0031b22a"
|
||||
"@angular/platform-server@4.4.5":
|
||||
version "4.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@angular/platform-server/-/platform-server-4.4.5.tgz#76f23b2c384ed7395dc1793cf85978883ba2cb50"
|
||||
dependencies:
|
||||
parse5 "^3.0.1"
|
||||
tslib "^1.7.1"
|
||||
xhr2 "^0.1.4"
|
||||
|
||||
"@angular/router@4.4.4":
|
||||
version "4.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@angular/router/-/router-4.4.4.tgz#7be391096e843cb3e04f9f05d1d65a88df9bc7cf"
|
||||
"@angular/router@4.4.5":
|
||||
version "4.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@angular/router/-/router-4.4.5.tgz#f73130cf487d9a32cc1988afda59665f44a28a89"
|
||||
dependencies:
|
||||
tslib "^1.7.1"
|
||||
|
||||
"@angular/tsc-wrapped@4.4.4":
|
||||
version "4.4.4"
|
||||
resolved "https://registry.yarnpkg.com/@angular/tsc-wrapped/-/tsc-wrapped-4.4.4.tgz#9841821e55616b826ca160250fe85e15fc74ffc3"
|
||||
"@angular/tsc-wrapped@4.4.5":
|
||||
version "4.4.5"
|
||||
resolved "https://registry.yarnpkg.com/@angular/tsc-wrapped/-/tsc-wrapped-4.4.5.tgz#30a0cbb43a663aa75dca984894be4813778ddc9c"
|
||||
dependencies:
|
||||
tsickle "^0.21.0"
|
||||
|
||||
@@ -106,9 +106,9 @@
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@ngrx/store/-/store-4.0.3.tgz#36abacdfa19bfb8506e40de80bae06050a1e15e9"
|
||||
|
||||
"@ngtools/webpack@1.7.2":
|
||||
version "1.7.2"
|
||||
resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-1.7.2.tgz#3fc4de01786dcc2f50d8cbaaa117311e56799977"
|
||||
"@ngtools/webpack@1.7.4":
|
||||
version "1.7.4"
|
||||
resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-1.7.4.tgz#5015c47ebd339045dd89a1bef0497f4524d2c8ed"
|
||||
dependencies:
|
||||
enhanced-resolve "^3.1.0"
|
||||
loader-utils "^1.0.2"
|
||||
@@ -150,42 +150,35 @@
|
||||
"@types/express-serve-static-core" "*"
|
||||
"@types/serve-static" "*"
|
||||
|
||||
"@types/fs-extra@^4.0.0":
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-4.0.2.tgz#7b9b1bbf85962cbe029b5a83c9b530d7c75af3ba"
|
||||
"@types/fs-extra@4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-4.0.0.tgz#1dd742ad5c9bce308f7a52d02ebc01421bc9102f"
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/glob@*":
|
||||
version "5.0.32"
|
||||
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-5.0.32.tgz#aec5cfe987c72f099fdb1184452986aa506d5e8f"
|
||||
dependencies:
|
||||
"@types/minimatch" "*"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/hammerjs@2.0.35":
|
||||
version "2.0.35"
|
||||
resolved "https://registry.yarnpkg.com/@types/hammerjs/-/hammerjs-2.0.35.tgz#7b7c950c7d54593e23bffc8d2b4feba9866a7277"
|
||||
|
||||
"@types/handlebars@^4.0.31":
|
||||
version "4.0.36"
|
||||
resolved "https://registry.yarnpkg.com/@types/handlebars/-/handlebars-4.0.36.tgz#ff57c77fa1ab6713bb446534ddc4d979707a3a79"
|
||||
"@types/handlebars@4.0.31":
|
||||
version "4.0.31"
|
||||
resolved "https://registry.yarnpkg.com/@types/handlebars/-/handlebars-4.0.31.tgz#a7fba66fafe42713aee88eeca8db91192efe6e72"
|
||||
|
||||
"@types/highlight.js@^9.1.8":
|
||||
version "9.1.10"
|
||||
resolved "https://registry.yarnpkg.com/@types/highlight.js/-/highlight.js-9.1.10.tgz#b621f809cd9573b80992b90cffc5788208e3069c"
|
||||
"@types/highlight.js@9.1.8":
|
||||
version "9.1.8"
|
||||
resolved "https://registry.yarnpkg.com/@types/highlight.js/-/highlight.js-9.1.8.tgz#d227f18bcb8f3f187e16965f2444859a04689758"
|
||||
|
||||
"@types/jasmine@2.6.0":
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-2.6.0.tgz#997b41a27752b4850af2683bc4a8d8222c25bd02"
|
||||
|
||||
"@types/lodash@^4.14.37":
|
||||
version "4.14.76"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.76.tgz#87874f766774d54e89589697340be9496fb8bf70"
|
||||
"@types/lodash@4.14.74":
|
||||
version "4.14.74"
|
||||
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.74.tgz#ac3bd8db988e7f7038e5d22bd76a7ba13f876168"
|
||||
|
||||
"@types/marked@0.0.28":
|
||||
version "0.0.28"
|
||||
resolved "https://registry.yarnpkg.com/@types/marked/-/marked-0.0.28.tgz#44ba754e9fa51432583e8eb30a7c4dd249b52faa"
|
||||
"@types/marked@0.3.0":
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/marked/-/marked-0.3.0.tgz#583c223dd33385a1dda01aaf77b0cd0411c4b524"
|
||||
|
||||
"@types/memory-cache@0.0.31":
|
||||
version "0.0.31"
|
||||
@@ -195,13 +188,13 @@
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.0.tgz#5a7306e367c539b9f6543499de8dd519fac37a8b"
|
||||
|
||||
"@types/minimatch@*", "@types/minimatch@^2.0.29":
|
||||
"@types/minimatch@2.0.29":
|
||||
version "2.0.29"
|
||||
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-2.0.29.tgz#5002e14f75e2d71e564281df0431c8c1b4a2a36a"
|
||||
|
||||
"@types/node@*", "@types/node@8.0.26":
|
||||
version "8.0.26"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.26.tgz#4d58be925306fd22b1141085535a0268b8beb189"
|
||||
"@types/node@*", "@types/node@8.0.34":
|
||||
version "8.0.34"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.34.tgz#55f801fa2ddb2a40dd6dfc15ecfe1dde9c129fe9"
|
||||
|
||||
"@types/node@^6.0.46":
|
||||
version "6.0.88"
|
||||
@@ -222,11 +215,10 @@
|
||||
"@types/express-serve-static-core" "*"
|
||||
"@types/mime" "*"
|
||||
|
||||
"@types/shelljs@^0.7.0":
|
||||
version "0.7.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.7.4.tgz#137b5f31306eaff4de120ffe5b9d74b297809cfc"
|
||||
"@types/shelljs@0.7.0":
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.7.0.tgz#229c157c6bc1e67d6b990e6c5e18dbd2ff58cff0"
|
||||
dependencies:
|
||||
"@types/glob" "*"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/source-map@0.5.1":
|
||||
@@ -576,15 +568,15 @@ atob@~1.1.0:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/atob/-/atob-1.1.3.tgz#95f13629b12c3a51a5d215abdce2aa9f32f80773"
|
||||
|
||||
autoprefixer@7.1.4, autoprefixer@^7.1.1:
|
||||
version "7.1.4"
|
||||
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.1.4.tgz#960847dbaa4016bc8e8e52ec891cbf8f1257a748"
|
||||
autoprefixer@7.1.5, autoprefixer@^7.1.1:
|
||||
version "7.1.5"
|
||||
resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-7.1.5.tgz#d65d14b83c7cd1dd7bc801daa00557addf5a06b2"
|
||||
dependencies:
|
||||
browserslist "^2.4.0"
|
||||
caniuse-lite "^1.0.30000726"
|
||||
browserslist "^2.5.0"
|
||||
caniuse-lite "^1.0.30000744"
|
||||
normalize-range "^0.1.2"
|
||||
num2fraction "^1.2.2"
|
||||
postcss "^6.0.11"
|
||||
postcss "^6.0.13"
|
||||
postcss-value-parser "^3.2.3"
|
||||
|
||||
autoprefixer@^6.3.1:
|
||||
@@ -790,13 +782,9 @@ blocking-proxy@0.0.5:
|
||||
dependencies:
|
||||
minimist "^1.2.0"
|
||||
|
||||
bluebird@^2.10.2:
|
||||
version "2.11.0"
|
||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1"
|
||||
|
||||
bluebird@^3.3.0, bluebird@^3.4.7:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.0.tgz#791420d7f551eea2897453a8a77653f96606d67c"
|
||||
bluebird@^3.3.0, bluebird@^3.4.7, bluebird@^3.5.1:
|
||||
version "3.5.1"
|
||||
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9"
|
||||
|
||||
bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0:
|
||||
version "4.11.8"
|
||||
@@ -972,12 +960,12 @@ browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6:
|
||||
caniuse-db "^1.0.30000639"
|
||||
electron-to-chromium "^1.2.7"
|
||||
|
||||
browserslist@^2.0.0, browserslist@^2.4.0:
|
||||
version "2.4.0"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.4.0.tgz#693ee93d01e66468a6348da5498e011f578f87f8"
|
||||
browserslist@^2.0.0, browserslist@^2.5.0:
|
||||
version "2.5.1"
|
||||
resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-2.5.1.tgz#68e4bc536bbcc6086d62843a2ffccea8396821c6"
|
||||
dependencies:
|
||||
caniuse-lite "^1.0.30000718"
|
||||
electron-to-chromium "^1.3.18"
|
||||
caniuse-lite "^1.0.30000744"
|
||||
electron-to-chromium "^1.3.24"
|
||||
|
||||
buffer-crc32@^0.2.1:
|
||||
version "0.2.13"
|
||||
@@ -1089,9 +1077,9 @@ caniuse-lite@1.0.30000697:
|
||||
version "1.0.30000697"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000697.tgz#125fb00604b63fbb188db96a667ce2922dcd6cdd"
|
||||
|
||||
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000718, caniuse-lite@^1.0.30000726:
|
||||
version "1.0.30000740"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000740.tgz#f2c4c04d6564eb812e61006841700ad557f6f973"
|
||||
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000744:
|
||||
version "1.0.30000745"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000745.tgz#20d6fede1157a4935133502946fc7e0e6b880da5"
|
||||
|
||||
capture-stack-trace@^1.0.0:
|
||||
version "1.0.0"
|
||||
@@ -1112,11 +1100,11 @@ center-align@^0.1.1:
|
||||
align-text "^0.1.3"
|
||||
lazy-cache "^1.0.3"
|
||||
|
||||
cerialize@0.1.16:
|
||||
version "0.1.16"
|
||||
resolved "https://registry.yarnpkg.com/cerialize/-/cerialize-0.1.16.tgz#88678bffbd7817a90aa5b58a8c66d6bdca3035be"
|
||||
cerialize@0.1.18:
|
||||
version "0.1.18"
|
||||
resolved "https://registry.yarnpkg.com/cerialize/-/cerialize-0.1.18.tgz#d0f4f1b61cec7e4ed16a3eda0cac2bc99787414d"
|
||||
dependencies:
|
||||
typescript "^2.1.6"
|
||||
typescript "^2.5.0"
|
||||
|
||||
chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3:
|
||||
version "1.1.3"
|
||||
@@ -1245,9 +1233,9 @@ code-point-at@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
|
||||
|
||||
codelyzer@3.2.0:
|
||||
version "3.2.0"
|
||||
resolved "https://registry.yarnpkg.com/codelyzer/-/codelyzer-3.2.0.tgz#68eb0a67771ea73006b517053c3035c1838abf14"
|
||||
codelyzer@3.2.1:
|
||||
version "3.2.1"
|
||||
resolved "https://registry.yarnpkg.com/codelyzer/-/codelyzer-3.2.1.tgz#5b1ac75f7e0eb04647842ee29a322bf2167e7229"
|
||||
dependencies:
|
||||
app-root-path "^2.0.1"
|
||||
css-selector-tokenizer "^0.7.0"
|
||||
@@ -1472,17 +1460,17 @@ copy-descriptor@^0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
|
||||
|
||||
copy-webpack-plugin@4.1.0:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-4.1.0.tgz#292a040318fe8ae3b1d7996ef05dfb483eb0b647"
|
||||
copy-webpack-plugin@4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-4.1.1.tgz#53ae69e04955ebfa9fda411f54cbb968531d71fd"
|
||||
dependencies:
|
||||
bluebird "^2.10.2"
|
||||
fs-extra "^0.26.4"
|
||||
glob "^6.0.4"
|
||||
is-glob "^3.1.0"
|
||||
bluebird "^3.5.1"
|
||||
fs-extra "^4.0.2"
|
||||
glob "^7.1.2"
|
||||
is-glob "^4.0.0"
|
||||
loader-utils "^0.2.15"
|
||||
lodash "^4.3.0"
|
||||
minimatch "^3.0.0"
|
||||
minimatch "^3.0.4"
|
||||
node-dir "^0.1.10"
|
||||
|
||||
core-js@2.5.1, core-js@^2.2.0, core-js@^2.4.0:
|
||||
@@ -2028,7 +2016,7 @@ ejs@^2.5.6:
|
||||
version "2.5.7"
|
||||
resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.5.7.tgz#cc872c168880ae3c7189762fd5ffc00896c9518a"
|
||||
|
||||
electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.18:
|
||||
electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.24:
|
||||
version "1.3.24"
|
||||
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.24.tgz#9b7b88bb05ceb9fa016a177833cc2dde388f21b6"
|
||||
|
||||
@@ -2400,9 +2388,9 @@ express-session@1.15.6:
|
||||
uid-safe "~2.1.5"
|
||||
utils-merge "1.0.1"
|
||||
|
||||
express@4.16.1, express@^4.13.3, express@^4.15.2:
|
||||
version "4.16.1"
|
||||
resolved "https://registry.yarnpkg.com/express/-/express-4.16.1.tgz#6b33b560183c9b253b7b62144df33a4654ac9ed0"
|
||||
express@4.16.2, express@^4.13.3, express@^4.15.2:
|
||||
version "4.16.2"
|
||||
resolved "https://registry.yarnpkg.com/express/-/express-4.16.2.tgz#e35c6dfe2d64b7dca0a5cd4f21781be3299e076c"
|
||||
dependencies:
|
||||
accepts "~1.3.4"
|
||||
array-flatten "1.1.1"
|
||||
@@ -2666,17 +2654,7 @@ fs-extra@^0.22.1:
|
||||
jsonfile "^2.1.0"
|
||||
rimraf "^2.2.8"
|
||||
|
||||
fs-extra@^0.26.4:
|
||||
version "0.26.7"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-0.26.7.tgz#9ae1fdd94897798edab76d0918cf42d0c3184fa9"
|
||||
dependencies:
|
||||
graceful-fs "^4.1.2"
|
||||
jsonfile "^2.1.0"
|
||||
klaw "^1.0.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
rimraf "^2.2.8"
|
||||
|
||||
fs-extra@^4.0.0, fs-extra@^4.0.1:
|
||||
fs-extra@^4.0.0, fs-extra@^4.0.1, fs-extra@^4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-4.0.2.tgz#f91704c53d1b461f893452b0c307d9997647ab6b"
|
||||
dependencies:
|
||||
@@ -2802,17 +2780,7 @@ glob@^5.0.15:
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
glob@^6.0.4:
|
||||
version "6.0.4"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-6.0.4.tgz#0f08860f6a155127b2fadd4f9ce24b1aab6e4d22"
|
||||
dependencies:
|
||||
inflight "^1.0.4"
|
||||
inherits "2"
|
||||
minimatch "2 || 3"
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1, glob@~7.1.1:
|
||||
glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.0.6, glob@^7.1.1, glob@^7.1.2, glob@~7.1.1:
|
||||
version "7.1.2"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15"
|
||||
dependencies:
|
||||
@@ -3430,7 +3398,7 @@ is-extglob@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0"
|
||||
|
||||
is-extglob@^2.1.0:
|
||||
is-extglob@^2.1.0, is-extglob@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2"
|
||||
|
||||
@@ -3462,6 +3430,12 @@ is-glob@^3.1.0:
|
||||
dependencies:
|
||||
is-extglob "^2.1.0"
|
||||
|
||||
is-glob@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0"
|
||||
dependencies:
|
||||
is-extglob "^2.1.1"
|
||||
|
||||
is-module@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591"
|
||||
@@ -3665,11 +3639,11 @@ jasmine-core@2.8.0, jasmine-core@~2.8.0:
|
||||
version "2.8.0"
|
||||
resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-2.8.0.tgz#bcc979ae1f9fd05701e45e52e65d3a5d63f1a24e"
|
||||
|
||||
jasmine-marbles@0.1.0:
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jasmine-marbles/-/jasmine-marbles-0.1.0.tgz#c9ecdc64e20b6cf55b49a10201a5be33907dadcc"
|
||||
jasmine-marbles@0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/jasmine-marbles/-/jasmine-marbles-0.2.0.tgz#b893d8508b75790b634876d3a1bea1345d65c156"
|
||||
dependencies:
|
||||
lodash.isequal "^4.5.0"
|
||||
lodash "^4.5.0"
|
||||
|
||||
jasmine-spec-reporter@4.2.1:
|
||||
version "4.2.1"
|
||||
@@ -3867,9 +3841,9 @@ karma-webdriver-launcher@1.0.5:
|
||||
dependencies:
|
||||
wd "^1.0.0"
|
||||
|
||||
karma-webpack@2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-2.0.4.tgz#3e2d4f48ba94a878e1c66bb8e1ae6128987a175b"
|
||||
karma-webpack@2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/karma-webpack/-/karma-webpack-2.0.5.tgz#4f56887e32cf4f9583391c2388415de06af06efd"
|
||||
dependencies:
|
||||
async "~0.9.0"
|
||||
loader-utils "^0.2.5"
|
||||
@@ -4131,10 +4105,6 @@ lodash.isarray@^3.0.0:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55"
|
||||
|
||||
lodash.isequal@^4.5.0:
|
||||
version "4.5.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0"
|
||||
|
||||
lodash.keys@^3.0.0:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a"
|
||||
@@ -5133,9 +5103,9 @@ pbkdf2@^3.0.3:
|
||||
safe-buffer "^5.0.1"
|
||||
sha.js "^2.4.8"
|
||||
|
||||
pem@1.12.0:
|
||||
version "1.12.0"
|
||||
resolved "https://registry.yarnpkg.com/pem/-/pem-1.12.0.tgz#603d8207b9b5f83225e37ffcc36268c3aa3fecf3"
|
||||
pem@1.12.3:
|
||||
version "1.12.3"
|
||||
resolved "https://registry.yarnpkg.com/pem/-/pem-1.12.3.tgz#b1fb5c8b79da8d18146c27fee79b0d4ddf9905b3"
|
||||
dependencies:
|
||||
md5 "^2.2.1"
|
||||
os-tmpdir "^1.0.1"
|
||||
@@ -5488,12 +5458,12 @@ postcss-load-plugins@^2.3.0:
|
||||
cosmiconfig "^2.1.1"
|
||||
object-assign "^4.1.0"
|
||||
|
||||
postcss-loader@2.0.6:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-2.0.6.tgz#8c7e0055a3df1889abc6bad52dd45b2f41bbc6fc"
|
||||
postcss-loader@2.0.7:
|
||||
version "2.0.7"
|
||||
resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-2.0.7.tgz#4d2da1489cee0a14f72c0d9440c9ee7eded34345"
|
||||
dependencies:
|
||||
loader-utils "^1.1.0"
|
||||
postcss "^6.0.2"
|
||||
postcss "^6.0.0"
|
||||
postcss-load-config "^1.2.0"
|
||||
schema-utils "^0.3.0"
|
||||
|
||||
@@ -5759,7 +5729,7 @@ postcss-zindex@^2.0.1:
|
||||
postcss "^5.0.4"
|
||||
uniqs "^2.0.0"
|
||||
|
||||
postcss@6.0.13:
|
||||
postcss@6.0.13, postcss@^6.0.0, postcss@^6.0.1, postcss@^6.0.11, postcss@^6.0.13, postcss@^6.0.3, postcss@^6.0.5, postcss@^6.0.6, postcss@^6.0.8:
|
||||
version "6.0.13"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.13.tgz#b9ecab4ee00c89db3ec931145bd9590bbf3f125f"
|
||||
dependencies:
|
||||
@@ -5776,14 +5746,6 @@ postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0
|
||||
source-map "^0.5.6"
|
||||
supports-color "^3.2.3"
|
||||
|
||||
postcss@^6.0.0, postcss@^6.0.1, postcss@^6.0.11, postcss@^6.0.2, postcss@^6.0.3, postcss@^6.0.5, postcss@^6.0.6, postcss@^6.0.8:
|
||||
version "6.0.12"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.12.tgz#6b0155089d2d212f7bd6a0cecd4c58c007403535"
|
||||
dependencies:
|
||||
chalk "^2.1.0"
|
||||
source-map "^0.5.7"
|
||||
supports-color "^4.4.0"
|
||||
|
||||
prelude-ls@~1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54"
|
||||
@@ -6332,9 +6294,9 @@ requires-port@1.0.x, requires-port@1.x.x:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
||||
|
||||
resolve-url-loader@2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-2.1.0.tgz#27c95cc16a4353923fdbdc2dbaf5eef22232c477"
|
||||
resolve-url-loader@2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-2.1.1.tgz#5354e87381aae348371e555172c50816708e6c1c"
|
||||
dependencies:
|
||||
adjust-sourcemap-loader "^1.1.0"
|
||||
camelcase "^4.0.0"
|
||||
@@ -6873,10 +6835,14 @@ source-map-url@~0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.3.0.tgz#7ecaf13b57bcd09da8a40c5d269db33799d4aaf9"
|
||||
|
||||
source-map@0.5.x, source-map@>=0.5.6, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.1, source-map@~0.5.3:
|
||||
source-map@0.5.x, source-map@^0.5.1, source-map@^0.5.3, source-map@^0.5.6, source-map@~0.5.1, source-map@~0.5.3:
|
||||
version "0.5.7"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
|
||||
|
||||
source-map@>=0.5.6, source-map@^0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
||||
|
||||
source-map@^0.1.38, source-map@^0.1.41, source-map@~0.1.33:
|
||||
version "0.1.43"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346"
|
||||
@@ -6889,10 +6855,6 @@ source-map@^0.4.2, source-map@^0.4.4:
|
||||
dependencies:
|
||||
amdefine ">=0.0.4"
|
||||
|
||||
source-map@^0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
||||
|
||||
source-map@~0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d"
|
||||
@@ -6958,11 +6920,7 @@ split@0.3:
|
||||
dependencies:
|
||||
through "2"
|
||||
|
||||
sprintf-js@^1.0.3:
|
||||
version "1.1.1"
|
||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.1.tgz#36be78320afe5801f6cea3ee78b6e5aab940ea0c"
|
||||
|
||||
sprintf-js@~1.0.2:
|
||||
sprintf-js@^1.0.3, sprintf-js@~1.0.2:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
|
||||
|
||||
@@ -7409,17 +7367,17 @@ typedoc-default-themes@^0.5.0:
|
||||
version "0.5.0"
|
||||
resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.5.0.tgz#6dc2433e78ed8bea8e887a3acde2f31785bd6227"
|
||||
|
||||
typedoc@0.8.0:
|
||||
version "0.8.0"
|
||||
resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.8.0.tgz#d7172bc6a29964f451b7609c005beadadefe2361"
|
||||
typedoc@0.9.0:
|
||||
version "0.9.0"
|
||||
resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.9.0.tgz#159bff7c7784ce5b91d86f3e4cc8928e62040957"
|
||||
dependencies:
|
||||
"@types/fs-extra" "^4.0.0"
|
||||
"@types/handlebars" "^4.0.31"
|
||||
"@types/highlight.js" "^9.1.8"
|
||||
"@types/lodash" "^4.14.37"
|
||||
"@types/marked" "0.0.28"
|
||||
"@types/minimatch" "^2.0.29"
|
||||
"@types/shelljs" "^0.7.0"
|
||||
"@types/fs-extra" "4.0.0"
|
||||
"@types/handlebars" "4.0.31"
|
||||
"@types/highlight.js" "9.1.8"
|
||||
"@types/lodash" "4.14.74"
|
||||
"@types/marked" "0.3.0"
|
||||
"@types/minimatch" "2.0.29"
|
||||
"@types/shelljs" "0.7.0"
|
||||
fs-extra "^4.0.0"
|
||||
handlebars "^4.0.6"
|
||||
highlight.js "^9.0.0"
|
||||
@@ -7435,7 +7393,7 @@ typescript@2.4.1:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.4.1.tgz#c3ccb16ddaa0b2314de031e7e6fee89e5ba346bc"
|
||||
|
||||
typescript@2.5.3, typescript@^2.1.6:
|
||||
typescript@2.5.3, typescript@^2.5.0:
|
||||
version "2.5.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.5.3.tgz#df3dcdc38f3beb800d4bc322646b04a3f6ca7f0d"
|
||||
|
||||
@@ -7843,9 +7801,9 @@ webpack-sources@^1.0.1:
|
||||
source-list-map "^2.0.0"
|
||||
source-map "~0.5.3"
|
||||
|
||||
webpack@3.6.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.6.0.tgz#a89a929fbee205d35a4fa2cc487be9cbec8898bc"
|
||||
webpack@3.7.1:
|
||||
version "3.7.1"
|
||||
resolved "https://registry.yarnpkg.com/webpack/-/webpack-3.7.1.tgz#6046b5c415ff7df7a0dc54c5b6b86098e8b952da"
|
||||
dependencies:
|
||||
acorn "^5.0.0"
|
||||
acorn-dynamic-import "^2.0.0"
|
||||
|
Reference in New Issue
Block a user