diff --git a/src/Squidex/app-config/webpack.common.js b/src/Squidex/app-config/webpack.common.js index 8058ae0ae..a6bc9feb9 100644 --- a/src/Squidex/app-config/webpack.common.js +++ b/src/Squidex/app-config/webpack.common.js @@ -37,9 +37,9 @@ module.exports = { helpers.root('app-libs') ], moduleDirectories: [ - "*", - "app/*", - "app/theme/*" + '*', + 'app/*', + 'app/theme/*' ] }, @@ -82,9 +82,11 @@ module.exports = { } ] }, + sassLoader: { includePaths: [helpers.root('app', 'theme')] }, + plugins: [ /** * Plugin: CommonsChunkPlugin diff --git a/src/Squidex/app-config/webpack.dev.js b/src/Squidex/app-config/webpack.dev.js index a856cd797..2086dc189 100644 --- a/src/Squidex/app-config/webpack.dev.js +++ b/src/Squidex/app-config/webpack.dev.js @@ -48,6 +48,10 @@ module.exports = webpackMerge(commonConfig, { new ExtractTextPlugin('[name].css') ], + sassLoader: { + includePaths: [helpers.root('app', 'theme')] + }, + tslint: { /** * Run tslint in production build, but do not fail if there is a warning. diff --git a/src/Squidex/app-config/webpack.prod.js b/src/Squidex/app-config/webpack.prod.js index 88cb7a539..316a01748 100644 --- a/src/Squidex/app-config/webpack.prod.js +++ b/src/Squidex/app-config/webpack.prod.js @@ -44,7 +44,7 @@ module.exports = webpackMerge(commonConfig, { module: { preLoaders: [{ test: /\.ts$/, - loader: "tslint" + loader: 'tslint' }], /** @@ -94,7 +94,7 @@ module.exports = webpackMerge(commonConfig, { new ExtractTextPlugin('[name].[hash].css'), function () { - this.plugin("done", function (stats) { + this.plugin('done', function (stats) { if (stats.compilation.errors && stats.compilation.errors.length && process.argv.indexOf('--watch') == -1) { console.log(stats.compilation.errors); diff --git a/src/Squidex/app-config/webpack.test.js b/src/Squidex/app-config/webpack.test.js index 97c35bdbe..b4985ad9b 100644 --- a/src/Squidex/app-config/webpack.test.js +++ b/src/Squidex/app-config/webpack.test.js @@ -62,6 +62,10 @@ module.exports = { } ] }, + + sassLoader: { + includePaths: [helpers.root('app', 'theme')] + }, plugins: [ /** diff --git a/src/Squidex/app/app.component.spec.ts b/src/Squidex/app/app.component.spec.ts index d6fc9c607..9ad137762 100644 --- a/src/Squidex/app/app.component.spec.ts +++ b/src/Squidex/app/app.component.spec.ts @@ -7,7 +7,7 @@ import { AppComponent } from './app.component'; describe('App', () => { beforeEach(() => { - TestBed.configureTestingModule({ + TestBed.configureTestingModule({ declarations: [ AppComponent ], @@ -20,7 +20,7 @@ describe('App', () => { ] }); }); - + it('should work', () => { const fixture = TestBed.createComponent(AppComponent); diff --git a/src/Squidex/app/app.module.ts b/src/Squidex/app/app.module.ts index 277e079d3..d05adbf9a 100644 --- a/src/Squidex/app/app.module.ts +++ b/src/Squidex/app/app.module.ts @@ -10,8 +10,9 @@ import * as Ng2Browser from '@angular/platform-browser'; import { AppComponent } from './app.component'; -import { +import { ApiUrlConfig, + AppMustExistGuard, AppsStoreService, AppsService, AuthService, @@ -53,6 +54,7 @@ const baseUrl = window.location.protocol + '//' + window.location.host + '/'; providers: [ AppsStoreService, AppsService, + AppMustExistGuard, AuthService, MustBeAuthenticatedGuard, MustBeNotAuthenticatedGuard, @@ -61,7 +63,7 @@ const baseUrl = window.location.protocol + '//' + window.location.host + '/'; { provide: CurrencyConfig, useValue: new CurrencyConfig('EUR', '€', true) }, { provide: DecimalSeparatorConfig, useValue: new DecimalSeparatorConfig('.') }, { provide: DragService, useFactory: DragServiceFactory }, - { provide: TitlesConfig, useValue: new TitlesConfig({}, null, 'Squidex Headless CMS') } + { provide: TitlesConfig, useValue: new TitlesConfig({}, undefined, 'Squidex Headless CMS') } ], bootstrap: [AppComponent] }) diff --git a/src/Squidex/app/app.routes.ts b/src/Squidex/app/app.routes.ts index 8ef5dec10..cfde1a782 100644 --- a/src/Squidex/app/app.routes.ts +++ b/src/Squidex/app/app.routes.ts @@ -18,7 +18,8 @@ import { NotFoundPageComponent } from './components'; -import { +import { + AppMustExistGuard, MustBeAuthenticatedGuard, MustBeNotAuthenticatedGuard } from './shared'; @@ -27,7 +28,7 @@ export const routes: Ng2Router.Routes = [ { path: '', component: HomePageComponent, - canActivate: [MustBeNotAuthenticatedGuard], + canActivate: [MustBeNotAuthenticatedGuard] }, { path: 'app', @@ -41,6 +42,7 @@ export const routes: Ng2Router.Routes = [ { path: ':appName', component: AppAreaComponent, + canActivate: [AppMustExistGuard], children: [ { path: '', diff --git a/src/Squidex/app/components/internal/app/dashboard/dashboard-page.component.ts b/src/Squidex/app/components/internal/app/dashboard/dashboard-page.component.ts index 8e9c1860f..270aa2982 100644 --- a/src/Squidex/app/components/internal/app/dashboard/dashboard-page.component.ts +++ b/src/Squidex/app/components/internal/app/dashboard/dashboard-page.component.ts @@ -6,9 +6,25 @@ */ import * as Ng2 from '@angular/core'; +import * as Ng2Router from '@angular/router'; + +import { TitleService } from 'shared'; @Ng2.Component({ selector: 'sqx-dashboard-page', template }) -export class DashboardComponent { } \ No newline at end of file +export class DashboardComponent implements Ng2.OnInit { + constructor( + private readonly titles: TitleService, + private readonly route: Ng2Router.ActivatedRoute + ) { + } + + public ngOnInit() { + const appName = this.route.snapshot.params['appName']; + + this.titles.setTitle('{appName} | Dashboard', { appName: appName }); + } +} + diff --git a/src/Squidex/app/components/internal/apps/apps-page.component.ts b/src/Squidex/app/components/internal/apps/apps-page.component.ts index 8d15b2a31..06c1e05f1 100644 --- a/src/Squidex/app/components/internal/apps/apps-page.component.ts +++ b/src/Squidex/app/components/internal/apps/apps-page.component.ts @@ -7,10 +7,11 @@ import * as Ng2 from '@angular/core'; -import { - fadeAnimation, +import { + AppsStoreService, + fadeAnimation, ModalView, - TitleService + TitleService } from 'shared'; @Ng2.Component({ @@ -25,11 +26,14 @@ export class AppsPageComponent implements Ng2.OnInit { public modalDialog = new ModalView(); constructor( - private readonly title: TitleService + private readonly title: TitleService, + private readonly appsStore: AppsStoreService, ) { } public ngOnInit() { + this.appsStore.selectApp(null); + this.title.setTitle('Apps'); } } \ No newline at end of file diff --git a/src/Squidex/app/components/internal/internal-area.component.ts b/src/Squidex/app/components/internal/internal-area.component.ts index 3344ebcb5..a16d8886e 100644 --- a/src/Squidex/app/components/internal/internal-area.component.ts +++ b/src/Squidex/app/components/internal/internal-area.component.ts @@ -7,29 +7,9 @@ import * as Ng2 from '@angular/core'; -import { - fadeAnimation, - ModalView, - TitleService -} from 'shared'; - @Ng2.Component({ selector: 'sqx-internal-area', styles, - template, - animations: [ - fadeAnimation() - ] + template }) -export class InternalAreaComponent implements Ng2.OnInit { - public modalDialog = new ModalView(); - - constructor( - private readonly title: TitleService - ) { - } - - public ngOnInit() { - this.title.setTitle('Apps'); - } -} \ No newline at end of file +export class InternalAreaComponent { } \ No newline at end of file diff --git a/src/Squidex/app/components/layout/app-form.component.html b/src/Squidex/app/components/layout/app-form.component.html index f9ff4f198..bb469722b 100644 --- a/src/Squidex/app/components/layout/app-form.component.html +++ b/src/Squidex/app/components/layout/app-form.component.html @@ -1,7 +1,7 @@
-
+
- {{creationError | async}} + {{creationError}}
@@ -25,7 +25,7 @@ - The app name becomes part of the api url, e.g, https://{{appName | async}}.squidex.io/.
+ The app name becomes part of the api url, e.g, https://{{appName}}.squidex.io/.
It must contain lower case letters (a-z), numbers and dashes only, and cannot be longer than 40 characters. The name cannot be changed later.
diff --git a/src/Squidex/app/components/layout/app-form.component.ts b/src/Squidex/app/components/layout/app-form.component.ts index 632abfeab..1aa2a87b6 100644 --- a/src/Squidex/app/components/layout/app-form.component.ts +++ b/src/Squidex/app/components/layout/app-form.component.ts @@ -8,12 +8,11 @@ import * as Ng2 from '@angular/core'; import * as Ng2Forms from '@angular/forms'; -import { BehaviorSubject } from 'rxjs'; - -import { - AppCreateDto, +import { + AppDto, + AppCreateDto, AppsStoreService, - fadeAnimation + fadeAnimation } from 'shared'; const FALLBACK_NAME = 'my-app'; @@ -25,34 +24,30 @@ const FALLBACK_NAME = 'my-app'; fadeAnimation() ] }) -export class AppFormComponent { +export class AppFormComponent implements Ng2.OnInit { @Ng2.Input() public showClose = false; @Ng2.Output() - public created = new Ng2.EventEmitter(); + public created = new Ng2.EventEmitter(); @Ng2.Output() public cancelled = new Ng2.EventEmitter(); public createForm = this.formBuilder.group({ - name: ['', + name: ['', [ Ng2Forms.Validators.required, Ng2Forms.Validators.maxLength(40), - Ng2Forms.Validators.pattern('[a-z0-9]+(\-[a-z0-9]+)*'), + Ng2Forms.Validators.pattern('[a-z0-9]+(\-[a-z0-9]+)*') ]] }); - public appName = - this.createForm.controls['name'].valueChanges.map(name => name || FALLBACK_NAME).publishBehavior(FALLBACK_NAME).refCount(); - - public creating = - new BehaviorSubject(false); + public appName = FALLBACK_NAME; - public creationError = - new BehaviorSubject(''); + public creating = false; + public creationError = ''; constructor( private readonly appsStore: AppsStoreService, @@ -60,30 +55,36 @@ export class AppFormComponent { ) { } + public ngOnInit() { + this.createForm.controls['name'].valueChanges.subscribe(value => { + this.appName = value; + }); + } + public submit() { this.createForm.markAsDirty(); if (this.createForm.valid) { this.createForm.disable(); - this.creating.next(true); - + this.creating = true; + const dto = new AppCreateDto(this.createForm.controls['name'].value); this.appsStore.createApp(dto) - .subscribe(() => { + .subscribe(app => { this.createForm.reset(); - this.created.emit(); + this.created.emit(app); }, error => { this.reset(); - this.creationError.next(error); + this.creationError = error; }); } } private reset() { this.createForm.enable(); - this.creating.next(false); - this.creationError.next(null); + this.creating = false; + this.creationError = ''; } public cancel() { diff --git a/src/Squidex/app/components/layout/apps-menu-list.component.html b/src/Squidex/app/components/layout/apps-menu-list.component.html deleted file mode 100644 index 853d6677c..000000000 --- a/src/Squidex/app/components/layout/apps-menu-list.component.html +++ /dev/null @@ -1,12 +0,0 @@ - - All Apps - {{apps.length || 0}} - - - - -
- {{app.name}} - - -
\ No newline at end of file diff --git a/src/Squidex/app/components/layout/apps-menu-list.component.scss b/src/Squidex/app/components/layout/apps-menu-list.component.scss deleted file mode 100644 index 039b0d6d7..000000000 --- a/src/Squidex/app/components/layout/apps-menu-list.component.scss +++ /dev/null @@ -1,19 +0,0 @@ -@import '_vars'; -@import '_mixins'; - -.all-apps { - & { - position: relative; - } - - &-text { - font-weight: bold; - } - - &-pill { - @include absolute(6px, 10px, auto, auto); - background: $theme-blue-lighter; - border: 0; - color: $theme-blue; - } -} \ No newline at end of file diff --git a/src/Squidex/app/components/layout/apps-menu-list.component.ts b/src/Squidex/app/components/layout/apps-menu-list.component.ts deleted file mode 100644 index bd4172f4e..000000000 --- a/src/Squidex/app/components/layout/apps-menu-list.component.ts +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Squidex Headless CMS - * - * @license - * Copyright (c) Sebastian Stehle. All rights reserved - */ - -import * as Ng2 from '@angular/core'; - -import { AppDto } from 'shared'; - -@Ng2.Component({ - selector: 'sqx-apps-menu-list', - styles, - template -}) -export class AppsMenuListComponent { - - @Ng2.Input() - public apps: AppDto[]; -} \ No newline at end of file diff --git a/src/Squidex/app/components/layout/apps-menu.component.html b/src/Squidex/app/components/layout/apps-menu.component.html index f16c62415..ddae75a9c 100644 --- a/src/Squidex/app/components/layout/apps-menu.component.html +++ b/src/Squidex/app/components/layout/apps-menu.component.html @@ -1,9 +1,20 @@