mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-06 17:44:11 +00:00
extend environment and use injected app config
This commit is contained in:
2
.github/workflows/build.yml
vendored
2
.github/workflows/build.yml
vendored
@@ -73,7 +73,7 @@ jobs:
|
||||
run: yarn run lint
|
||||
|
||||
- name: Run build
|
||||
run: yarn run build:ssr:ci
|
||||
run: yarn run build:prod
|
||||
|
||||
- name: Run specs (unit tests)
|
||||
run: yarn run test:headless
|
||||
|
26
angular.json
26
angular.json
@@ -94,22 +94,6 @@
|
||||
"maximumError": "300kb"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ci": {
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.ci.ts"
|
||||
}
|
||||
],
|
||||
"optimization": true,
|
||||
"outputHashing": "all",
|
||||
"extractCss": true,
|
||||
"namedChunks": false,
|
||||
"aot": true,
|
||||
"extractLicenses": true,
|
||||
"vendorChunk": false,
|
||||
"buildOptimizer": true
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -222,16 +206,6 @@
|
||||
"with": "src/environments/environment.prod.ts"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ci": {
|
||||
"sourceMap": false,
|
||||
"optimization": true,
|
||||
"fileReplacements": [
|
||||
{
|
||||
"replace": "src/environments/environment.ts",
|
||||
"with": "src/environments/environment.ci.ts"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
6
nodemon.json
Normal file
6
nodemon.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"watch": [
|
||||
"config"
|
||||
],
|
||||
"ext": "json"
|
||||
}
|
16
package.json
16
package.json
@@ -3,24 +3,25 @@
|
||||
"version": "0.0.0",
|
||||
"scripts": {
|
||||
"ng": "ng",
|
||||
"config:watch": "nodemon",
|
||||
"test:rest": "ts-node --project ./tsconfig.ts-node.json scripts/test-rest.ts",
|
||||
"start": "yarn run start:prod",
|
||||
"serve": "ts-node --project ./tsconfig.ts-node.json scripts/serve.ts",
|
||||
"start:dev": "yarn run serve",
|
||||
"start:dev": "nodemon --exec \"yarn run serve\"",
|
||||
"start:prod": "yarn run build:prod && yarn run serve:ssr",
|
||||
"start:mirador:prod": "yarn run build:mirador && yarn run start:prod",
|
||||
"serve": "ts-node --project ./tsconfig.ts-node.json scripts/serve.ts",
|
||||
"serve:ssr": "node dist/server/main",
|
||||
"analyze": "webpack-bundle-analyzer dist/browser/stats.json",
|
||||
"build": "ng build",
|
||||
"build:stats": "ng build --stats-json",
|
||||
"build:prod": "yarn run build:ssr",
|
||||
"build:ssr": "ng build --configuration production && ng run dspace-angular:server:production",
|
||||
"build:ssr:ci": "ng build --configuration ci && ng run dspace-angular:server:ci",
|
||||
"test": "ng test --sourceMap=true --watch=true --configuration test",
|
||||
"test": "ng test --sourceMap=true --watch=false --configuration test",
|
||||
"test:watch": "nodemon --exec \"ng test --sourceMap=true --watch=true --configuration test\"",
|
||||
"test:headless": "ng test --sourceMap=true --watch=false --configuration test --browsers=ChromeHeadless --code-coverage",
|
||||
"lint": "ng lint",
|
||||
"lint-fix": "ng lint --fix=true",
|
||||
"e2e": "ng e2e",
|
||||
"serve:ssr": "node dist/server/main",
|
||||
"clean:dev:config": "rimraf src/assets/appConfig.json",
|
||||
"clean:coverage": "rimraf coverage",
|
||||
"clean:dist": "rimraf dist",
|
||||
@@ -86,8 +87,8 @@
|
||||
"file-saver": "^2.0.5",
|
||||
"filesize": "^6.1.0",
|
||||
"font-awesome": "4.7.0",
|
||||
"https": "1.0.0",
|
||||
"http-proxy-middleware": "^1.0.5",
|
||||
"https": "1.0.0",
|
||||
"js-cookie": "2.2.1",
|
||||
"json5": "^2.1.3",
|
||||
"jsonschema": "1.4.0",
|
||||
@@ -162,6 +163,7 @@
|
||||
"karma-jasmine": "~4.0.0",
|
||||
"karma-jasmine-html-reporter": "^1.5.0",
|
||||
"karma-mocha-reporter": "2.2.5",
|
||||
"nodemon": "^2.0.15",
|
||||
"optimize-css-assets-webpack-plugin": "^5.0.4",
|
||||
"postcss-apply": "0.11.0",
|
||||
"postcss-import": "^12.0.1",
|
||||
@@ -186,4 +188,4 @@
|
||||
"webpack-cli": "^4.2.0",
|
||||
"webpack-dev-server": "^4.5.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,16 +1,14 @@
|
||||
import * as child from 'child_process';
|
||||
|
||||
import { environment } from '../src/environments/environment';
|
||||
import { AppConfig } from '../src/config/app-config.interface';
|
||||
import { buildAppConfig } from '../src/config/config.server';
|
||||
|
||||
// import { AppConfig } from '../src/config/app-config.interface';
|
||||
// import { buildAppConfig } from '../src/config/config.server';
|
||||
|
||||
// const appConfig: AppConfig = buildAppConfig();
|
||||
const appConfig: AppConfig = buildAppConfig();
|
||||
|
||||
/**
|
||||
* Calls `ng serve` with the following arguments configured for the UI in the environment: host, port, nameSpace, ssl
|
||||
* Calls `ng serve` with the following arguments configured for the UI in the app config: host, port, nameSpace, ssl
|
||||
*/
|
||||
child.spawn(
|
||||
`ng serve --host ${environment.ui.host} --port ${environment.ui.port} --serve-path ${environment.ui.nameSpace} --ssl ${environment.ui.ssl}`,
|
||||
{ stdio:'inherit', shell: true }
|
||||
`ng serve --host ${appConfig.ui.host} --port ${appConfig.ui.port} --serve-path ${appConfig.ui.nameSpace} --ssl ${appConfig.ui.ssl}`,
|
||||
{ stdio: 'inherit', shell: true }
|
||||
);
|
||||
|
@@ -1,15 +1,13 @@
|
||||
import * as http from 'http';
|
||||
import * as https from 'https';
|
||||
|
||||
import { environment } from '../src/environments/environment';
|
||||
|
||||
// import { AppConfig } from '../src/config/app-config.interface';
|
||||
// import { buildAppConfig } from '../src/config/config.server';
|
||||
import { AppConfig } from '../src/config/app-config.interface';
|
||||
import { buildAppConfig } from '../src/config/config.server';
|
||||
|
||||
// const appConfig: AppConfig = buildAppConfig();
|
||||
const appConfig: AppConfig = buildAppConfig();
|
||||
|
||||
/**
|
||||
* Script to test the connection with the configured REST API (in the 'rest' settings of your environment.*.ts)
|
||||
* Script to test the connection with the configured REST API (in the 'rest' settings of your appConfig.*.json)
|
||||
*
|
||||
* This script is useful to test for any Node.js connection issues with your REST API.
|
||||
*
|
||||
@@ -17,11 +15,11 @@ import { environment } from '../src/environments/environment';
|
||||
*/
|
||||
|
||||
// Get root URL of configured REST API
|
||||
const restUrl = environment.rest.baseUrl + '/api';
|
||||
const restUrl = appConfig.rest.baseUrl + '/api';
|
||||
console.log(`...Testing connection to REST API at ${restUrl}...\n`);
|
||||
|
||||
// If SSL enabled, test via HTTPS, else via HTTP
|
||||
if (environment.rest.ssl) {
|
||||
if (appConfig.rest.ssl) {
|
||||
const req = https.request(restUrl, (res) => {
|
||||
console.log(`RESPONSE: ${res.statusCode} ${res.statusMessage} \n`);
|
||||
res.on('data', (data) => {
|
||||
@@ -61,7 +59,7 @@ function checkJSONResponse(responseData: any): any {
|
||||
console.log(`\t"dspaceVersion" = ${parsedData.dspaceVersion}`);
|
||||
console.log(`\t"dspaceUI" = ${parsedData.dspaceUI}`);
|
||||
console.log(`\t"dspaceServer" = ${parsedData.dspaceServer}`);
|
||||
console.log(`\t"dspaceServer" property matches UI's "rest" config? ${(parsedData.dspaceServer === environment.rest.baseUrl)}`);
|
||||
console.log(`\t"dspaceServer" property matches UI's "rest" config? ${(parsedData.dspaceServer === appConfig.rest.baseUrl)}`);
|
||||
// Check for "authn" and "sites" in "_links" section as they should always exist (even if no data)!
|
||||
const linksFound: string[] = Object.keys(parsedData._links);
|
||||
console.log(`\tDoes "/api" endpoint have HAL links ("_links" section)? ${linksFound.includes('authn') && linksFound.includes('sites')}`);
|
||||
|
31
server.ts
31
server.ts
@@ -19,29 +19,33 @@ import 'zone.js/dist/zone-node';
|
||||
import 'reflect-metadata';
|
||||
import 'rxjs';
|
||||
|
||||
import * as fs from 'fs';
|
||||
import * as pem from 'pem';
|
||||
import * as https from 'https';
|
||||
import * as morgan from 'morgan';
|
||||
import * as express from 'express';
|
||||
import * as bodyParser from 'body-parser';
|
||||
import * as compression from 'compression';
|
||||
|
||||
import { existsSync, readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { APP_BASE_HREF } from '@angular/common';
|
||||
import { enableProdMode } from '@angular/core';
|
||||
import { existsSync } from 'fs';
|
||||
|
||||
import { ngExpressEngine } from '@nguniversal/express-engine';
|
||||
import { REQUEST, RESPONSE } from '@nguniversal/express-engine/tokens';
|
||||
|
||||
import { environment } from './src/environments/environment';
|
||||
import { createProxyMiddleware } from 'http-proxy-middleware';
|
||||
import { hasValue, hasNoValue } from './src/app/shared/empty.util';
|
||||
import { APP_BASE_HREF } from '@angular/common';
|
||||
|
||||
import { UIServerConfig } from './src/config/ui-server-config.interface';
|
||||
|
||||
import { ServerAppModule } from './src/main.server';
|
||||
|
||||
// import { buildAppConfig } from './src/config/config.server';
|
||||
// import { AppConfig, APP_CONFIG } from './src/config/app-config.interface';
|
||||
import { buildAppConfig } from './src/config/config.server';
|
||||
import { AppConfig, APP_CONFIG } from './src/config/app-config.interface';
|
||||
import { extendEnvironmentWithAppConfig } from './src/config/config.util';
|
||||
|
||||
/*
|
||||
* Set path for the browser application's dist folder
|
||||
@@ -54,7 +58,10 @@ const indexHtml = existsSync(join(DIST_FOLDER, 'index.html')) ? 'index.html' : '
|
||||
|
||||
const cookieParser = require('cookie-parser');
|
||||
|
||||
// const appConfig: AppConfig = buildAppConfig(join(DIST_FOLDER, 'assets/appConfig.json'));
|
||||
const appConfig: AppConfig = buildAppConfig(join(DIST_FOLDER, 'assets/appConfig.json'));
|
||||
|
||||
// extend environment with app config for server
|
||||
extendEnvironmentWithAppConfig(environment, appConfig);
|
||||
|
||||
// The Express app is exported so that it can be used by serverless Functions.
|
||||
export function app() {
|
||||
@@ -105,10 +112,10 @@ export function app() {
|
||||
provide: RESPONSE,
|
||||
useValue: (options as any).req.res,
|
||||
},
|
||||
// {
|
||||
// provide: APP_CONFIG,
|
||||
// useValue: appConfig
|
||||
// }
|
||||
{
|
||||
provide: APP_CONFIG,
|
||||
useValue: environment
|
||||
}
|
||||
]
|
||||
})(_, (options as any), callback)
|
||||
);
|
||||
@@ -246,14 +253,14 @@ function start() {
|
||||
if (environment.ui.ssl) {
|
||||
let serviceKey;
|
||||
try {
|
||||
serviceKey = fs.readFileSync('./config/ssl/key.pem');
|
||||
serviceKey = readFileSync('./config/ssl/key.pem');
|
||||
} catch (e) {
|
||||
console.warn('Service key not found at ./config/ssl/key.pem');
|
||||
}
|
||||
|
||||
let certificate;
|
||||
try {
|
||||
certificate = fs.readFileSync('./config/ssl/cert.pem');
|
||||
certificate = readFileSync('./config/ssl/cert.pem');
|
||||
} catch (e) {
|
||||
console.warn('Certificate not found at ./config/ssl/key.pem');
|
||||
}
|
||||
|
@@ -36,6 +36,8 @@ import { GoogleAnalyticsService } from './statistics/google-analytics.service';
|
||||
import { ThemeService } from './shared/theme-support/theme.service';
|
||||
import { getMockThemeService } from './shared/mocks/theme-service.mock';
|
||||
import { BreadcrumbsService } from './breadcrumbs/breadcrumbs.service';
|
||||
import { APP_CONFIG } from '../config/app-config.interface';
|
||||
import { environment } from '../environments/environment';
|
||||
|
||||
let comp: AppComponent;
|
||||
let fixture: ComponentFixture<AppComponent>;
|
||||
@@ -83,6 +85,7 @@ describe('App component', () => {
|
||||
{ provide: LocaleService, useValue: getMockLocaleService() },
|
||||
{ provide: ThemeService, useValue: getMockThemeService() },
|
||||
{ provide: BreadcrumbsService, useValue: breadcrumbsServiceSpy },
|
||||
{ provide: APP_CONFIG, useValue: environment },
|
||||
provideMockStore({ initialState }),
|
||||
AppComponent,
|
||||
RouteService
|
||||
|
@@ -18,6 +18,7 @@ import {
|
||||
Router,
|
||||
} from '@angular/router';
|
||||
|
||||
import { isEqual } from 'lodash';
|
||||
import { BehaviorSubject, Observable, of } from 'rxjs';
|
||||
import { select, Store } from '@ngrx/store';
|
||||
import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
|
||||
@@ -46,6 +47,7 @@ import { BASE_THEME_NAME } from './shared/theme-support/theme.constants';
|
||||
import { BreadcrumbsService } from './breadcrumbs/breadcrumbs.service';
|
||||
import { IdleModalComponent } from './shared/idle-modal/idle-modal.component';
|
||||
import { getDefaultThemeConfig } from '../config/config.util';
|
||||
import { AppConfig, APP_CONFIG } from 'src/config/app-config.interface';
|
||||
|
||||
@Component({
|
||||
selector: 'ds-app',
|
||||
@@ -59,7 +61,7 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||
collapsedSidebarWidth: Observable<string>;
|
||||
totalSidebarWidth: Observable<string>;
|
||||
theme: Observable<ThemeConfig> = of({} as any);
|
||||
notificationOptions = environment.notifications;
|
||||
notificationOptions;
|
||||
models;
|
||||
|
||||
/**
|
||||
@@ -88,6 +90,7 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||
@Inject(NativeWindowService) private _window: NativeWindowRef,
|
||||
@Inject(DOCUMENT) private document: any,
|
||||
@Inject(PLATFORM_ID) private platformId: any,
|
||||
@Inject(APP_CONFIG) private appConfig: AppConfig,
|
||||
private themeService: ThemeService,
|
||||
private translate: TranslateService,
|
||||
private store: Store<HostWindowState>,
|
||||
@@ -106,6 +109,14 @@ export class AppComponent implements OnInit, AfterViewInit {
|
||||
@Optional() private googleAnalyticsService: GoogleAnalyticsService,
|
||||
) {
|
||||
|
||||
console.log(this.appConfig);
|
||||
|
||||
if (!isEqual(environment, this.appConfig)) {
|
||||
throw new Error('environment does not match app config!');
|
||||
}
|
||||
|
||||
this.notificationOptions = environment.notifications;
|
||||
|
||||
/* Use models object so all decorators are actually called */
|
||||
this.models = models;
|
||||
|
||||
|
@@ -58,14 +58,18 @@ import { IdleModalComponent } from './shared/idle-modal/idle-modal.component';
|
||||
import { UUIDService } from './core/shared/uuid.service';
|
||||
import { CookieService } from './core/services/cookie.service';
|
||||
|
||||
// import { AppConfig, APP_CONFIG } from '../config/app-config.interface';
|
||||
import { AppConfig, APP_CONFIG } from '../config/app-config.interface';
|
||||
|
||||
export function getBase() {
|
||||
return environment.ui.nameSpace;
|
||||
export function getConfig() {
|
||||
return environment;
|
||||
}
|
||||
|
||||
export function getMetaReducers(): MetaReducer<AppState>[] {
|
||||
return environment.debug ? [...appMetaReducers, ...debugMetaReducers] : appMetaReducers;
|
||||
export function getBase(appConfig: AppConfig) {
|
||||
return appConfig.ui.nameSpace;
|
||||
}
|
||||
|
||||
export function getMetaReducers(appConfig: AppConfig): MetaReducer<AppState>[] {
|
||||
return appConfig.debug ? [...appMetaReducers, ...debugMetaReducers] : appMetaReducers;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,15 +104,19 @@ IMPORTS.push(
|
||||
);
|
||||
|
||||
const PROVIDERS = [
|
||||
{
|
||||
provide: APP_CONFIG,
|
||||
useFactory: getConfig
|
||||
},
|
||||
{
|
||||
provide: APP_BASE_HREF,
|
||||
useFactory: getBase,
|
||||
// deps: [APP_CONFIG]
|
||||
deps: [APP_CONFIG]
|
||||
},
|
||||
{
|
||||
provide: USER_PROVIDED_META_REDUCERS,
|
||||
useFactory: getMetaReducers,
|
||||
// deps: [APP_CONFIG]
|
||||
deps: [APP_CONFIG]
|
||||
},
|
||||
{
|
||||
provide: RouterStateSerializer,
|
||||
@@ -199,7 +207,7 @@ const EXPORTS = [
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
BrowserModule.withServerTransition({ appId: 'serverApp' }),
|
||||
BrowserModule.withServerTransition({ appId: 'dspace-angular' }),
|
||||
...IMPORTS
|
||||
],
|
||||
providers: [
|
||||
|
@@ -36,9 +36,10 @@ export class ItemComponent implements OnInit {
|
||||
*/
|
||||
iiifQuery$: Observable<string>;
|
||||
|
||||
mediaViewer = environment.mediaViewer;
|
||||
mediaViewer;
|
||||
|
||||
constructor(protected routeService: RouteService) {
|
||||
this.mediaViewer = environment.mediaViewer;
|
||||
}
|
||||
|
||||
ngOnInit(): void {
|
||||
|
@@ -32,7 +32,7 @@ export class RootComponent implements OnInit {
|
||||
collapsedSidebarWidth: Observable<string>;
|
||||
totalSidebarWidth: Observable<string>;
|
||||
theme: Observable<ThemeConfig> = of({} as any);
|
||||
notificationOptions = environment.notifications;
|
||||
notificationOptions;
|
||||
models;
|
||||
|
||||
/**
|
||||
@@ -58,6 +58,7 @@ export class RootComponent implements OnInit {
|
||||
private menuService: MenuService,
|
||||
private windowService: HostWindowService
|
||||
) {
|
||||
this.notificationOptions = environment.notifications;
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
|
@@ -14,6 +14,7 @@ import { ThemeConfig } from './theme.model';
|
||||
import { AuthConfig } from './auth-config.interfaces';
|
||||
import { UIServerConfig } from './ui-server-config.interface';
|
||||
import { MediaViewerConfig } from './media-viewer-config.interface';
|
||||
import { makeStateKey } from '@angular/platform-browser';
|
||||
|
||||
interface AppConfig extends Config {
|
||||
ui: UIServerConfig;
|
||||
@@ -37,7 +38,10 @@ interface AppConfig extends Config {
|
||||
|
||||
const APP_CONFIG = new InjectionToken<AppConfig>('APP_CONFIG');
|
||||
|
||||
const APP_CONFIG_STATE = makeStateKey('APP_CONFIG_STATE');
|
||||
|
||||
export {
|
||||
AppConfig,
|
||||
APP_CONFIG
|
||||
APP_CONFIG,
|
||||
APP_CONFIG_STATE
|
||||
};
|
||||
|
@@ -2,13 +2,11 @@ import * as colors from 'colors';
|
||||
import * as fs from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
import { environment } from '../environments/environment';
|
||||
|
||||
import { AppConfig } from './app-config.interface';
|
||||
import { Config } from './config.interface';
|
||||
import { DefaultAppConfig } from './default-app-config';
|
||||
import { ServerConfig } from './server-config.interface';
|
||||
import { extendConfig, extendEnvironmentWithAppConfig } from './config.util';
|
||||
import { extendConfig } from './config.util';
|
||||
import { isNotEmpty } from '../app/shared/empty.util';
|
||||
|
||||
const CONFIG_PATH = join(process.cwd(), 'config');
|
||||
@@ -182,9 +180,6 @@ export const buildAppConfig = (destConfigPath?: string): AppConfig => {
|
||||
buildBaseUrl(appConfig.ui);
|
||||
buildBaseUrl(appConfig.rest);
|
||||
|
||||
// extend environment with app config for server side use
|
||||
extendEnvironmentWithAppConfig(environment, appConfig);
|
||||
|
||||
if (isNotEmpty(destConfigPath)) {
|
||||
fs.writeFileSync(destConfigPath, JSON.stringify(appConfig, null, 2));
|
||||
|
||||
|
@@ -18,7 +18,7 @@ import { UIServerConfig } from './ui-server-config.interface';
|
||||
import { UniversalConfig } from './universal-config.interface';
|
||||
|
||||
export class DefaultAppConfig implements AppConfig {
|
||||
production: boolean = false;
|
||||
production = false;
|
||||
|
||||
// Angular Universal server settings.
|
||||
// NOTE: these must be 'synced' with the 'dspace.ui.url' setting in your backend's local.cfg.
|
||||
@@ -172,10 +172,10 @@ export class DefaultAppConfig implements AppConfig {
|
||||
};
|
||||
|
||||
// NOTE: will log all redux actions and transfers in console
|
||||
debug: boolean = false;
|
||||
debug = false;
|
||||
|
||||
// Default Language in which the UI will be rendered if the user's browser language is not an active language
|
||||
defaultLanguage: string = 'en';
|
||||
defaultLanguage = 'en';
|
||||
|
||||
// Languages. DSpace Angular holds a message catalog for each of the following languages.
|
||||
// When set to active, users will be able to switch to the use of this language in the user interface.
|
||||
|
@@ -1,294 +0,0 @@
|
||||
import { BrowseByType } from '../app/browse-by/browse-by-switcher/browse-by-decorator';
|
||||
import { RestRequestMethod } from '../app/core/data/rest-request-method';
|
||||
import { NotificationAnimationsType } from '../app/shared/notifications/models/notification-animations-type';
|
||||
import { AppConfig } from '../config/app-config.interface';
|
||||
|
||||
export const environment: AppConfig = {
|
||||
production: true,
|
||||
|
||||
// Angular Universal settings
|
||||
universal: {
|
||||
preboot: true,
|
||||
async: true,
|
||||
time: false
|
||||
},
|
||||
|
||||
// Angular Universal server settings.
|
||||
// NOTE: these must be 'synced' with the 'dspace.ui.url' setting in your backend's local.cfg.
|
||||
ui: {
|
||||
ssl: false,
|
||||
host: 'localhost',
|
||||
port: 4000,
|
||||
// NOTE: Space is capitalized because 'namespace' is a reserved string in TypeScript
|
||||
nameSpace: '/',
|
||||
baseUrl: 'http://localhost:4000/',
|
||||
|
||||
// The rateLimiter settings limit each IP to a 'max' of 500 requests per 'windowMs' (1 minute).
|
||||
rateLimiter: {
|
||||
windowMs: 1 * 60 * 1000, // 1 minute
|
||||
max: 500 // limit each IP to 500 requests per windowMs
|
||||
}
|
||||
},
|
||||
|
||||
// The REST API server settings.
|
||||
// NOTE: these must be 'synced' with the 'dspace.server.url' setting in your backend's local.cfg.
|
||||
rest: {
|
||||
ssl: false,
|
||||
host: 'localhost',
|
||||
port: 8080,
|
||||
// NOTE: Space is capitalized because 'namespace' is a reserved string in TypeScript
|
||||
nameSpace: '/server',
|
||||
baseUrl: 'http://localhost:8080/server'
|
||||
},
|
||||
|
||||
// Caching settings
|
||||
cache: {
|
||||
// NOTE: how long should objects be cached for by default
|
||||
msToLive: {
|
||||
default: 15 * 60 * 1000 // 15 minutes
|
||||
},
|
||||
control: 'max-age=60', // revalidate browser
|
||||
autoSync: {
|
||||
defaultTime: 0,
|
||||
maxBufferSize: 100,
|
||||
timePerMethod: { [RestRequestMethod.PATCH]: 3 } as any // time in seconds
|
||||
}
|
||||
},
|
||||
|
||||
// Authentication settings
|
||||
auth: {
|
||||
// Authentication UI settings
|
||||
ui: {
|
||||
// the amount of time before the idle warning is shown
|
||||
timeUntilIdle: 15 * 60 * 1000, // 15 minutes
|
||||
// the amount of time the user has to react after the idle warning is shown before they are logged out.
|
||||
idleGracePeriod: 5 * 60 * 1000 // 5 minutes
|
||||
},
|
||||
// Authentication REST settings
|
||||
rest: {
|
||||
// If the rest token expires in less than this amount of time, it will be refreshed automatically.
|
||||
// This is independent from the idle warning.
|
||||
timeLeftBeforeTokenRefresh: 2 * 60 * 1000 // 2 minutes
|
||||
}
|
||||
},
|
||||
|
||||
// Form settings
|
||||
form: {
|
||||
// NOTE: Map server-side validators to comparative Angular form validators
|
||||
validatorMap: {
|
||||
required: 'required',
|
||||
regex: 'pattern'
|
||||
}
|
||||
},
|
||||
|
||||
// Notifications
|
||||
notifications: {
|
||||
rtl: false,
|
||||
position: ['top', 'right'],
|
||||
maxStack: 8,
|
||||
// NOTE: after how many seconds notification is closed automatically. If set to zero notifications are not closed automatically
|
||||
timeOut: 5000, // 5 second
|
||||
clickToClose: true,
|
||||
// NOTE: 'fade' | 'fromTop' | 'fromRight' | 'fromBottom' | 'fromLeft' | 'rotate' | 'scale'
|
||||
animate: NotificationAnimationsType.Scale
|
||||
},
|
||||
|
||||
// Submission settings
|
||||
submission: {
|
||||
autosave: {
|
||||
// NOTE: which metadata trigger an autosave
|
||||
metadata: [],
|
||||
/**
|
||||
* NOTE: after how many time (milliseconds) submission is saved automatically
|
||||
* eg. timer: 5 * (1000 * 60); // 5 minutes
|
||||
*/
|
||||
timer: 0
|
||||
},
|
||||
icons: {
|
||||
metadata: [
|
||||
/**
|
||||
* NOTE: example of configuration
|
||||
* {
|
||||
* // NOTE: metadata name
|
||||
* name: 'dc.author',
|
||||
* // NOTE: fontawesome (v5.x) icon classes and bootstrap utility classes can be used
|
||||
* style: 'fa-user'
|
||||
* }
|
||||
*/
|
||||
{
|
||||
name: 'dc.author',
|
||||
style: 'fas fa-user'
|
||||
},
|
||||
// default configuration
|
||||
{
|
||||
name: 'default',
|
||||
style: ''
|
||||
}
|
||||
],
|
||||
authority: {
|
||||
confidence: [
|
||||
/**
|
||||
* NOTE: example of configuration
|
||||
* {
|
||||
* // NOTE: confidence value
|
||||
* value: 'dc.author',
|
||||
* // NOTE: fontawesome (v4.x) icon classes and bootstrap utility classes can be used
|
||||
* style: 'fa-user'
|
||||
* }
|
||||
*/
|
||||
{
|
||||
value: 600,
|
||||
style: 'text-success'
|
||||
},
|
||||
{
|
||||
value: 500,
|
||||
style: 'text-info'
|
||||
},
|
||||
{
|
||||
value: 400,
|
||||
style: 'text-warning'
|
||||
},
|
||||
// default configuration
|
||||
{
|
||||
value: 'default',
|
||||
style: 'text-muted'
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// NOTE: will log all redux actions and transfers in console
|
||||
debug: false,
|
||||
|
||||
// Default Language in which the UI will be rendered if the user's browser language is not an active language
|
||||
defaultLanguage: 'en',
|
||||
|
||||
// Languages. DSpace Angular holds a message catalog for each of the following languages.
|
||||
// When set to active, users will be able to switch to the use of this language in the user interface.
|
||||
languages: [
|
||||
{ code: 'en', label: 'English', active: true },
|
||||
{ code: 'cs', label: 'Čeština', active: true },
|
||||
{ code: 'de', label: 'Deutsch', active: true },
|
||||
{ code: 'es', label: 'Español', active: true },
|
||||
{ code: 'fr', label: 'Français', active: true },
|
||||
{ code: 'lv', label: 'Latviešu', active: true },
|
||||
{ code: 'hu', label: 'Magyar', active: true },
|
||||
{ code: 'nl', label: 'Nederlands', active: true },
|
||||
{ code: 'pt-PT', label: 'Português', active: true },
|
||||
{ code: 'pt-BR', label: 'Português do Brasil', active: true },
|
||||
{ code: 'fi', label: 'Suomi', active: true }
|
||||
],
|
||||
|
||||
// Browse-By Pages
|
||||
browseBy: {
|
||||
// Amount of years to display using jumps of one year (current year - oneYearLimit)
|
||||
oneYearLimit: 10,
|
||||
// Limit for years to display using jumps of five years (current year - fiveYearLimit)
|
||||
fiveYearLimit: 30,
|
||||
// The absolute lowest year to display in the dropdown (only used when no lowest date can be found for all items)
|
||||
defaultLowerLimit: 1900,
|
||||
// List of all the active Browse-By types
|
||||
// Adding a type will activate their Browse-By page and add them to the global navigation menu,
|
||||
// as well as community and collection pages
|
||||
// Allowed fields and their purpose:
|
||||
// id: The browse id to use for fetching info from the rest api
|
||||
// type: The type of Browse-By page to display
|
||||
// metadataField: The metadata-field used to create starts-with options (only necessary when the type is set to 'date')
|
||||
types: [
|
||||
{
|
||||
id: 'title',
|
||||
type: BrowseByType.Title,
|
||||
},
|
||||
{
|
||||
id: 'dateissued',
|
||||
type: BrowseByType.Date,
|
||||
metadataField: 'dc.date.issued'
|
||||
},
|
||||
{
|
||||
id: 'author',
|
||||
type: BrowseByType.Metadata
|
||||
},
|
||||
{
|
||||
id: 'subject',
|
||||
type: BrowseByType.Metadata
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// Item Page Config
|
||||
item: {
|
||||
edit: {
|
||||
undoTimeout: 10000 // 10 seconds
|
||||
}
|
||||
},
|
||||
|
||||
// Collection Page Config
|
||||
collection: {
|
||||
edit: {
|
||||
undoTimeout: 10000 // 10 seconds
|
||||
}
|
||||
},
|
||||
|
||||
// Theme Config
|
||||
themes: [
|
||||
// Add additional themes here. In the case where multiple themes match a route, the first one
|
||||
// in this list will get priority. It is advisable to always have a theme that matches
|
||||
// every route as the last one
|
||||
|
||||
// {
|
||||
// // A theme with a handle property will match the community, collection or item with the given
|
||||
// // handle, and all collections and/or items within it
|
||||
// name: 'custom',
|
||||
// handle: '10673/1233'
|
||||
// },
|
||||
// {
|
||||
// // A theme with a regex property will match the route using a regular expression. If it
|
||||
// // matches the route for a community or collection it will also apply to all collections
|
||||
// // and/or items within it
|
||||
// name: 'custom',
|
||||
// regex: 'collections\/e8043bc2.*'
|
||||
// },
|
||||
// {
|
||||
// // A theme with a uuid property will match the community, collection or item with the given
|
||||
// // ID, and all collections and/or items within it
|
||||
// name: 'custom',
|
||||
// uuid: '0958c910-2037-42a9-81c7-dca80e3892b4'
|
||||
// },
|
||||
// {
|
||||
// // The extends property specifies an ancestor theme (by name). Whenever a themed component is not found
|
||||
// // in the current theme, its ancestor theme(s) will be checked recursively before falling back to default.
|
||||
// name: 'custom-A',
|
||||
// extends: 'custom-B',
|
||||
// // Any of the matching properties above can be used
|
||||
// handle: '10673/34'
|
||||
// },
|
||||
// {
|
||||
// name: 'custom-B',
|
||||
// extends: 'custom',
|
||||
// handle: '10673/12'
|
||||
// },
|
||||
// {
|
||||
// // A theme with only a name will match every route
|
||||
// name: 'custom'
|
||||
// },
|
||||
// {
|
||||
// // This theme will use the default bootstrap styling for DSpace components
|
||||
// name: BASE_THEME_NAME
|
||||
// },
|
||||
|
||||
{
|
||||
// The default dspace theme
|
||||
name: 'dspace'
|
||||
}
|
||||
],
|
||||
|
||||
// Whether to enable media viewer for image and/or video Bitstreams (i.e. Bitstreams whose MIME type starts with 'image' or 'video').
|
||||
// For images, this enables a gallery viewer where you can zoom or page through images.
|
||||
// For videos, this enables embedded video streaming
|
||||
mediaViewer: {
|
||||
image: false,
|
||||
video: false
|
||||
}
|
||||
};
|
@@ -1,9 +1,6 @@
|
||||
import { BrowseByType } from '../app/browse-by/browse-by-switcher/browse-by-decorator';
|
||||
import { RestRequestMethod } from '../app/core/data/rest-request-method';
|
||||
import { NotificationAnimationsType } from '../app/shared/notifications/models/notification-animations-type';
|
||||
import { AppConfig } from '../config/app-config.interface';
|
||||
|
||||
export const environment: AppConfig = {
|
||||
export const environment: Partial<AppConfig> = {
|
||||
production: true,
|
||||
|
||||
// Angular Universal settings
|
||||
@@ -11,284 +8,5 @@ export const environment: AppConfig = {
|
||||
preboot: true,
|
||||
async: true,
|
||||
time: false
|
||||
},
|
||||
|
||||
// Angular Universal server settings.
|
||||
// NOTE: these must be 'synced' with the 'dspace.ui.url' setting in your backend's local.cfg.
|
||||
ui: {
|
||||
ssl: false,
|
||||
host: 'localhost',
|
||||
port: 4000,
|
||||
// NOTE: Space is capitalized because 'namespace' is a reserved string in TypeScript
|
||||
nameSpace: '/',
|
||||
baseUrl: 'http://localhost:4000/',
|
||||
|
||||
// The rateLimiter settings limit each IP to a 'max' of 500 requests per 'windowMs' (1 minute).
|
||||
rateLimiter: {
|
||||
windowMs: 1 * 60 * 1000, // 1 minute
|
||||
max: 500 // limit each IP to 500 requests per windowMs
|
||||
}
|
||||
},
|
||||
|
||||
// The REST API server settings.
|
||||
// NOTE: these must be 'synced' with the 'dspace.server.url' setting in your backend's local.cfg.
|
||||
rest: {
|
||||
ssl: true,
|
||||
host: 'api7.dspace.org',
|
||||
port: 443,
|
||||
// NOTE: Space is capitalized because 'namespace' is a reserved string in TypeScript
|
||||
nameSpace: '/server',
|
||||
baseUrl: 'https://api7.dspace.org/server'
|
||||
},
|
||||
|
||||
// Caching settings
|
||||
cache: {
|
||||
// NOTE: how long should objects be cached for by default
|
||||
msToLive: {
|
||||
default: 15 * 60 * 1000 // 15 minutes
|
||||
},
|
||||
control: 'max-age=60', // revalidate browser
|
||||
autoSync: {
|
||||
defaultTime: 0,
|
||||
maxBufferSize: 100,
|
||||
timePerMethod: { [RestRequestMethod.PATCH]: 3 } as any // time in seconds
|
||||
}
|
||||
},
|
||||
|
||||
// Authentication settings
|
||||
auth: {
|
||||
// Authentication UI settings
|
||||
ui: {
|
||||
// the amount of time before the idle warning is shown
|
||||
timeUntilIdle: 15 * 60 * 1000, // 15 minutes
|
||||
// the amount of time the user has to react after the idle warning is shown before they are logged out.
|
||||
idleGracePeriod: 5 * 60 * 1000 // 5 minutes
|
||||
},
|
||||
// Authentication REST settings
|
||||
rest: {
|
||||
// If the rest token expires in less than this amount of time, it will be refreshed automatically.
|
||||
// This is independent from the idle warning.
|
||||
timeLeftBeforeTokenRefresh: 2 * 60 * 1000 // 2 minutes
|
||||
}
|
||||
},
|
||||
|
||||
// Form settings
|
||||
form: {
|
||||
// NOTE: Map server-side validators to comparative Angular form validators
|
||||
validatorMap: {
|
||||
required: 'required',
|
||||
regex: 'pattern'
|
||||
}
|
||||
},
|
||||
|
||||
// Notifications
|
||||
notifications: {
|
||||
rtl: false,
|
||||
position: ['top', 'right'],
|
||||
maxStack: 8,
|
||||
// NOTE: after how many seconds notification is closed automatically. If set to zero notifications are not closed automatically
|
||||
timeOut: 5000, // 5 second
|
||||
clickToClose: true,
|
||||
// NOTE: 'fade' | 'fromTop' | 'fromRight' | 'fromBottom' | 'fromLeft' | 'rotate' | 'scale'
|
||||
animate: NotificationAnimationsType.Scale
|
||||
},
|
||||
|
||||
// Submission settings
|
||||
submission: {
|
||||
autosave: {
|
||||
// NOTE: which metadata trigger an autosave
|
||||
metadata: [],
|
||||
/**
|
||||
* NOTE: after how many time (milliseconds) submission is saved automatically
|
||||
* eg. timer: 5 * (1000 * 60); // 5 minutes
|
||||
*/
|
||||
timer: 0
|
||||
},
|
||||
icons: {
|
||||
metadata: [
|
||||
/**
|
||||
* NOTE: example of configuration
|
||||
* {
|
||||
* // NOTE: metadata name
|
||||
* name: 'dc.author',
|
||||
* // NOTE: fontawesome (v5.x) icon classes and bootstrap utility classes can be used
|
||||
* style: 'fa-user'
|
||||
* }
|
||||
*/
|
||||
{
|
||||
name: 'dc.author',
|
||||
style: 'fas fa-user'
|
||||
},
|
||||
// default configuration
|
||||
{
|
||||
name: 'default',
|
||||
style: ''
|
||||
}
|
||||
],
|
||||
authority: {
|
||||
confidence: [
|
||||
/**
|
||||
* NOTE: example of configuration
|
||||
* {
|
||||
* // NOTE: confidence value
|
||||
* value: 'dc.author',
|
||||
* // NOTE: fontawesome (v4.x) icon classes and bootstrap utility classes can be used
|
||||
* style: 'fa-user'
|
||||
* }
|
||||
*/
|
||||
{
|
||||
value: 600,
|
||||
style: 'text-success'
|
||||
},
|
||||
{
|
||||
value: 500,
|
||||
style: 'text-info'
|
||||
},
|
||||
{
|
||||
value: 400,
|
||||
style: 'text-warning'
|
||||
},
|
||||
// default configuration
|
||||
{
|
||||
value: 'default',
|
||||
style: 'text-muted'
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// NOTE: will log all redux actions and transfers in console
|
||||
debug: false,
|
||||
|
||||
// Default Language in which the UI will be rendered if the user's browser language is not an active language
|
||||
defaultLanguage: 'en',
|
||||
|
||||
// Languages. DSpace Angular holds a message catalog for each of the following languages.
|
||||
// When set to active, users will be able to switch to the use of this language in the user interface.
|
||||
languages: [
|
||||
{ code: 'en', label: 'English', active: true },
|
||||
{ code: 'cs', label: 'Čeština', active: true },
|
||||
{ code: 'de', label: 'Deutsch', active: true },
|
||||
{ code: 'es', label: 'Español', active: true },
|
||||
{ code: 'fr', label: 'Français', active: true },
|
||||
{ code: 'lv', label: 'Latviešu', active: true },
|
||||
{ code: 'hu', label: 'Magyar', active: true },
|
||||
{ code: 'nl', label: 'Nederlands', active: true },
|
||||
{ code: 'pt-PT', label: 'Português', active: true },
|
||||
{ code: 'pt-BR', label: 'Português do Brasil', active: true },
|
||||
{ code: 'fi', label: 'Suomi', active: true }
|
||||
],
|
||||
|
||||
// Browse-By Pages
|
||||
browseBy: {
|
||||
// Amount of years to display using jumps of one year (current year - oneYearLimit)
|
||||
oneYearLimit: 10,
|
||||
// Limit for years to display using jumps of five years (current year - fiveYearLimit)
|
||||
fiveYearLimit: 30,
|
||||
// The absolute lowest year to display in the dropdown (only used when no lowest date can be found for all items)
|
||||
defaultLowerLimit: 1900,
|
||||
// List of all the active Browse-By types
|
||||
// Adding a type will activate their Browse-By page and add them to the global navigation menu,
|
||||
// as well as community and collection pages
|
||||
// Allowed fields and their purpose:
|
||||
// id: The browse id to use for fetching info from the rest api
|
||||
// type: The type of Browse-By page to display
|
||||
// metadataField: The metadata-field used to create starts-with options (only necessary when the type is set to 'date')
|
||||
types: [
|
||||
{
|
||||
id: 'title',
|
||||
type: BrowseByType.Title,
|
||||
},
|
||||
{
|
||||
id: 'dateissued',
|
||||
type: BrowseByType.Date,
|
||||
metadataField: 'dc.date.issued'
|
||||
},
|
||||
{
|
||||
id: 'author',
|
||||
type: BrowseByType.Metadata
|
||||
},
|
||||
{
|
||||
id: 'subject',
|
||||
type: BrowseByType.Metadata
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// Item Page Config
|
||||
item: {
|
||||
edit: {
|
||||
undoTimeout: 10000 // 10 seconds
|
||||
}
|
||||
},
|
||||
|
||||
// Collection Page Config
|
||||
collection: {
|
||||
edit: {
|
||||
undoTimeout: 10000 // 10 seconds
|
||||
}
|
||||
},
|
||||
|
||||
// Theme Config
|
||||
themes: [
|
||||
// Add additional themes here. In the case where multiple themes match a route, the first one
|
||||
// in this list will get priority. It is advisable to always have a theme that matches
|
||||
// every route as the last one
|
||||
|
||||
// {
|
||||
// // A theme with a handle property will match the community, collection or item with the given
|
||||
// // handle, and all collections and/or items within it
|
||||
// name: 'custom',
|
||||
// handle: '10673/1233'
|
||||
// },
|
||||
// {
|
||||
// // A theme with a regex property will match the route using a regular expression. If it
|
||||
// // matches the route for a community or collection it will also apply to all collections
|
||||
// // and/or items within it
|
||||
// name: 'custom',
|
||||
// regex: 'collections\/e8043bc2.*'
|
||||
// },
|
||||
// {
|
||||
// // A theme with a uuid property will match the community, collection or item with the given
|
||||
// // ID, and all collections and/or items within it
|
||||
// name: 'custom',
|
||||
// uuid: '0958c910-2037-42a9-81c7-dca80e3892b4'
|
||||
// },
|
||||
// {
|
||||
// // The extends property specifies an ancestor theme (by name). Whenever a themed component is not found
|
||||
// // in the current theme, its ancestor theme(s) will be checked recursively before falling back to default.
|
||||
// name: 'custom-A',
|
||||
// extends: 'custom-B',
|
||||
// // Any of the matching properties above can be used
|
||||
// handle: '10673/34'
|
||||
// },
|
||||
// {
|
||||
// name: 'custom-B',
|
||||
// extends: 'custom',
|
||||
// handle: '10673/12'
|
||||
// },
|
||||
// {
|
||||
// // A theme with only a name will match every route
|
||||
// name: 'custom'
|
||||
// },
|
||||
// {
|
||||
// // This theme will use the default bootstrap styling for DSpace components
|
||||
// name: BASE_THEME_NAME
|
||||
// },
|
||||
|
||||
{
|
||||
// The default dspace theme
|
||||
name: 'dspace'
|
||||
}
|
||||
],
|
||||
|
||||
// Whether to enable media viewer for image and/or video Bitstreams (i.e. Bitstreams whose MIME type starts with 'image' or 'video').
|
||||
// For images, this enables a gallery viewer where you can zoom or page through images.
|
||||
// For videos, this enables embedded video streaming
|
||||
mediaViewer: {
|
||||
image: false,
|
||||
video: false
|
||||
}
|
||||
};
|
||||
|
@@ -1,4 +1,4 @@
|
||||
// This configuration is only used for unit tests, end-to-end tests use environment.e2e.ts
|
||||
// This configuration is only used for unit tests, end-to-end tests use environment.prod.ts
|
||||
import { BrowseByType } from '../app/browse-by/browse-by-switcher/browse-by-decorator';
|
||||
import { RestRequestMethod } from '../app/core/data/rest-request-method';
|
||||
import { NotificationAnimationsType } from '../app/shared/notifications/models/notification-animations-type';
|
||||
|
@@ -1,15 +1,11 @@
|
||||
// This file can be replaced during build by using the `fileReplacements` array.
|
||||
// `ng build --configuration production` replaces `environment.ts` with `environment.prod.ts`.
|
||||
// `ng build --configuration ci` replaces `environment.ts` with `environment.ci.ts`.
|
||||
// `ng test --configuration test` replaces `environment.ts` with `environment.test.ts`.
|
||||
// The list of file replacements can be found in `angular.json`.
|
||||
|
||||
import { BrowseByType } from '../app/browse-by/browse-by-switcher/browse-by-decorator';
|
||||
import { RestRequestMethod } from '../app/core/data/rest-request-method';
|
||||
import { NotificationAnimationsType } from '../app/shared/notifications/models/notification-animations-type';
|
||||
import { AppConfig } from '../config/app-config.interface';
|
||||
|
||||
export const environment: AppConfig = {
|
||||
export const environment: Partial<AppConfig> = {
|
||||
production: false,
|
||||
|
||||
// Angular Universal settings
|
||||
@@ -17,285 +13,6 @@ export const environment: AppConfig = {
|
||||
preboot: true,
|
||||
async: true,
|
||||
time: false
|
||||
},
|
||||
|
||||
// Angular Universal server settings.
|
||||
// NOTE: these must be 'synced' with the 'dspace.ui.url' setting in your backend's local.cfg.
|
||||
ui: {
|
||||
ssl: false,
|
||||
host: 'localhost',
|
||||
port: 4000,
|
||||
// NOTE: Space is capitalized because 'namespace' is a reserved string in TypeScript
|
||||
nameSpace: '/',
|
||||
baseUrl: 'http://localhost:4000/',
|
||||
|
||||
// The rateLimiter settings limit each IP to a 'max' of 500 requests per 'windowMs' (1 minute).
|
||||
rateLimiter: {
|
||||
windowMs: 1 * 60 * 1000, // 1 minute
|
||||
max: 500 // limit each IP to 500 requests per windowMs
|
||||
}
|
||||
},
|
||||
|
||||
// The REST API server settings.
|
||||
// NOTE: these must be 'synced' with the 'dspace.server.url' setting in your backend's local.cfg.
|
||||
rest: {
|
||||
ssl: true,
|
||||
host: 'api7.dspace.org',
|
||||
port: 443,
|
||||
// NOTE: Space is capitalized because 'namespace' is a reserved string in TypeScript
|
||||
nameSpace: '/server',
|
||||
baseUrl: 'https://api7.dspace.org/server'
|
||||
},
|
||||
|
||||
// Caching settings
|
||||
cache: {
|
||||
// NOTE: how long should objects be cached for by default
|
||||
msToLive: {
|
||||
default: 15 * 60 * 1000 // 15 minutes
|
||||
},
|
||||
control: 'max-age=60', // revalidate browser
|
||||
autoSync: {
|
||||
defaultTime: 0,
|
||||
maxBufferSize: 100,
|
||||
timePerMethod: { [RestRequestMethod.PATCH]: 3 } as any // time in seconds
|
||||
}
|
||||
},
|
||||
|
||||
// Authentication settings
|
||||
auth: {
|
||||
// Authentication UI settings
|
||||
ui: {
|
||||
// the amount of time before the idle warning is shown
|
||||
timeUntilIdle: 15 * 60 * 1000, // 15 minutes
|
||||
// the amount of time the user has to react after the idle warning is shown before they are logged out.
|
||||
idleGracePeriod: 5 * 60 * 1000 // 5 minutes
|
||||
},
|
||||
// Authentication REST settings
|
||||
rest: {
|
||||
// If the rest token expires in less than this amount of time, it will be refreshed automatically.
|
||||
// This is independent from the idle warning.
|
||||
timeLeftBeforeTokenRefresh: 2 * 60 * 1000 // 2 minutes
|
||||
}
|
||||
},
|
||||
|
||||
// Form settings
|
||||
form: {
|
||||
// NOTE: Map server-side validators to comparative Angular form validators
|
||||
validatorMap: {
|
||||
required: 'required',
|
||||
regex: 'pattern'
|
||||
}
|
||||
},
|
||||
|
||||
// Notifications
|
||||
notifications: {
|
||||
rtl: false,
|
||||
position: ['top', 'right'],
|
||||
maxStack: 8,
|
||||
// NOTE: after how many seconds notification is closed automatically. If set to zero notifications are not closed automatically
|
||||
timeOut: 5000, // 5 second
|
||||
clickToClose: true,
|
||||
// NOTE: 'fade' | 'fromTop' | 'fromRight' | 'fromBottom' | 'fromLeft' | 'rotate' | 'scale'
|
||||
animate: NotificationAnimationsType.Scale
|
||||
},
|
||||
|
||||
// Submission settings
|
||||
submission: {
|
||||
autosave: {
|
||||
// NOTE: which metadata trigger an autosave
|
||||
metadata: [],
|
||||
/**
|
||||
* NOTE: after how many time (milliseconds) submission is saved automatically
|
||||
* eg. timer: 5 * (1000 * 60); // 5 minutes
|
||||
*/
|
||||
timer: 0
|
||||
},
|
||||
icons: {
|
||||
metadata: [
|
||||
/**
|
||||
* NOTE: example of configuration
|
||||
* {
|
||||
* // NOTE: metadata name
|
||||
* name: 'dc.author',
|
||||
* // NOTE: fontawesome (v5.x) icon classes and bootstrap utility classes can be used
|
||||
* style: 'fa-user'
|
||||
* }
|
||||
*/
|
||||
{
|
||||
name: 'dc.author',
|
||||
style: 'fas fa-user'
|
||||
},
|
||||
// default configuration
|
||||
{
|
||||
name: 'default',
|
||||
style: ''
|
||||
}
|
||||
],
|
||||
authority: {
|
||||
confidence: [
|
||||
/**
|
||||
* NOTE: example of configuration
|
||||
* {
|
||||
* // NOTE: confidence value
|
||||
* value: 'dc.author',
|
||||
* // NOTE: fontawesome (v4.x) icon classes and bootstrap utility classes can be used
|
||||
* style: 'fa-user'
|
||||
* }
|
||||
*/
|
||||
{
|
||||
value: 600,
|
||||
style: 'text-success'
|
||||
},
|
||||
{
|
||||
value: 500,
|
||||
style: 'text-info'
|
||||
},
|
||||
{
|
||||
value: 400,
|
||||
style: 'text-warning'
|
||||
},
|
||||
// default configuration
|
||||
{
|
||||
value: 'default',
|
||||
style: 'text-muted'
|
||||
}
|
||||
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
// NOTE: will log all redux actions and transfers in console
|
||||
debug: false,
|
||||
|
||||
// Default Language in which the UI will be rendered if the user's browser language is not an active language
|
||||
defaultLanguage: 'en',
|
||||
|
||||
// Languages. DSpace Angular holds a message catalog for each of the following languages.
|
||||
// When set to active, users will be able to switch to the use of this language in the user interface.
|
||||
languages: [
|
||||
{ code: 'en', label: 'English', active: true },
|
||||
{ code: 'cs', label: 'Čeština', active: true },
|
||||
{ code: 'de', label: 'Deutsch', active: true },
|
||||
{ code: 'es', label: 'Español', active: true },
|
||||
{ code: 'fr', label: 'Français', active: true },
|
||||
{ code: 'lv', label: 'Latviešu', active: true },
|
||||
{ code: 'hu', label: 'Magyar', active: true },
|
||||
{ code: 'nl', label: 'Nederlands', active: true },
|
||||
{ code: 'pt-PT', label: 'Português', active: true },
|
||||
{ code: 'pt-BR', label: 'Português do Brasil', active: true },
|
||||
{ code: 'fi', label: 'Suomi', active: true }
|
||||
],
|
||||
|
||||
// Browse-By Pages
|
||||
browseBy: {
|
||||
// Amount of years to display using jumps of one year (current year - oneYearLimit)
|
||||
oneYearLimit: 10,
|
||||
// Limit for years to display using jumps of five years (current year - fiveYearLimit)
|
||||
fiveYearLimit: 30,
|
||||
// The absolute lowest year to display in the dropdown (only used when no lowest date can be found for all items)
|
||||
defaultLowerLimit: 1900,
|
||||
// List of all the active Browse-By types
|
||||
// Adding a type will activate their Browse-By page and add them to the global navigation menu,
|
||||
// as well as community and collection pages
|
||||
// Allowed fields and their purpose:
|
||||
// id: The browse id to use for fetching info from the rest api
|
||||
// type: The type of Browse-By page to display
|
||||
// metadataField: The metadata-field used to create starts-with options (only necessary when the type is set to 'date')
|
||||
types: [
|
||||
{
|
||||
id: 'title',
|
||||
type: BrowseByType.Title,
|
||||
},
|
||||
{
|
||||
id: 'dateissued',
|
||||
type: BrowseByType.Date,
|
||||
metadataField: 'dc.date.issued'
|
||||
},
|
||||
{
|
||||
id: 'author',
|
||||
type: BrowseByType.Metadata
|
||||
},
|
||||
{
|
||||
id: 'subject',
|
||||
type: BrowseByType.Metadata
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// Item Page Config
|
||||
item: {
|
||||
edit: {
|
||||
undoTimeout: 10000 // 10 seconds
|
||||
}
|
||||
},
|
||||
|
||||
// Collection Page Config
|
||||
collection: {
|
||||
edit: {
|
||||
undoTimeout: 10000 // 10 seconds
|
||||
}
|
||||
},
|
||||
|
||||
// Theme Config
|
||||
themes: [
|
||||
// Add additional themes here. In the case where multiple themes match a route, the first one
|
||||
// in this list will get priority. It is advisable to always have a theme that matches
|
||||
// every route as the last one
|
||||
|
||||
// {
|
||||
// // A theme with a handle property will match the community, collection or item with the given
|
||||
// // handle, and all collections and/or items within it
|
||||
// name: 'custom',
|
||||
// handle: '10673/1233'
|
||||
// },
|
||||
// {
|
||||
// // A theme with a regex property will match the route using a regular expression. If it
|
||||
// // matches the route for a community or collection it will also apply to all collections
|
||||
// // and/or items within it
|
||||
// name: 'custom',
|
||||
// regex: 'collections\/e8043bc2.*'
|
||||
// },
|
||||
// {
|
||||
// // A theme with a uuid property will match the community, collection or item with the given
|
||||
// // ID, and all collections and/or items within it
|
||||
// name: 'custom',
|
||||
// uuid: '0958c910-2037-42a9-81c7-dca80e3892b4'
|
||||
// },
|
||||
// {
|
||||
// // The extends property specifies an ancestor theme (by name). Whenever a themed component is not found
|
||||
// // in the current theme, its ancestor theme(s) will be checked recursively before falling back to default.
|
||||
// name: 'custom-A',
|
||||
// extends: 'custom-B',
|
||||
// // Any of the matching properties above can be used
|
||||
// handle: '10673/34'
|
||||
// },
|
||||
// {
|
||||
// name: 'custom-B',
|
||||
// extends: 'custom',
|
||||
// handle: '10673/12'
|
||||
// },
|
||||
// {
|
||||
// // A theme with only a name will match every route
|
||||
// name: 'custom'
|
||||
// },
|
||||
// {
|
||||
// // This theme will use the default bootstrap styling for DSpace components
|
||||
// name: BASE_THEME_NAME
|
||||
// },
|
||||
|
||||
{
|
||||
// The default dspace theme
|
||||
name: 'dspace'
|
||||
}
|
||||
],
|
||||
|
||||
// Whether to enable media viewer for image and/or video Bitstreams (i.e. Bitstreams whose MIME type starts with 'image' or 'video').
|
||||
// For images, this enables a gallery viewer where you can zoom or page through images.
|
||||
// For videos, this enables embedded video streaming
|
||||
mediaViewer: {
|
||||
image: false,
|
||||
video: false
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -11,13 +11,13 @@ import { hasValue } from './app/shared/empty.util';
|
||||
import { BrowserAppModule } from './modules/app/browser-app.module';
|
||||
|
||||
import { environment } from './environments/environment';
|
||||
import { AppConfig } from './config/app-config.interface';
|
||||
import { extendEnvironmentWithAppConfig } from './config/config.util';
|
||||
|
||||
// import { AppConfig, APP_CONFIG } from './config/app-config.interface';
|
||||
// import { extendEnvironmentWithAppConfig } from './config/config.util';
|
||||
|
||||
if (environment.production) {
|
||||
enableProdMode();
|
||||
}
|
||||
const bootstrap = () => platformBrowserDynamic()
|
||||
.bootstrapModule(BrowserAppModule, {
|
||||
preserveWhitespaces: true
|
||||
});
|
||||
|
||||
const main = () => {
|
||||
// Load fonts async
|
||||
@@ -28,10 +28,22 @@ const main = () => {
|
||||
}
|
||||
});
|
||||
|
||||
return platformBrowserDynamic()
|
||||
.bootstrapModule(BrowserAppModule, {
|
||||
preserveWhitespaces: true
|
||||
});
|
||||
if (environment.production) {
|
||||
enableProdMode();
|
||||
|
||||
return bootstrap();
|
||||
} else {
|
||||
|
||||
return fetch('assets/appConfig.json')
|
||||
.then((response) => response.json())
|
||||
.then((appConfig: AppConfig) => {
|
||||
|
||||
// extend environment with app config for browser when not prerendered
|
||||
extendEnvironmentWithAppConfig(environment, appConfig);
|
||||
|
||||
return bootstrap();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// support async tag or hmr
|
||||
@@ -40,11 +52,3 @@ if (hasValue(environment.universal) && environment.universal.preboot === false)
|
||||
} else {
|
||||
document.addEventListener('DOMContentLoaded', main);
|
||||
}
|
||||
|
||||
|
||||
// fetch('assets/appConfig.json')
|
||||
// .then((response) => response.json())
|
||||
// .then((appConfig: AppConfig) => {
|
||||
// // extend environment with app config for client side use
|
||||
// extendEnvironmentWithAppConfig(environment, appConfig);
|
||||
// });
|
||||
|
@@ -1,7 +1,8 @@
|
||||
import { HttpClient, HttpClientModule } from '@angular/common/http';
|
||||
import { NgModule } from '@angular/core';
|
||||
import { APP_INITIALIZER, NgModule } from '@angular/core';
|
||||
import { BrowserModule, makeStateKey, TransferState } from '@angular/platform-browser';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { RouterModule, NoPreloading } from '@angular/router';
|
||||
import { REQUEST } from '@nguniversal/express-engine/tokens';
|
||||
|
||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
@@ -30,9 +31,13 @@ import {
|
||||
} from '../../app/core/services/browser-hard-redirect.service';
|
||||
import { LocaleService } from '../../app/core/locale/locale.service';
|
||||
import { GoogleAnalyticsService } from '../../app/statistics/google-analytics.service';
|
||||
import { RouterModule, NoPreloading } from '@angular/router';
|
||||
import { AuthRequestService } from '../../app/core/auth/auth-request.service';
|
||||
import { BrowserAuthRequestService } from '../../app/core/auth/browser-auth-request.service';
|
||||
import { AppConfig, APP_CONFIG_STATE } from '../../config/app-config.interface';
|
||||
import { DefaultAppConfig } from '../../config/default-app-config';
|
||||
import { extendEnvironmentWithAppConfig } from '../../config/config.util';
|
||||
|
||||
import { environment } from '../../environments/environment';
|
||||
|
||||
export const REQ_KEY = makeStateKey<string>('req');
|
||||
|
||||
@@ -54,12 +59,12 @@ export function getRequest(transferState: TransferState): any {
|
||||
// forRoot ensures the providers are only created once
|
||||
IdlePreloadModule.forRoot(),
|
||||
RouterModule.forRoot([], {
|
||||
// enableTracing: true,
|
||||
useHash: false,
|
||||
scrollPositionRestoration: 'enabled',
|
||||
anchorScrolling: 'enabled',
|
||||
preloadingStrategy: NoPreloading
|
||||
}),
|
||||
// enableTracing: true,
|
||||
useHash: false,
|
||||
scrollPositionRestoration: 'enabled',
|
||||
anchorScrolling: 'enabled',
|
||||
preloadingStrategy: NoPreloading
|
||||
}),
|
||||
StatisticsModule.forRoot(),
|
||||
Angulartics2RouterlessModule.forRoot(),
|
||||
BrowserAnimationsModule,
|
||||
@@ -74,6 +79,20 @@ export function getRequest(transferState: TransferState): any {
|
||||
AppModule
|
||||
],
|
||||
providers: [
|
||||
{
|
||||
provide: APP_INITIALIZER,
|
||||
useFactory: (transferState: TransferState) => {
|
||||
if (transferState.hasKey<AppConfig>(APP_CONFIG_STATE)) {
|
||||
const appConfig = transferState.get<AppConfig>(APP_CONFIG_STATE, new DefaultAppConfig());
|
||||
// extend environment with app config for browser
|
||||
extendEnvironmentWithAppConfig(environment, appConfig);
|
||||
}
|
||||
|
||||
return () => true;
|
||||
},
|
||||
deps: [TransferState],
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: REQUEST,
|
||||
useFactory: getRequest,
|
||||
|
@@ -1,38 +1,40 @@
|
||||
import { NgModule } from '@angular/core';
|
||||
import { BrowserModule } from '@angular/platform-browser';
|
||||
import { HTTP_INTERCEPTORS } from '@angular/common/http';
|
||||
import { APP_INITIALIZER, NgModule } from '@angular/core';
|
||||
import { BrowserModule, TransferState } from '@angular/platform-browser';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { ServerModule } from '@angular/platform-server';
|
||||
import { RouterModule } from '@angular/router';
|
||||
|
||||
import { TranslateLoader, TranslateModule } from '@ngx-translate/core';
|
||||
|
||||
import { Angulartics2 } from 'angulartics2';
|
||||
import { Angulartics2GoogleAnalytics } from 'angulartics2/ga';
|
||||
|
||||
import { AppComponent } from '../../app/app.component';
|
||||
|
||||
import { AppModule } from '../../app/app.module';
|
||||
import { DSpaceServerTransferStateModule } from '../transfer-state/dspace-server-transfer-state.module';
|
||||
import { DSpaceTransferState } from '../transfer-state/dspace-transfer-state.service';
|
||||
|
||||
import { TranslateJson5UniversalLoader } from '../../ngx-translate-loaders/translate-json5-universal.loader';
|
||||
import { CookieService } from '../../app/core/services/cookie.service';
|
||||
import { ServerCookieService } from '../../app/core/services/server-cookie.service';
|
||||
import { AuthService } from '../../app/core/auth/auth.service';
|
||||
import { ServerAuthService } from '../../app/core/auth/server-auth.service';
|
||||
|
||||
import { Angulartics2GoogleAnalytics } from 'angulartics2/ga';
|
||||
import { AngularticsProviderMock } from '../../app/shared/mocks/angulartics-provider.service.mock';
|
||||
import { SubmissionService } from '../../app/submission/submission.service';
|
||||
import { ServerSubmissionService } from '../../app/submission/server-submission.service';
|
||||
import { Angulartics2DSpace } from '../../app/statistics/angulartics/dspace-provider';
|
||||
import { ServerLocaleService } from '../../app/core/locale/server-locale.service';
|
||||
import { LocaleService } from '../../app/core/locale/locale.service';
|
||||
import { HTTP_INTERCEPTORS } from '@angular/common/http';
|
||||
import { ForwardClientIpInterceptor } from '../../app/core/forward-client-ip/forward-client-ip.interceptor';
|
||||
import { HardRedirectService } from '../../app/core/services/hard-redirect.service';
|
||||
import { ServerHardRedirectService } from '../../app/core/services/server-hard-redirect.service';
|
||||
import { Angulartics2 } from 'angulartics2';
|
||||
import { Angulartics2Mock } from '../../app/shared/mocks/angulartics2.service.mock';
|
||||
import { RouterModule } from '@angular/router';
|
||||
import { AuthRequestService } from '../../app/core/auth/auth-request.service';
|
||||
import { ServerAuthRequestService } from '../../app/core/auth/server-auth-request.service';
|
||||
import { AppConfig, APP_CONFIG_STATE } from '../../config/app-config.interface';
|
||||
|
||||
import { environment } from '../../environments/environment';
|
||||
|
||||
export function createTranslateLoader() {
|
||||
return new TranslateJson5UniversalLoader('dist/server/assets/i18n/', '.json5');
|
||||
@@ -60,6 +62,16 @@ export function createTranslateLoader() {
|
||||
AppModule
|
||||
],
|
||||
providers: [
|
||||
// Initialize app config and extend environment
|
||||
{
|
||||
provide: APP_INITIALIZER,
|
||||
useFactory: (transferState: TransferState) => {
|
||||
transferState.set<AppConfig>(APP_CONFIG_STATE, environment as AppConfig);
|
||||
return () => true;
|
||||
},
|
||||
deps: [TransferState],
|
||||
multi: true
|
||||
},
|
||||
{
|
||||
provide: Angulartics2,
|
||||
useClass: Angulartics2Mock
|
||||
|
@@ -170,9 +170,5 @@
|
||||
"use-life-cycle-interface": false,
|
||||
"no-outputs-metadata-property": true,
|
||||
"use-pipe-transform-interface": true
|
||||
// "rxjs-collapse-imports": true,
|
||||
// "rxjs-pipeable-operators-only": true,
|
||||
// "rxjs-no-static-observable-methods": true,
|
||||
// "rxjs-proper-imports": true
|
||||
}
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
// import { join } from 'path';
|
||||
import { join } from 'path';
|
||||
|
||||
// import { buildAppConfig } from '../src/config/config.server';
|
||||
import { buildAppConfig } from '../src/config/config.server';
|
||||
import { commonExports } from './webpack.common';
|
||||
|
||||
module.exports = Object.assign({}, commonExports, {
|
||||
@@ -10,7 +10,7 @@ module.exports = Object.assign({}, commonExports, {
|
||||
},
|
||||
devServer: {
|
||||
before(app, server) {
|
||||
// buildAppConfig(join(process.cwd(), 'src/assets/appConfig.json'));
|
||||
buildAppConfig(join(process.cwd(), 'src/assets/appConfig.json'));
|
||||
}
|
||||
}
|
||||
});
|
||||
|
Reference in New Issue
Block a user