mirror of
https://github.com/DSpace/dspace-angular.git
synced 2025-10-07 01:54:15 +00:00
[DURACOM-234] Switch to standalone bootstrapping API
This commit is contained in:
34
server.ts
34
server.ts
@@ -48,7 +48,7 @@ import { hasNoValue, hasValue } from './src/app/shared/empty.util';
|
||||
|
||||
import { UIServerConfig } from './src/config/ui-server-config.interface';
|
||||
|
||||
import { ServerAppModule } from './src/main.server';
|
||||
import bootstrap from './src/main.server';
|
||||
|
||||
import { buildAppConfig } from './src/config/config.server';
|
||||
import { APP_CONFIG, AppConfig } from './src/config/app-config.interface';
|
||||
@@ -130,7 +130,7 @@ export function app() {
|
||||
// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
|
||||
server.engine('html', (_, options, callback) =>
|
||||
ngExpressEngine({
|
||||
bootstrap: ServerAppModule,
|
||||
bootstrap,
|
||||
providers: [
|
||||
{
|
||||
provide: REQUEST,
|
||||
@@ -142,10 +142,10 @@ export function app() {
|
||||
},
|
||||
{
|
||||
provide: APP_CONFIG,
|
||||
useValue: environment
|
||||
}
|
||||
]
|
||||
})(_, (options as any), callback)
|
||||
useValue: environment,
|
||||
},
|
||||
],
|
||||
})(_, (options as any), callback),
|
||||
);
|
||||
|
||||
server.engine('ejs', ejs.renderFile);
|
||||
@@ -162,7 +162,7 @@ export function app() {
|
||||
server.get('/robots.txt', (req, res) => {
|
||||
res.setHeader('content-type', 'text/plain');
|
||||
res.render('assets/robots.txt.ejs', {
|
||||
'origin': req.protocol + '://' + req.headers.host
|
||||
'origin': req.protocol + '://' + req.headers.host,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -177,7 +177,7 @@ export function app() {
|
||||
router.use('/sitemap**', createProxyMiddleware({
|
||||
target: `${environment.rest.baseUrl}/sitemaps`,
|
||||
pathRewrite: path => path.replace(environment.ui.nameSpace, '/'),
|
||||
changeOrigin: true
|
||||
changeOrigin: true,
|
||||
}));
|
||||
|
||||
/**
|
||||
@@ -186,7 +186,7 @@ export function app() {
|
||||
router.use('/signposting**', createProxyMiddleware({
|
||||
target: `${environment.rest.baseUrl}`,
|
||||
pathRewrite: path => path.replace(environment.ui.nameSpace, '/'),
|
||||
changeOrigin: true
|
||||
changeOrigin: true,
|
||||
}));
|
||||
|
||||
/**
|
||||
@@ -197,7 +197,7 @@ export function app() {
|
||||
const RateLimit = require('express-rate-limit');
|
||||
const limiter = new RateLimit({
|
||||
windowMs: (environment.ui as UIServerConfig).rateLimiter.windowMs,
|
||||
max: (environment.ui as UIServerConfig).rateLimiter.max
|
||||
max: (environment.ui as UIServerConfig).rateLimiter.max,
|
||||
});
|
||||
server.use(limiter);
|
||||
}
|
||||
@@ -325,7 +325,7 @@ function initCache() {
|
||||
botCache = new LRU( {
|
||||
max: environment.cache.serverSide.botCache.max,
|
||||
ttl: environment.cache.serverSide.botCache.timeToLive,
|
||||
allowStale: environment.cache.serverSide.botCache.allowStale
|
||||
allowStale: environment.cache.serverSide.botCache.allowStale,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -337,7 +337,7 @@ function initCache() {
|
||||
anonymousCache = new LRU( {
|
||||
max: environment.cache.serverSide.anonymousCache.max,
|
||||
ttl: environment.cache.serverSide.anonymousCache.timeToLive,
|
||||
allowStale: environment.cache.serverSide.anonymousCache.allowStale
|
||||
allowStale: environment.cache.serverSide.anonymousCache.allowStale,
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -415,7 +415,7 @@ function checkCacheForRequest(cacheName: string, cache: LRU<string, any>, req, r
|
||||
const key = getCacheKey(req);
|
||||
|
||||
// Check if this page is in our cache
|
||||
let cachedCopy = cache.get(key);
|
||||
const cachedCopy = cache.get(key);
|
||||
if (cachedCopy) {
|
||||
if (environment.cache.serverSide.debug) { console.log(`CACHE HIT FOR ${key} in ${cacheName} cache`); }
|
||||
|
||||
@@ -529,7 +529,7 @@ function serverStarted() {
|
||||
function createHttpsServer(keys) {
|
||||
const listener = createServer({
|
||||
key: keys.serviceKey,
|
||||
cert: keys.certificate
|
||||
cert: keys.certificate,
|
||||
}, app).listen(environment.ui.port, environment.ui.host, () => {
|
||||
serverStarted();
|
||||
});
|
||||
@@ -597,7 +597,7 @@ function start() {
|
||||
if (serviceKey && certificate) {
|
||||
createHttpsServer({
|
||||
serviceKey: serviceKey,
|
||||
certificate: certificate
|
||||
certificate: certificate,
|
||||
});
|
||||
} else {
|
||||
console.warn('Disabling certificate validation and proceeding with a self-signed certificate. If this is a production server, it is recommended that you configure a valid certificate instead.');
|
||||
@@ -606,7 +606,7 @@ function start() {
|
||||
|
||||
createCertificate({
|
||||
days: 1,
|
||||
selfSigned: true
|
||||
selfSigned: true,
|
||||
}, (error, keys) => {
|
||||
createHttpsServer(keys);
|
||||
});
|
||||
@@ -627,7 +627,7 @@ function healthCheck(req, res) {
|
||||
})
|
||||
.catch((error) => {
|
||||
res.status(error.response.status).send({
|
||||
error: error.message
|
||||
error: error.message,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@@ -35,6 +35,7 @@ import {
|
||||
NativeWindowRef,
|
||||
NativeWindowService,
|
||||
} from './core/services/window.service';
|
||||
import { ThemedRootComponent } from './root/themed-root.component';
|
||||
import { HostWindowResizeAction } from './shared/host-window.actions';
|
||||
import { HostWindowService } from './shared/host-window.service';
|
||||
import { MenuService } from './shared/menu/menu.service';
|
||||
@@ -84,7 +85,6 @@ describe('App component', () => {
|
||||
},
|
||||
}),
|
||||
],
|
||||
declarations: [AppComponent], // declare the test component
|
||||
providers: [
|
||||
{ provide: NativeWindowService, useValue: new NativeWindowRef() },
|
||||
{ provide: MetadataService, useValue: new MetadataServiceMock() },
|
||||
@@ -109,7 +109,13 @@ describe('App component', () => {
|
||||
|
||||
// waitForAsync beforeEach
|
||||
beforeEach(waitForAsync(() => {
|
||||
return TestBed.configureTestingModule(getDefaultTestBedConf());
|
||||
return TestBed.configureTestingModule(getDefaultTestBedConf()).overrideComponent(
|
||||
AppComponent, {
|
||||
remove: {
|
||||
imports: [ ThemedRootComponent ],
|
||||
},
|
||||
},
|
||||
);
|
||||
}));
|
||||
|
||||
// synchronous beforeEach
|
||||
|
@@ -1,4 +1,5 @@
|
||||
import {
|
||||
AsyncPipe,
|
||||
DOCUMENT,
|
||||
isPlatformBrowser,
|
||||
} from '@angular/common';
|
||||
@@ -44,6 +45,7 @@ import {
|
||||
NativeWindowService,
|
||||
} from './core/services/window.service';
|
||||
import { distinctNext } from './core/shared/distinct-next';
|
||||
import { ThemedRootComponent } from './root/themed-root.component';
|
||||
import { HostWindowResizeAction } from './shared/host-window.actions';
|
||||
import { IdleModalComponent } from './shared/idle-modal/idle-modal.component';
|
||||
import { CSSVariableService } from './shared/sass-helper/css-variable.service';
|
||||
@@ -55,6 +57,11 @@ import { ThemeService } from './shared/theme-support/theme.service';
|
||||
templateUrl: './app.component.html',
|
||||
styleUrls: ['./app.component.scss'],
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
standalone: true,
|
||||
imports: [
|
||||
ThemedRootComponent,
|
||||
AsyncPipe,
|
||||
],
|
||||
})
|
||||
export class AppComponent implements OnInit, AfterViewInit {
|
||||
notificationOptions;
|
||||
|
@@ -1,15 +1,11 @@
|
||||
import {
|
||||
APP_BASE_HREF,
|
||||
CommonModule,
|
||||
DOCUMENT,
|
||||
} from '@angular/common';
|
||||
import { HTTP_INTERCEPTORS } from '@angular/common/http';
|
||||
import {
|
||||
HTTP_INTERCEPTORS,
|
||||
HttpClientModule,
|
||||
} from '@angular/common/http';
|
||||
import {
|
||||
APP_ID,
|
||||
NgModule,
|
||||
ApplicationConfig,
|
||||
importProvidersFrom,
|
||||
} from '@angular/core';
|
||||
import {
|
||||
NoPreloading,
|
||||
@@ -31,7 +27,6 @@ import {
|
||||
StoreModule,
|
||||
USER_PROVIDED_META_REDUCERS,
|
||||
} from '@ngrx/store';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { ScrollToModule } from '@nicky-lenaers/ngx-scroll-to';
|
||||
import { NgxMaskModule } from 'ngx-mask';
|
||||
|
||||
@@ -42,7 +37,6 @@ import {
|
||||
import { StoreDevModules } from '../config/store/devtools';
|
||||
import { environment } from '../environments/environment';
|
||||
import { EagerThemesModule } from '../themes/eager-themes.module';
|
||||
import { AppComponent } from './app.component';
|
||||
import { appEffects } from './app.effects';
|
||||
import {
|
||||
appMetaReducers,
|
||||
@@ -70,7 +64,6 @@ import { ClientCookieService } from './core/services/client-cookie.service';
|
||||
import { ListableModule } from './core/shared/listable.module';
|
||||
import { XsrfInterceptor } from './core/xsrf/xsrf.interceptor';
|
||||
import { RootModule } from './root.module';
|
||||
import { ThemedRootComponent } from './root/themed-root.component';
|
||||
import { AUTH_METHOD_FOR_DECORATOR_MAP } from './shared/log-in/methods/log-in.methods-decorator';
|
||||
import { METADATA_REPRESENTATION_COMPONENT_DECORATOR_MAP } from './shared/metadata-representation/metadata-representation.decorator';
|
||||
import {
|
||||
@@ -94,12 +87,12 @@ export function getMetaReducers(appConfig: AppConfig): MetaReducer<AppState>[] {
|
||||
return appConfig.debug ? [...appMetaReducers, ...debugMetaReducers] : appMetaReducers;
|
||||
}
|
||||
|
||||
const IMPORTS = [
|
||||
CommonModule,
|
||||
HttpClientModule,
|
||||
export const commonAppConfig: ApplicationConfig = {
|
||||
providers: [
|
||||
importProvidersFrom(
|
||||
ScrollToModule.forRoot(),
|
||||
NgbModule,
|
||||
TranslateModule.forRoot(),
|
||||
// TranslateModule.forRoot(),
|
||||
EffectsModule.forRoot(appEffects),
|
||||
StoreModule.forRoot(appReducers, storeModuleConfig),
|
||||
StoreRouterConnectingModule.forRoot(),
|
||||
@@ -107,9 +100,8 @@ const IMPORTS = [
|
||||
EagerThemesModule,
|
||||
RootModule,
|
||||
ListableModule.withEntryComponents(),
|
||||
];
|
||||
|
||||
const PROVIDERS = [
|
||||
NgxMaskModule.forRoot(),
|
||||
),
|
||||
provideRouter(
|
||||
APP_ROUTES,
|
||||
withRouterConfig(APP_ROUTING_CONF),
|
||||
@@ -158,33 +150,16 @@ const PROVIDERS = [
|
||||
},
|
||||
// register the dynamic matcher used by form. MUST be provided by the app module
|
||||
...DYNAMIC_MATCHER_PROVIDERS,
|
||||
];
|
||||
|
||||
|
||||
@NgModule({
|
||||
declarations: [
|
||||
AppComponent,
|
||||
],
|
||||
imports: [
|
||||
...IMPORTS,
|
||||
NgxMaskModule.forRoot(),
|
||||
ThemedRootComponent,
|
||||
],
|
||||
providers: [
|
||||
...PROVIDERS,
|
||||
{ provide: APP_ID, useValue: 'dspace-angular' },
|
||||
provideCore(),
|
||||
],
|
||||
bootstrap: [AppComponent],
|
||||
})
|
||||
export class AppModule {
|
||||
};
|
||||
|
||||
|
||||
/* Use models object so all decorators are actually called */
|
||||
modelList = models;
|
||||
workflowTasks = WORKFLOW_TASK_OPTION_DECORATOR_MAP;
|
||||
advancedWorfklowTasks = ADVANCED_WORKFLOW_TASK_OPTION_DECORATOR_MAP;
|
||||
metadataRepresentations = METADATA_REPRESENTATION_COMPONENT_DECORATOR_MAP;
|
||||
startsWithDecoratorMap = STARTS_WITH_DECORATOR_MAP;
|
||||
browseByDecoratorMap = BROWSE_BY_DECORATOR_MAP;
|
||||
authMethodForDecoratorMap = AUTH_METHOD_FOR_DECORATOR_MAP;
|
||||
}
|
||||
const modelList = models;
|
||||
const workflowTasks = WORKFLOW_TASK_OPTION_DECORATOR_MAP;
|
||||
const advancedWorfklowTasks = ADVANCED_WORKFLOW_TASK_OPTION_DECORATOR_MAP;
|
||||
const metadataRepresentations = METADATA_REPRESENTATION_COMPONENT_DECORATOR_MAP;
|
||||
const startsWithDecoratorMap = STARTS_WITH_DECORATOR_MAP;
|
||||
const browseByDecoratorMap = BROWSE_BY_DECORATOR_MAP;
|
||||
const authMethodForDecoratorMap = AUTH_METHOD_FOR_DECORATOR_MAP;
|
@@ -3,15 +3,17 @@ import 'reflect-metadata';
|
||||
import 'core-js/es/reflect';
|
||||
|
||||
import { enableProdMode } from '@angular/core';
|
||||
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
|
||||
import { bootstrapApplication } from '@angular/platform-browser';
|
||||
|
||||
import { AppComponent } from './app/app.component';
|
||||
import { AppConfig } from './config/app-config.interface';
|
||||
import { extendEnvironmentWithAppConfig } from './config/config.util';
|
||||
import { environment } from './environments/environment';
|
||||
import { BrowserAppModule } from './modules/app/browser-app.module';
|
||||
import { browserAppConfig } from './modules/app/browser-app.config';
|
||||
|
||||
const bootstrap = () => platformBrowserDynamic()
|
||||
.bootstrapModule(BrowserAppModule, {});
|
||||
/*const bootstrap = () => platformBrowserDynamic()
|
||||
.bootstrapModule(BrowserAppModule, {});*/
|
||||
const bootstrap = () => bootstrapApplication(AppComponent, browserAppConfig);
|
||||
|
||||
/**
|
||||
* We use this to determine have been serven SSR HTML or not.
|
||||
@@ -33,9 +35,9 @@ const main = () => {
|
||||
// Configuration must be fetched explicitly
|
||||
return fetch('assets/config.json')
|
||||
.then((response) => response.json())
|
||||
.then((appConfig: AppConfig) => {
|
||||
.then((config: AppConfig) => {
|
||||
// extend environment with app config for browser when not prerendered
|
||||
extendEnvironmentWithAppConfig(environment, appConfig);
|
||||
extendEnvironmentWithAppConfig(environment, config);
|
||||
return bootstrap();
|
||||
});
|
||||
}
|
||||
|
@@ -7,14 +7,13 @@ import 'reflect-metadata';
|
||||
*/
|
||||
import '@angular/localize/init';
|
||||
|
||||
import { enableProdMode } from '@angular/core';
|
||||
import { bootstrapApplication } from '@angular/platform-browser';
|
||||
|
||||
import { environment } from './environments/environment';
|
||||
import { AppComponent } from './app/app.component';
|
||||
import { serverAppConfig } from './modules/app/server-app.config';
|
||||
|
||||
if (environment.production) {
|
||||
enableProdMode();
|
||||
}
|
||||
const bootstrap = () => bootstrapApplication(AppComponent, serverAppConfig);
|
||||
|
||||
export { ServerAppModule } from './modules/app/server-app.module';
|
||||
export { renderModule } from '@angular/platform-server';
|
||||
export { ngExpressEngine } from '@nguniversal/express-engine';
|
||||
export default bootstrap;
|
||||
|
@@ -1,14 +1,18 @@
|
||||
import {
|
||||
HttpClient,
|
||||
HttpClientModule,
|
||||
provideHttpClient,
|
||||
withInterceptorsFromDi,
|
||||
} from '@angular/common/http';
|
||||
import {
|
||||
APP_ID,
|
||||
ApplicationConfig,
|
||||
importProvidersFrom,
|
||||
makeStateKey,
|
||||
NgModule,
|
||||
mergeApplicationConfig,
|
||||
TransferState,
|
||||
} from '@angular/core';
|
||||
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { provideClientHydration } from '@angular/platform-browser';
|
||||
import { provideAnimations } from '@angular/platform-browser/animations';
|
||||
import { EffectsModule } from '@ngrx/effects';
|
||||
import {
|
||||
Action,
|
||||
@@ -26,8 +30,7 @@ import {
|
||||
Angulartics2RouterlessModule,
|
||||
} from 'angulartics2';
|
||||
|
||||
import { AppComponent } from '../../app/app.component';
|
||||
import { AppModule } from '../../app/app.module';
|
||||
import { commonAppConfig } from '../../app/app.config';
|
||||
import { storeModuleConfig } from '../../app/app.reducer';
|
||||
import { AuthService } from '../../app/core/auth/auth.service';
|
||||
import { AuthRequestService } from '../../app/core/auth/auth-request.service';
|
||||
@@ -66,13 +69,14 @@ export function getRequest(transferState: TransferState): any {
|
||||
return transferState.get<any>(REQ_KEY, {});
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
bootstrap: [AppComponent],
|
||||
imports: [
|
||||
HttpClientModule,
|
||||
export const browserAppConfig: ApplicationConfig = mergeApplicationConfig({
|
||||
providers: [
|
||||
provideHttpClient(withInterceptorsFromDi()),
|
||||
provideAnimations(),
|
||||
provideClientHydration(),
|
||||
importProvidersFrom(
|
||||
// forRoot ensures the providers are only created once
|
||||
Angulartics2RouterlessModule.forRoot(),
|
||||
BrowserAnimationsModule,
|
||||
StoreModule.forFeature('core', coreReducers, storeModuleConfig as StoreConfig<CoreState, Action>),
|
||||
EffectsModule.forFeature(coreEffects),
|
||||
TranslateModule.forRoot({
|
||||
@@ -84,9 +88,7 @@ export function getRequest(transferState: TransferState): any {
|
||||
missingTranslationHandler: { provide: MissingTranslationHandler, useClass: MissingTranslationHelper },
|
||||
useDefaultLang: true,
|
||||
}),
|
||||
AppModule,
|
||||
],
|
||||
providers: [
|
||||
),
|
||||
...BrowserInitService.providers(),
|
||||
{ provide: APP_ID, useValue: 'dspace-angular' },
|
||||
{
|
||||
@@ -143,6 +145,4 @@ export function getRequest(transferState: TransferState): any {
|
||||
useClass: ClientMathService,
|
||||
},
|
||||
],
|
||||
})
|
||||
export class BrowserAppModule {
|
||||
}
|
||||
}, commonAppConfig);
|
@@ -1,12 +1,18 @@
|
||||
import { XhrFactory } from '@angular/common';
|
||||
import { HTTP_INTERCEPTORS } from '@angular/common/http';
|
||||
import {
|
||||
HTTP_INTERCEPTORS,
|
||||
provideHttpClient,
|
||||
withInterceptorsFromDi,
|
||||
} from '@angular/common/http';
|
||||
import {
|
||||
APP_ID,
|
||||
NgModule,
|
||||
ApplicationConfig,
|
||||
importProvidersFrom,
|
||||
mergeApplicationConfig,
|
||||
TransferState,
|
||||
} from '@angular/core';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { ServerModule } from '@angular/platform-server';
|
||||
import { provideAnimations } from '@angular/platform-browser/animations';
|
||||
import { provideServerRendering } from '@angular/platform-server';
|
||||
import { EffectsModule } from '@ngrx/effects';
|
||||
import {
|
||||
Action,
|
||||
@@ -23,8 +29,7 @@ import {
|
||||
Angulartics2GoogleGlobalSiteTag,
|
||||
} from 'angulartics2';
|
||||
|
||||
import { AppComponent } from '../../app/app.component';
|
||||
import { AppModule } from '../../app/app.module';
|
||||
import { commonAppConfig } from '../../app/app.config';
|
||||
import { storeModuleConfig } from '../../app/app.reducer';
|
||||
import { AuthService } from '../../app/core/auth/auth.service';
|
||||
import { AuthRequestService } from '../../app/core/auth/auth-request.service';
|
||||
@@ -57,10 +62,12 @@ export function createTranslateLoader(transferState: TransferState) {
|
||||
return new TranslateServerLoader(transferState, 'dist/server/assets/i18n/', '.json');
|
||||
}
|
||||
|
||||
@NgModule({
|
||||
bootstrap: [AppComponent],
|
||||
imports: [
|
||||
NoopAnimationsModule,
|
||||
export const serverAppConfig: ApplicationConfig = mergeApplicationConfig({
|
||||
providers: [
|
||||
provideHttpClient(withInterceptorsFromDi()),
|
||||
provideAnimations(),
|
||||
provideServerRendering(),
|
||||
importProvidersFrom(
|
||||
StoreModule.forFeature('core', coreReducers, storeModuleConfig as StoreConfig<CoreState, Action>),
|
||||
EffectsModule.forFeature(coreEffects),
|
||||
TranslateModule.forRoot({
|
||||
@@ -70,10 +77,7 @@ export function createTranslateLoader(transferState: TransferState) {
|
||||
deps: [TransferState],
|
||||
},
|
||||
}),
|
||||
AppModule,
|
||||
ServerModule,
|
||||
],
|
||||
providers: [
|
||||
),
|
||||
...ServerInitService.providers(),
|
||||
{ provide: APP_ID, useValue: 'dspace-angular' },
|
||||
{
|
||||
@@ -135,6 +139,4 @@ export function createTranslateLoader(transferState: TransferState) {
|
||||
useClass: ServerMathService,
|
||||
},
|
||||
],
|
||||
})
|
||||
export class ServerAppModule {
|
||||
}
|
||||
}, commonAppConfig);
|
@@ -11,7 +11,6 @@ import { StoreModule } from '@ngrx/store';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { ScrollToModule } from '@nicky-lenaers/ngx-scroll-to';
|
||||
|
||||
import { AppModule } from '../../app/app.module';
|
||||
import { RootModule } from '../../app/root.module';
|
||||
import { AdminSidebarComponent } from './app/admin/admin-sidebar/admin-sidebar.component';
|
||||
import { EditBitstreamPageComponent } from './app/bitstream-page/edit-bitstream-page/edit-bitstream-page.component';
|
||||
@@ -185,7 +184,6 @@ const DECLARATIONS = [
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
AppModule,
|
||||
RootModule,
|
||||
CommonModule,
|
||||
DragDropModule,
|
||||
|
@@ -10,7 +10,6 @@ import { StoreModule } from '@ngrx/store';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { ScrollToModule } from '@nicky-lenaers/ngx-scroll-to';
|
||||
|
||||
import { AppModule } from '../../app/app.module';
|
||||
import { RootModule } from '../../app/root.module';
|
||||
|
||||
const DECLARATIONS = [
|
||||
@@ -18,7 +17,6 @@ const DECLARATIONS = [
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
AppModule,
|
||||
RootModule,
|
||||
CommonModule,
|
||||
DragDropModule,
|
||||
|
Reference in New Issue
Block a user