diff --git a/src/Squidex.Domain.Apps.Read/Apps/Services/IAppPlansProvider.cs b/src/Squidex.Domain.Apps.Read/Apps/Services/IAppPlansProvider.cs index 884dfb3a1..5128fdfb2 100644 --- a/src/Squidex.Domain.Apps.Read/Apps/Services/IAppPlansProvider.cs +++ b/src/Squidex.Domain.Apps.Read/Apps/Services/IAppPlansProvider.cs @@ -16,7 +16,11 @@ namespace Squidex.Domain.Apps.Read.Apps.Services bool IsConfiguredPlan(string planId); - IAppLimitsPlan GetPlanForApp(IAppEntity entity); + IAppLimitsPlan GetPlanUpgradeForApp(IAppEntity app); + + IAppLimitsPlan GetPlanUpgrade(string planId); + + IAppLimitsPlan GetPlanForApp(IAppEntity app); IAppLimitsPlan GetPlan(string planId); } diff --git a/src/Squidex.Domain.Apps.Read/Apps/Services/Implementations/ConfigAppPlansProvider.cs b/src/Squidex.Domain.Apps.Read/Apps/Services/Implementations/ConfigAppPlansProvider.cs index ee44aac44..ed2e6181a 100644 --- a/src/Squidex.Domain.Apps.Read/Apps/Services/Implementations/ConfigAppPlansProvider.cs +++ b/src/Squidex.Domain.Apps.Read/Apps/Services/Implementations/ConfigAppPlansProvider.cs @@ -24,18 +24,25 @@ namespace Squidex.Domain.Apps.Read.Apps.Services.Implementations MaxContributors = -1 }; - private readonly Dictionary config; + private readonly Dictionary plansById; + private readonly List plansList; public ConfigAppPlansProvider(IEnumerable config) { Guard.NotNull(config, nameof(config)); - this.config = config.Select(c => c.Clone()).OrderBy(x => x.MaxApiCalls).ToDictionary(c => c.Id, StringComparer.OrdinalIgnoreCase); + plansList = config.Select(c => c.Clone()).OrderBy(x => x.MaxApiCalls).ToList(); + plansById = plansList.ToDictionary(c => c.Id, StringComparer.OrdinalIgnoreCase); } public IEnumerable GetAvailablePlans() { - return config.Values; + return plansList; + } + + public bool IsConfiguredPlan(string planId) + { + return planId != null && plansById.ContainsKey(planId); } public IAppLimitsPlan GetPlanForApp(IAppEntity app) @@ -47,12 +54,33 @@ namespace Squidex.Domain.Apps.Read.Apps.Services.Implementations public IAppLimitsPlan GetPlan(string planId) { - return config.GetOrDefault(planId ?? string.Empty) ?? config.Values.FirstOrDefault() ?? Infinite; + return GetPlanCore(planId); } - public bool IsConfiguredPlan(string planId) + public IAppLimitsPlan GetPlanUpgradeForApp(IAppEntity app) + { + Guard.NotNull(app, nameof(app)); + + return GetPlanUpgrade(app.PlanId); + } + + public IAppLimitsPlan GetPlanUpgrade(string planId) + { + var plan = GetPlanCore(planId); + + var nextPlanIndex = plansList.IndexOf(plan); + + if (nextPlanIndex >= 0 && nextPlanIndex < plansList.Count - 1) + { + return plansList[nextPlanIndex + 1]; + } + + return null; + } + + private ConfigAppLimitsPlan GetPlanCore(string planId) { - return planId != null && config.ContainsKey(planId); + return plansById.GetOrDefault(planId ?? string.Empty) ?? plansById.Values.FirstOrDefault() ?? Infinite; } } } diff --git a/src/Squidex/Controllers/Api/Apps/AppsController.cs b/src/Squidex/Controllers/Api/Apps/AppsController.cs index dbb119dbd..31ddaa735 100644 --- a/src/Squidex/Controllers/Api/Apps/AppsController.cs +++ b/src/Squidex/Controllers/Api/Apps/AppsController.cs @@ -12,7 +12,9 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using NSwag.Annotations; using Squidex.Controllers.Api.Apps.Models; +using Squidex.Domain.Apps.Core.Apps; using Squidex.Domain.Apps.Read.Apps.Repositories; +using Squidex.Domain.Apps.Read.Apps.Services; using Squidex.Domain.Apps.Write.Apps.Commands; using Squidex.Infrastructure.CQRS.Commands; using Squidex.Infrastructure.Reflection; @@ -30,11 +32,15 @@ namespace Squidex.Controllers.Api.Apps public sealed class AppsController : ControllerBase { private readonly IAppRepository appRepository; + private readonly IAppPlansProvider appPlansProvider; - public AppsController(ICommandBus commandBus, IAppRepository appRepository) + public AppsController(ICommandBus commandBus, + IAppRepository appRepository, + IAppPlansProvider appPlansProvider) : base(commandBus) { this.appRepository = appRepository; + this.appPlansProvider = appPlansProvider; } /// @@ -57,11 +63,14 @@ namespace Squidex.Controllers.Api.Apps var apps = await appRepository.QueryAllAsync(subject); - var response = apps.Select(s => + var response = apps.Select(a => { - var dto = SimpleMapper.Map(s, new AppDto()); + var dto = SimpleMapper.Map(a, new AppDto()); - dto.Permission = s.Contributors[subject]; + dto.Permission = a.Contributors[subject]; + + dto.PlanName = appPlansProvider.GetPlanForApp(a)?.Name; + dto.PlanUpgrade = appPlansProvider.GetPlanUpgradeForApp(a)?.Name; return dto; }).ToList(); @@ -84,7 +93,7 @@ namespace Squidex.Controllers.Api.Apps /// [HttpPost] [Route("apps/")] - [ProducesResponseType(typeof(EntityCreatedDto), 201)] + [ProducesResponseType(typeof(AppCreatedDto), 201)] [ProducesResponseType(typeof(ErrorDto), 400)] [ProducesResponseType(typeof(ErrorDto), 409)] [ApiCosts(1)] @@ -95,7 +104,12 @@ namespace Squidex.Controllers.Api.Apps var context = await CommandBus.PublishAsync(command); var result = context.Result>(); - var response = new EntityCreatedDto { Id = result.IdOrValue.ToString(), Version = result.Version }; + var response = new AppCreatedDto { Id = result.IdOrValue.ToString(), Version = result.Version }; + + response.Permission = AppContributorPermission.Owner; + + response.PlanName = appPlansProvider.GetPlan(null)?.Name; + response.PlanUpgrade = appPlansProvider.GetPlanUpgrade(null)?.Name; return CreatedAtAction(nameof(GetApps), response); } diff --git a/src/Squidex/Controllers/Api/Apps/Models/AppCreatedDto.cs b/src/Squidex/Controllers/Api/Apps/Models/AppCreatedDto.cs new file mode 100644 index 000000000..90c191755 --- /dev/null +++ b/src/Squidex/Controllers/Api/Apps/Models/AppCreatedDto.cs @@ -0,0 +1,45 @@ +// ========================================================================== +// AppCreatedDto.cs +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex Group +// All rights reserved. +// ========================================================================== + +using System.ComponentModel.DataAnnotations; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Squidex.Domain.Apps.Core.Apps; + +namespace Squidex.Controllers.Api.Apps.Models +{ + public sealed class AppCreatedDto + { + /// + /// Id of the created entity. + /// + [Required] + public string Id { get; set; } + + /// + /// The new version of the entity. + /// + public long Version { get; set; } + + /// + /// The permission level of the user. + /// + [JsonConverter(typeof(StringEnumConverter))] + public AppContributorPermission Permission { get; set; } + + /// + /// Gets the current plan name. + /// + public string PlanName { get; set; } + + /// + /// Gets the next plan name. + /// + public string PlanUpgrade { get; set; } + } +} diff --git a/src/Squidex/Controllers/Api/Apps/Models/AppDto.cs b/src/Squidex/Controllers/Api/Apps/Models/AppDto.cs index f0eddfd0e..f48917dae 100644 --- a/src/Squidex/Controllers/Api/Apps/Models/AppDto.cs +++ b/src/Squidex/Controllers/Api/Apps/Models/AppDto.cs @@ -49,5 +49,15 @@ namespace Squidex.Controllers.Api.Apps.Models /// [JsonConverter(typeof(StringEnumConverter))] public AppContributorPermission Permission { get; set; } + + /// + /// Gets the current plan name. + /// + public string PlanName { get; set; } + + /// + /// Gets the next plan name. + /// + public string PlanUpgrade { get; set; } } } diff --git a/src/Squidex/app/app.routes.ts b/src/Squidex/app/app.routes.ts index 2505c716a..72ca0bca7 100644 --- a/src/Squidex/app/app.routes.ts +++ b/src/Squidex/app/app.routes.ts @@ -18,9 +18,9 @@ import { } from './shell'; import { - AppMustExistGuard, MustBeAuthenticatedGuard, - MustBeNotAuthenticatedGuard + MustBeNotAuthenticatedGuard, + ResolveAppGuard } from './shared'; export const routes: Routes = [ @@ -45,7 +45,9 @@ export const routes: Routes = [ { path: ':appName', component: AppAreaComponent, - canActivate: [AppMustExistGuard], + resolve: { + app: ResolveAppGuard + }, children: [ { path: '', diff --git a/src/Squidex/app/features/administration/pages/event-consumers/event-consumers-page.component.html b/src/Squidex/app/features/administration/pages/event-consumers/event-consumers-page.component.html index 8fa8f7792..fd3a2f58e 100644 --- a/src/Squidex/app/features/administration/pages/event-consumers/event-consumers-page.component.html +++ b/src/Squidex/app/features/administration/pages/event-consumers/event-consumers-page.component.html @@ -1,6 +1,6 @@ - +
diff --git a/src/Squidex/app/features/administration/pages/event-consumers/event-consumers-page.component.ts b/src/Squidex/app/features/administration/pages/event-consumers/event-consumers-page.component.ts index a87dc7006..a2485aab4 100644 --- a/src/Squidex/app/features/administration/pages/event-consumers/event-consumers-page.component.ts +++ b/src/Squidex/app/features/administration/pages/event-consumers/event-consumers-page.component.ts @@ -9,8 +9,7 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { Observable, Subscription } from 'rxjs'; import { - ComponentBase, - DialogService, + AppContext, EventConsumerDto, EventConsumersService, fadeAnimation, @@ -22,21 +21,23 @@ import { selector: 'sqx-event-consumers-page', styleUrls: ['./event-consumers-page.component.scss'], templateUrl: './event-consumers-page.component.html', + providers: [ + AppContext + ], animations: [ fadeAnimation ] }) -export class EventConsumersPageComponent extends ComponentBase implements OnDestroy, OnInit { +export class EventConsumersPageComponent implements OnDestroy, OnInit { private subscription: Subscription; public eventConsumerErrorDialog = new ModalView(); public eventConsumerError = ''; public eventConsumers = ImmutableArray.empty(); - constructor(dialogs: DialogService, + constructor(public readonly ctx: AppContext, private readonly eventConsumersService: EventConsumersService ) { - super(dialogs); } public ngOnDestroy() { @@ -58,11 +59,11 @@ export class EventConsumersPageComponent extends ComponentBase implements OnDest this.eventConsumers = ImmutableArray.of(dtos); if (showInfo) { - this.notifyInfo('Event Consumers reloaded.'); + this.ctx.notifyInfo('Event Consumers reloaded.'); } }, error => { if (showError) { - this.notifyError(error); + this.ctx.notifyError(error); } }); } @@ -72,7 +73,7 @@ export class EventConsumersPageComponent extends ComponentBase implements OnDest .subscribe(() => { this.eventConsumers = this.eventConsumers.replaceBy('name', consumer.start()); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } @@ -81,7 +82,7 @@ export class EventConsumersPageComponent extends ComponentBase implements OnDest .subscribe(() => { this.eventConsumers = this.eventConsumers.replaceBy('name', consumer.stop()); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } @@ -90,7 +91,7 @@ export class EventConsumersPageComponent extends ComponentBase implements OnDest .subscribe(() => { this.eventConsumers = this.eventConsumers.replaceBy('name', consumer.reset()); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } diff --git a/src/Squidex/app/features/administration/pages/users/user-page.component.html b/src/Squidex/app/features/administration/pages/users/user-page.component.html index 3dbd6bc57..39a96fe6d 100644 --- a/src/Squidex/app/features/administration/pages/users/user-page.component.html +++ b/src/Squidex/app/features/administration/pages/users/user-page.component.html @@ -3,7 +3,7 @@
- +
@@ -52,7 +52,7 @@
-
+
diff --git a/src/Squidex/app/features/administration/pages/users/user-page.component.ts b/src/Squidex/app/features/administration/pages/users/user-page.component.ts index eb8824a30..105c1d55f 100644 --- a/src/Squidex/app/features/administration/pages/users/user-page.component.ts +++ b/src/Squidex/app/features/administration/pages/users/user-page.component.ts @@ -7,13 +7,10 @@ import { Component, OnInit } from '@angular/core'; import { FormGroup, FormBuilder, Validators } from '@angular/forms'; -import { ActivatedRoute, Router } from '@angular/router'; +import { Router } from '@angular/router'; import { - AuthService, - ComponentBase, - DialogService, - MessageBus, + AppContext, UserDto, UserManagementService, ValidatorsEx @@ -24,12 +21,14 @@ import { UserCreated, UserUpdated } from './../messages'; @Component({ selector: 'sqx-user-page', styleUrls: ['./user-page.component.scss'], - templateUrl: './user-page.component.html' + templateUrl: './user-page.component.html', + providers: [ + AppContext + ] }) -export class UserPageComponent extends ComponentBase implements OnInit { +export class UserPageComponent implements OnInit { private user: UserDto; - public currentUserId: string; public userFormSubmitted = false; public userForm: FormGroup; public userFormError? = ''; @@ -37,21 +36,15 @@ export class UserPageComponent extends ComponentBase implements OnInit { public isCurrentUser = false; public isNewMode = false; - constructor(dialogs: DialogService, - private readonly authService: AuthService, + constructor(public readonly ctx: AppContext, private readonly formBuilder: FormBuilder, - private readonly messageBus: MessageBus, - private readonly route: ActivatedRoute, private readonly router: Router, private readonly userManagementService: UserManagementService ) { - super(dialogs); } public ngOnInit() { - this.currentUserId = this.authService.user!.id; - - this.route.data.map(p => p['user']) + this.ctx.route.data.map(d => d.user) .subscribe((user: UserDto) => { this.user = user; @@ -78,8 +71,9 @@ export class UserPageComponent extends ComponentBase implements OnInit { created.pictureUrl!, false); + this.ctx.notifyInfo('User created successfully.'); + this.emitUserCreated(this.user); - this.notifyInfo('User created successfully.'); this.back(); }, error => { this.resetUserForm(error.displayMessage); @@ -92,8 +86,9 @@ export class UserPageComponent extends ComponentBase implements OnInit { requestDto.email, requestDto.displayMessage); + this.ctx.notifyInfo('User saved successfully.'); + this.emitUserUpdated(this.user); - this.notifyInfo('User saved successfully.'); this.resetUserForm(); }, error => { this.resetUserForm(error.displayMessage); @@ -103,15 +98,15 @@ export class UserPageComponent extends ComponentBase implements OnInit { } private back() { - this.router.navigate(['../'], { relativeTo: this.route, replaceUrl: true }); + this.router.navigate(['../'], { relativeTo: this.ctx.route, replaceUrl: true }); } private emitUserCreated(user: UserDto) { - this.messageBus.emit(new UserCreated(user)); + this.ctx.bus.emit(new UserCreated(user)); } private emitUserUpdated(user: UserDto) { - this.messageBus.emit(new UserUpdated(user)); + this.ctx.bus.emit(new UserUpdated(user)); } private setupAndPopulateForm() { @@ -141,7 +136,7 @@ export class UserPageComponent extends ComponentBase implements OnInit { ]] }); - this.isCurrentUser = this.user && this.user.id === this.currentUserId; + this.isCurrentUser = this.user && this.user.id === this.ctx.userId; this.resetUserForm(); } diff --git a/src/Squidex/app/features/administration/pages/users/users-page.component.html b/src/Squidex/app/features/administration/pages/users/users-page.component.html index c4370b21f..d22a8362c 100644 --- a/src/Squidex/app/features/administration/pages/users/users-page.component.html +++ b/src/Squidex/app/features/administration/pages/users/users-page.component.html @@ -1,6 +1,6 @@ - +
@@ -69,7 +69,7 @@ {{user.email}} - + diff --git a/src/Squidex/app/features/administration/pages/users/users-page.component.ts b/src/Squidex/app/features/administration/pages/users/users-page.component.ts index 918619e22..dc3c508e4 100644 --- a/src/Squidex/app/features/administration/pages/users/users-page.component.ts +++ b/src/Squidex/app/features/administration/pages/users/users-page.component.ts @@ -10,11 +10,8 @@ import { FormControl } from '@angular/forms'; import { Subscription } from 'rxjs'; import { - AuthService, - ComponentBase, - DialogService, + AppContext, ImmutableArray, - MessageBus, Pager, UserDto, UserManagementService @@ -25,25 +22,23 @@ import { UserCreated, UserUpdated } from './../messages'; @Component({ selector: 'sqx-users-page', styleUrls: ['./users-page.component.scss'], - templateUrl: './users-page.component.html' + templateUrl: './users-page.component.html', + providers: [ + AppContext + ] }) -export class UsersPageComponent extends ComponentBase implements OnDestroy, OnInit { +export class UsersPageComponent implements OnDestroy, OnInit { private userCreatedSubscription: Subscription; private userUpdatedSubscription: Subscription; - public currentUserId: string; - public usersItems = ImmutableArray.empty(); public usersPager = new Pager(0); public usersFilter = new FormControl(); public usersQuery = ''; - constructor(dialogs: DialogService, - private readonly userManagementService: UserManagementService, - private readonly authService: AuthService, - private readonly messageBus: MessageBus + constructor(public readonly ctx: AppContext, + private readonly userManagementService: UserManagementService ) { - super(dialogs); } public ngOnDestroy() { @@ -53,20 +48,18 @@ export class UsersPageComponent extends ComponentBase implements OnDestroy, OnIn public ngOnInit() { this.userCreatedSubscription = - this.messageBus.of(UserCreated) + this.ctx.bus.of(UserCreated) .subscribe(message => { this.usersItems = this.usersItems.pushFront(message.user); this.usersPager = this.usersPager.incrementCount(); }); this.userUpdatedSubscription = - this.messageBus.of(UserUpdated) + this.ctx.bus.of(UserUpdated) .subscribe(message => { this.usersItems = this.usersItems.replaceBy('id', message.user); }); - this.currentUserId = this.authService.user!.id; - this.load(); } @@ -84,10 +77,10 @@ export class UsersPageComponent extends ComponentBase implements OnDestroy, OnIn this.usersPager = this.usersPager.setCount(dtos.total); if (showInfo) { - this.notifyInfo('Users reloaded.'); + this.ctx.notifyInfo('Users reloaded.'); } }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } @@ -96,7 +89,7 @@ export class UsersPageComponent extends ComponentBase implements OnDestroy, OnIn .subscribe(() => { this.usersItems = this.usersItems.replaceBy('id', user.lock()); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } @@ -105,7 +98,7 @@ export class UsersPageComponent extends ComponentBase implements OnDestroy, OnIn .subscribe(() => { this.usersItems = this.usersItems.replaceBy('id', user.unlock()); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } diff --git a/src/Squidex/app/features/api/api-area.component.html b/src/Squidex/app/features/api/api-area.component.html index c94f15286..59c48ccf6 100644 --- a/src/Squidex/app/features/api/api-area.component.html +++ b/src/Squidex/app/features/api/api-area.component.html @@ -1,6 +1,6 @@ - + - +

API

@@ -21,7 +21,7 @@ diff --git a/src/Squidex/app/features/api/api-area.component.ts b/src/Squidex/app/features/api/api-area.component.ts index cf4864388..8278d5b36 100644 --- a/src/Squidex/app/features/api/api-area.component.ts +++ b/src/Squidex/app/features/api/api-area.component.ts @@ -7,21 +7,19 @@ import { Component } from '@angular/core'; -import { - AppComponentBase, - AppsStoreService, - AuthService, - DialogService -} from 'shared'; +import { AppContext } from 'shared'; @Component({ selector: 'sqx-api-area', styleUrls: ['./api-area.component.scss'], - templateUrl: './api-area.component.html' + templateUrl: './api-area.component.html', + providers: [ + AppContext + ] }) -export class ApiAreaComponent extends AppComponentBase { - constructor(apps: AppsStoreService, dialogs: DialogService, authService: AuthService +export class ApiAreaComponent { + constructor( + public readonly ctx: AppContext ) { - super(dialogs, apps, authService); } } \ No newline at end of file diff --git a/src/Squidex/app/features/api/pages/graphql/graphql-page.component.html b/src/Squidex/app/features/api/pages/graphql/graphql-page.component.html index 7dedbeb1b..ff2fc5573 100644 --- a/src/Squidex/app/features/api/pages/graphql/graphql-page.component.html +++ b/src/Squidex/app/features/api/pages/graphql/graphql-page.component.html @@ -1,5 +1,5 @@ - + - +
\ No newline at end of file diff --git a/src/Squidex/app/features/api/pages/graphql/graphql-page.component.ts b/src/Squidex/app/features/api/pages/graphql/graphql-page.component.ts index c045b75df..323a1b033 100644 --- a/src/Squidex/app/features/api/pages/graphql/graphql-page.component.ts +++ b/src/Squidex/app/features/api/pages/graphql/graphql-page.component.ts @@ -16,10 +16,7 @@ const GraphiQL = require('graphiql'); /* tslint:disable:use-view-encapsulation */ import { - AppComponentBase, - AppsStoreService, - AuthService, - DialogService, + AppContext, GraphQlService, LocalStoreService } from 'shared'; @@ -28,17 +25,19 @@ import { selector: 'sqx-graphql-page', styleUrls: ['./graphql-page.component.scss'], templateUrl: './graphql-page.component.html', + providers: [ + AppContext + ], encapsulation: ViewEncapsulation.None }) -export class GraphQLPageComponent extends AppComponentBase implements OnInit { +export class GraphQLPageComponent implements OnInit { @ViewChild('graphiQLContainer') public graphiQLContainer: ElementRef; - constructor(apps: AppsStoreService, dialogs: DialogService, authService: AuthService, + constructor(public readonly ctx: AppContext, private readonly graphQlService: GraphQlService, private readonly localStoreService: LocalStoreService ) { - super(dialogs, apps, authService); } public ngOnInit() { @@ -57,9 +56,7 @@ export class GraphQLPageComponent extends AppComponentBase implements OnInit { } private request(params: any) { - return this.appNameOnce() - .switchMap(app => this.graphQlService.query(app, params).catch(response => Observable.of(response.error))) - .toPromise(); + return this.graphQlService.query(this.ctx.appName, params).catch(response => Observable.of(response.error)).toPromise(); } } diff --git a/src/Squidex/app/features/apps/pages/apps-page.component.html b/src/Squidex/app/features/apps/pages/apps-page.component.html index bb08afd66..aa3f2a039 100644 --- a/src/Squidex/app/features/apps/pages/apps-page.component.html +++ b/src/Squidex/app/features/apps/pages/apps-page.component.html @@ -1,13 +1,13 @@ 
-
+

You are not collaborating to any app yet

-
+

{{app.name}}

diff --git a/src/Squidex/app/features/apps/pages/apps-page.component.ts b/src/Squidex/app/features/apps/pages/apps-page.component.ts index 741dc448f..4cb17902c 100644 --- a/src/Squidex/app/features/apps/pages/apps-page.component.ts +++ b/src/Squidex/app/features/apps/pages/apps-page.component.ts @@ -9,7 +9,8 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { Subscription } from 'rxjs'; import { - AppsStoreService, + AppDto, + AppsService, fadeAnimation, ModalView, OnboardingService @@ -24,33 +25,33 @@ import { ] }) export class AppsPageComponent implements OnDestroy, OnInit { - private onboardingAppsSubscription: Subscription; + private appsSubscription: Subscription; public addAppDialog = new ModalView(); - public apps = this.appsStore.apps; + public apps: AppDto[]; public onboardingModal = new ModalView(); constructor( - private readonly appsStore: AppsStoreService, + private readonly appsService: AppsService, private readonly onboardingService: OnboardingService ) { } public ngOnDestroy() { - this.onboardingAppsSubscription.unsubscribe(); + this.appsSubscription.unsubscribe(); } public ngOnInit() { - this.appsStore.selectApp(null); - - this.onboardingAppsSubscription = - this.appsStore.apps + this.appsSubscription = + this.appsService.getApps() .subscribe(apps => { if (apps.length === 0 && this.onboardingService.shouldShow('dialog')) { this.onboardingService.disable('dialog'); this.onboardingModal.show(); } + + this.apps = apps; }); } } \ No newline at end of file diff --git a/src/Squidex/app/features/assets/pages/assets-page.component.html b/src/Squidex/app/features/assets/pages/assets-page.component.html index a127b3ab1..640ed5fcd 100644 --- a/src/Squidex/app/features/assets/pages/assets-page.component.html +++ b/src/Squidex/app/features/assets/pages/assets-page.component.html @@ -1,6 +1,6 @@ - + - +
diff --git a/src/Squidex/app/features/assets/pages/assets-page.component.ts b/src/Squidex/app/features/assets/pages/assets-page.component.ts index 4e879650f..a20a27a93 100644 --- a/src/Squidex/app/features/assets/pages/assets-page.component.ts +++ b/src/Squidex/app/features/assets/pages/assets-page.component.ts @@ -12,24 +12,23 @@ import { FormControl } from '@angular/forms'; import { Subscription } from 'rxjs'; import { - AppComponentBase, - AppsStoreService, + AppContext, AssetDto, AssetsService, AssetUpdated, - AuthService, - DialogService, ImmutableArray, - MessageBus, Pager } from 'shared'; @Component({ selector: 'sqx-assets-page', styleUrls: ['./assets-page.component.scss'], - templateUrl: './assets-page.component.html' + templateUrl: './assets-page.component.html', + providers: [ + AppContext + ] }) -export class AssetsPageComponent extends AppComponentBase implements OnDestroy, OnInit { +export class AssetsPageComponent implements OnDestroy, OnInit { private assetUpdatedSubscription: Subscription; public newFiles = ImmutableArray.empty(); @@ -39,11 +38,9 @@ export class AssetsPageComponent extends AppComponentBase implements OnDestroy, public assetsFilter = new FormControl(); public assertQuery = ''; - constructor(apps: AppsStoreService, dialogs: DialogService, authService: AuthService, - private readonly assetsService: AssetsService, - private readonly messageBus: MessageBus + constructor(public readonly ctx: AppContext, + private readonly assetsService: AssetsService ) { - super(dialogs, apps, authService); } public ngOnDestroy() { @@ -52,7 +49,7 @@ export class AssetsPageComponent extends AppComponentBase implements OnDestroy, public ngOnInit() { this.assetUpdatedSubscription = - this.messageBus.of(AssetUpdated) + this.ctx.bus.of(AssetUpdated) .subscribe(event => { if (event.sender !== this) { this.assetsItems = this.assetsItems.replaceBy('id', event.assetDto); @@ -70,28 +67,26 @@ export class AssetsPageComponent extends AppComponentBase implements OnDestroy, } public load(showInfo = false) { - this.appNameOnce() - .switchMap(app => this.assetsService.getAssets(app, this.assetsPager.pageSize, this.assetsPager.skip, this.assertQuery)) + this.assetsService.getAssets(this.ctx.appName, this.assetsPager.pageSize, this.assetsPager.skip, this.assertQuery) .subscribe(dtos => { this.assetsItems = ImmutableArray.of(dtos.items); this.assetsPager = this.assetsPager.setCount(dtos.total); if (showInfo) { - this.notifyInfo('Assets reloaded.'); + this.ctx.notifyInfo('Assets reloaded.'); } }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } public onAssetDeleting(asset: AssetDto) { - this.appNameOnce() - .switchMap(app => this.assetsService.deleteAsset(app, asset.id, asset.version)) + this.assetsService.deleteAsset(this.ctx.appName, asset.id, asset.version) .subscribe(dto => { this.assetsItems = this.assetsItems.filter(x => x.id !== asset.id); this.assetsPager = this.assetsPager.decrementCount(); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } @@ -103,7 +98,7 @@ export class AssetsPageComponent extends AppComponentBase implements OnDestroy, } public onAssetUpdated(asset: AssetDto) { - this.messageBus.emit(new AssetUpdated(asset, this)); + this.ctx.bus.emit(new AssetUpdated(asset, this)); } public onAssetFailed(file: File) { diff --git a/src/Squidex/app/features/content/pages/content/content-history.component.html b/src/Squidex/app/features/content/pages/content/content-history.component.html index cd7db5ce1..f04d85e62 100644 --- a/src/Squidex/app/features/content/pages/content/content-history.component.html +++ b/src/Squidex/app/features/content/pages/content/content-history.component.html @@ -1,4 +1,4 @@ - +

Activity

diff --git a/src/Squidex/app/features/content/pages/content/content-history.component.ts b/src/Squidex/app/features/content/pages/content/content-history.component.ts index cc4ed02ed..29d7fed8e 100644 --- a/src/Squidex/app/features/content/pages/content/content-history.component.ts +++ b/src/Squidex/app/features/content/pages/content/content-history.component.ts @@ -6,19 +6,14 @@ */ import { Component } from '@angular/core'; -import { ActivatedRoute } from '@angular/router'; import { Observable } from 'rxjs'; import { allParams, - AppComponentBase, - AppsStoreService, - AuthService, - DialogService, + AppContext, HistoryChannelUpdated, HistoryEventDto, HistoryService, - MessageBus, UsersProviderService } from 'shared'; @@ -29,14 +24,17 @@ const REPLACEMENT_TEMP = '$TEMP$'; @Component({ selector: 'sqx-history', styleUrls: ['./content-history.component.scss'], - templateUrl: './content-history.component.html' + templateUrl: './content-history.component.html', + providers: [ + AppContext + ] }) -export class ContentHistoryComponent extends AppComponentBase { +export class ContentHistoryComponent { public get channel(): string { - let channelPath = this.route.snapshot.data['channel']; + let channelPath = this.ctx.route.snapshot.data['channel']; if (channelPath) { - const params = allParams(this.route); + const params = allParams(this.ctx.route); for (let key in params) { if (params.hasOwnProperty(key)) { @@ -51,18 +49,13 @@ export class ContentHistoryComponent extends AppComponentBase { } public events: Observable = - Observable.timer(0, 10000) - .merge(this.messageBus.of(HistoryChannelUpdated).delay(1000)) - .switchMap(() => this.appNameOnce()) - .switchMap(app => this.historyService.getHistory(app, this.channel).retry(2)); + Observable.timer(0, 10000).merge(this.ctx.bus.of(HistoryChannelUpdated).delay(1000)) + .switchMap(app => this.historyService.getHistory(this.ctx.appName, this.channel)); - constructor(appsStore: AppsStoreService, dialogs: DialogService, authService: AuthService, + constructor(public readonly ctx: AppContext, private readonly users: UsersProviderService, - private readonly historyService: HistoryService, - private readonly messageBus: MessageBus, - private readonly route: ActivatedRoute + private readonly historyService: HistoryService ) { - super(dialogs, appsStore, authService); } private userName(userId: string): Observable { @@ -80,7 +73,7 @@ export class ContentHistoryComponent extends AppComponentBase { } public loadVersion(version: number) { - this.messageBus.emit(new ContentVersionSelected(version)); + this.ctx.bus.emit(new ContentVersionSelected(version)); } public format(message: string): Observable { diff --git a/src/Squidex/app/features/content/pages/content/content-page.component.html b/src/Squidex/app/features/content/pages/content/content-page.component.html index eaf689467..bb578347a 100644 --- a/src/Squidex/app/features/content/pages/content/content-page.component.html +++ b/src/Squidex/app/features/content/pages/content/content-page.component.html @@ -1,7 +1,7 @@ - + - +
diff --git a/src/Squidex/app/features/content/pages/content/content-page.component.ts b/src/Squidex/app/features/content/pages/content/content-page.component.ts index a2b6fd49b..61717ed0a 100644 --- a/src/Squidex/app/features/content/pages/content/content-page.component.ts +++ b/src/Squidex/app/features/content/pages/content/content-page.component.ts @@ -7,7 +7,7 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { AbstractControl, FormControl, FormGroup } from '@angular/forms'; -import { ActivatedRoute, Router } from '@angular/router'; +import { Router } from '@angular/router'; import { Observable, Subscription } from 'rxjs'; import { @@ -20,16 +20,12 @@ import { } from './../messages'; import { - AppComponentBase, + AppContext, AppLanguageDto, - AppsStoreService, allData, - AuthService, CanComponentDeactivate, ContentDto, ContentsService, - DialogService, - MessageBus, SchemaDetailsDto, Version } from 'shared'; @@ -37,9 +33,12 @@ import { @Component({ selector: 'sqx-content-page', styleUrls: ['./content-page.component.scss'], - templateUrl: './content-page.component.html' + templateUrl: './content-page.component.html', + providers: [ + AppContext + ] }) -export class ContentPageComponent extends AppComponentBase implements CanComponentDeactivate, OnDestroy, OnInit { +export class ContentPageComponent implements CanComponentDeactivate, OnDestroy, OnInit { private contentPublishedSubscription: Subscription; private contentUnpublishedSubscription: Subscription; private contentDeletedSubscription: Subscription; @@ -55,13 +54,10 @@ export class ContentPageComponent extends AppComponentBase implements CanCompone public languages: AppLanguageDto[] = []; - constructor(apps: AppsStoreService, dialogs: DialogService, authService: AuthService, + constructor(public readonly ctx: AppContext, private readonly contentsService: ContentsService, - private readonly route: ActivatedRoute, - private readonly router: Router, - private readonly messageBus: MessageBus + private readonly router: Router ) { - super(dialogs, apps, authService); } public ngOnDestroy() { @@ -72,18 +68,18 @@ export class ContentPageComponent extends AppComponentBase implements CanCompone } public ngOnInit() { - const routeData = allData(this.route); + const routeData = allData(this.ctx.route); this.languages = routeData['appLanguages']; this.contentVersionSelectedSubscription = - this.messageBus.of(ContentVersionSelected) + this.ctx.bus.of(ContentVersionSelected) .subscribe(message => { this.loadVersion(message.version); }); this.contentPublishedSubscription = - this.messageBus.of(ContentPublished) + this.ctx.bus.of(ContentPublished) .subscribe(message => { if (this.content && message.content.id === this.content.id) { this.content = this.content.publish(message.content.lastModifiedBy, message.content.version, message.content.lastModified); @@ -91,7 +87,7 @@ export class ContentPageComponent extends AppComponentBase implements CanCompone }); this.contentUnpublishedSubscription = - this.messageBus.of(ContentUnpublished) + this.ctx.bus.of(ContentUnpublished) .subscribe(message => { if (this.content && message.content.id === this.content.id) { this.content = this.content.unpublish(message.content.lastModifiedBy, message.content.version, message.content.lastModified); @@ -99,16 +95,16 @@ export class ContentPageComponent extends AppComponentBase implements CanCompone }); this.contentDeletedSubscription = - this.messageBus.of(ContentRemoved) + this.ctx.bus.of(ContentRemoved) .subscribe(message => { if (this.content && message.content.id === this.content.id) { - this.router.navigate(['../'], { relativeTo: this.route }); + this.router.navigate(['../'], { relativeTo: this.ctx.route }); } }); this.setupContentForm(routeData['schema']); - this.route.data.map(p => p['content']) + this.ctx.route.data.map(d => d.content) .subscribe((content: ContentDto) => { this.content = content; @@ -120,7 +116,7 @@ export class ContentPageComponent extends AppComponentBase implements CanCompone if (!this.contentForm.dirty || this.isNewMode) { return Observable.of(true); } else { - return this.dialogs.confirmUnsavedChanges(); + return this.ctx.confirmUnsavedChanges(); } } @@ -141,64 +137,66 @@ export class ContentPageComponent extends AppComponentBase implements CanCompone const requestDto = this.contentForm.value; if (this.isNewMode) { - this.appNameOnce() - .switchMap(app => this.contentsService.postContent(app, this.schema.name, requestDto, publish)) + this.contentsService.postContent(this.ctx.appName, this.schema.name, requestDto, publish) .subscribe(dto => { this.content = dto; + this.ctx.notifyInfo('Content created successfully.'); + this.emitContentCreated(this.content); - this.notifyInfo('Content created successfully.'); this.back(); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); + this.enableContentForm(); }); } else { - this.appNameOnce() - .switchMap(app => this.contentsService.putContent(app, this.schema.name, this.content.id, requestDto, this.content.version)) + this.contentsService.putContent(this.ctx.appName, this.schema.name, this.content.id, requestDto, this.content.version) .subscribe(dto => { - this.content = this.content.update(dto.payload, this.userToken, dto.version); + this.content = this.content.update(dto.payload, this.ctx.userToken, dto.version); + + this.ctx.notifyInfo('Content saved successfully.'); this.emitContentUpdated(this.content); - this.notifyInfo('Content saved successfully.'); this.enableContentForm(); this.populateContentForm(); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); + this.enableContentForm(); }); } } else { - this.notifyError('Content element not valid, please check the field with the red bar on the left in all languages (if localizable).'); + this.ctx.notifyError('Content element not valid, please check the field with the red bar on the left in all languages (if localizable).'); } } private loadVersion(version: number) { if (!this.isNewMode && this.content) { - this.appNameOnce() - .switchMap(app => this.contentsService.getVersionData(app, this.schema.name, this.content.id, new Version(version.toString()))) + this.contentsService.getVersionData(this.ctx.appName, this.schema.name, this.content.id, new Version(version.toString())) .subscribe(dto => { this.content = this.content.setData(dto); + this.ctx.notifyInfo('Content version loaded successfully.'); + this.emitContentUpdated(this.content); - this.notifyInfo('Content version loaded successfully.'); this.populateContentForm(); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } } private back() { - this.router.navigate(['../'], { relativeTo: this.route, replaceUrl: true }); + this.router.navigate(['../'], { relativeTo: this.ctx.route, replaceUrl: true }); } private emitContentCreated(content: ContentDto) { - this.messageBus.emit(new ContentCreated(content)); + this.ctx.bus.emit(new ContentCreated(content)); } private emitContentUpdated(content: ContentDto) { - this.messageBus.emit(new ContentUpdated(content)); + this.ctx.bus.emit(new ContentUpdated(content)); } private disableContentForm() { diff --git a/src/Squidex/app/features/content/pages/contents/contents-page.component.html b/src/Squidex/app/features/content/pages/contents/contents-page.component.html index d5d39e2c4..40e630622 100644 --- a/src/Squidex/app/features/content/pages/contents/contents-page.component.html +++ b/src/Squidex/app/features/content/pages/contents/contents-page.component.html @@ -1,6 +1,6 @@ - + - +
diff --git a/src/Squidex/app/features/content/pages/contents/contents-page.component.ts b/src/Squidex/app/features/content/pages/contents/contents-page.component.ts index 76e94b060..8c3c30f26 100644 --- a/src/Squidex/app/features/content/pages/contents/contents-page.component.ts +++ b/src/Squidex/app/features/content/pages/contents/contents-page.component.ts @@ -7,7 +7,6 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { FormControl } from '@angular/forms'; -import { ActivatedRoute } from '@angular/router'; import { Subscription } from 'rxjs'; import { @@ -20,16 +19,12 @@ import { import { allData, - AppComponentBase, + AppContext, AppLanguageDto, - AppsStoreService, - AuthService, ContentDto, ContentsService, - DialogService, FieldDto, ImmutableArray, - MessageBus, ModalView, Pager, SchemaDetailsDto @@ -38,9 +33,12 @@ import { @Component({ selector: 'sqx-contents-page', styleUrls: ['./contents-page.component.scss'], - templateUrl: './contents-page.component.html' + templateUrl: './contents-page.component.html', + providers: [ + AppContext + ] }) -export class ContentsPageComponent extends AppComponentBase implements OnDestroy, OnInit { +export class ContentsPageComponent implements OnDestroy, OnInit { private contentCreatedSubscription: Subscription; private contentUpdatedSubscription: Subscription; @@ -63,12 +61,9 @@ export class ContentsPageComponent extends AppComponentBase implements OnDestroy public columnWidth: number; - constructor(apps: AppsStoreService, dialogs: DialogService, authService: AuthService, - private readonly contentsService: ContentsService, - private readonly route: ActivatedRoute, - private readonly messageBus: MessageBus + constructor(public readonly ctx: AppContext, + private readonly contentsService: ContentsService ) { - super(dialogs, apps, authService); } public ngOnDestroy() { @@ -77,29 +72,29 @@ export class ContentsPageComponent extends AppComponentBase implements OnDestroy } public ngOnInit() { - const routeData = allData(this.route); + const routeData = allData(this.ctx.route); this.languages = routeData['appLanguages']; this.contentCreatedSubscription = - this.messageBus.of(ContentCreated) + this.ctx.bus.of(ContentCreated) .subscribe(message => { this.contentItems = this.contentItems.pushFront(message.content); this.contentsPager = this.contentsPager.incrementCount(); }); this.contentUpdatedSubscription = - this.messageBus.of(ContentUpdated) + this.ctx.bus.of(ContentUpdated) .subscribe(message => { this.contentItems = this.contentItems.replaceBy('id', message.content, (o, n) => o.update(n.data, n.lastModifiedBy, n.version, n.lastModified)); }); - this.route.params.map(p => p['language']) + this.ctx.route.params.map(p => p.language) .subscribe(language => { this.languageSelected = this.languages.find(l => l.iso2Code === language) || this.languages.find(l => l.isMaster) || this.languages[0]; }); - this.route.data.map(p => p['schemaOverride'] || p['schema']) + this.ctx.route.data.map(d => d.schemaOverride || d.schema) .subscribe(schema => { this.schema = schema; @@ -115,79 +110,73 @@ export class ContentsPageComponent extends AppComponentBase implements OnDestroy } public publishContent(content: ContentDto) { - this.appNameOnce() - .switchMap(app => this.contentsService.publishContent(app, this.schema.name, content.id, content.version)) + this.contentsService.publishContent(this.ctx.appName, this.schema.name, content.id, content.version) .subscribe(dto => { - content = content.publish(this.userToken, dto.version); + content = content.publish(this.ctx.userToken, dto.version); this.contentItems = this.contentItems.replaceBy('id', content); this.emitContentPublished(content); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } public unpublishContent(content: ContentDto) { - this.appNameOnce() - .switchMap(app => this.contentsService.unpublishContent(app, this.schema.name, content.id, content.version)) + this.contentsService.unpublishContent(this.ctx.appName, this.schema.name, content.id, content.version) .subscribe(dto => { - content = content.unpublish(this.userToken, dto.version); + content = content.unpublish(this.ctx.userToken, dto.version); this.contentItems = this.contentItems.replaceBy('id', content); this.emitContentUnpublished(content); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } public archiveContent(content: ContentDto) { - this.appNameOnce() - .switchMap(app => this.contentsService.archiveContent(app, this.schema.name, content.id, content.version)) + this.contentsService.archiveContent(this.ctx.appName, this.schema.name, content.id, content.version) .subscribe(dto => { - content = content.archive(this.userToken, dto.version); + content = content.archive(this.ctx.userToken, dto.version); this.removeContent(content); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } public restoreContent(content: ContentDto) { - this.appNameOnce() - .switchMap(app => this.contentsService.restoreContent(app, this.schema.name, content.id, content.version)) + this.contentsService.restoreContent(this.ctx.appName, this.schema.name, content.id, content.version) .subscribe(dto => { - content = content.restore(this.userToken, dto.version); + content = content.restore(this.ctx.userToken, dto.version); this.removeContent(content); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } public deleteContent(content: ContentDto) { - this.appNameOnce() - .switchMap(app => this.contentsService.deleteContent(app, this.schema.name, content.id, content.version)) + this.contentsService.deleteContent(this.ctx.appName, this.schema.name, content.id, content.version) .subscribe(() => { this.removeContent(content); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } public load(showInfo = false) { - this.appNameOnce() - .switchMap(app => this.contentsService.getContents(app, this.schema.name, this.contentsPager.pageSize, this.contentsPager.skip, this.contentsQuery, null, this.isArchive)) + this.contentsService.getContents(this.ctx.appName, this.schema.name, this.contentsPager.pageSize, this.contentsPager.skip, this.contentsQuery, null, this.isArchive) .subscribe(dtos => { this.contentItems = ImmutableArray.of(dtos.items); this.contentsPager = this.contentsPager.setCount(dtos.total); if (showInfo) { - this.notifyInfo('Contents reloaded.'); + this.ctx.notifyInfo('Contents reloaded.'); } }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } @@ -226,15 +215,15 @@ export class ContentsPageComponent extends AppComponentBase implements OnDestroy } private emitContentPublished(content: ContentDto) { - this.messageBus.emit(new ContentPublished(content)); + this.ctx.bus.emit(new ContentPublished(content)); } private emitContentUnpublished(content: ContentDto) { - this.messageBus.emit(new ContentUnpublished(content)); + this.ctx.bus.emit(new ContentUnpublished(content)); } private emitContentRemoved(content: ContentDto) { - this.messageBus.emit(new ContentRemoved(content)); + this.ctx.bus.emit(new ContentRemoved(content)); } private resetContents() { diff --git a/src/Squidex/app/features/content/pages/schemas/schemas-page.component.html b/src/Squidex/app/features/content/pages/schemas/schemas-page.component.html index f2c1d6c6b..e49d84873 100644 --- a/src/Squidex/app/features/content/pages/schemas/schemas-page.component.html +++ b/src/Squidex/app/features/content/pages/schemas/schemas-page.component.html @@ -1,6 +1,6 @@ - + - +

Schemas

diff --git a/src/Squidex/app/features/content/pages/schemas/schemas-page.component.ts b/src/Squidex/app/features/content/pages/schemas/schemas-page.component.ts index 0664d01ff..c4e18eeb2 100644 --- a/src/Squidex/app/features/content/pages/schemas/schemas-page.component.ts +++ b/src/Squidex/app/features/content/pages/schemas/schemas-page.component.ts @@ -10,10 +10,7 @@ import { FormControl } from '@angular/forms'; import { Observable } from 'rxjs'; import { - AppComponentBase, - AppsStoreService, - AuthService, - DialogService, + AppContext, SchemaDto, SchemasService } from 'shared'; @@ -21,9 +18,12 @@ import { @Component({ selector: 'sqx-schemas-page', styleUrls: ['./schemas-page.component.scss'], - templateUrl: './schemas-page.component.html' + templateUrl: './schemas-page.component.html', + providers: [ + AppContext + ] }) -export class SchemasPageComponent extends AppComponentBase { +export class SchemasPageComponent { public schemasFilter = new FormControl(); public schemasFiltered = this.schemasFilter.valueChanges @@ -53,17 +53,15 @@ export class SchemasPageComponent extends AppComponentBase { }); }); - constructor(apps: AppsStoreService, dialogs: DialogService, authService: AuthService, + constructor(public readonly ctx: AppContext, private readonly schemasService: SchemasService ) { - super(dialogs, apps, authService); } private loadSchemas(): Observable { - return this.appNameOnce() - .switchMap(app => this.schemasService.getSchemas(app).retry(2)) + return this.schemasService.getSchemas(this.ctx.appName) .catch(error => { - this.notifyError(error); + this.ctx.notifyError(error); return []; }); } diff --git a/src/Squidex/app/features/content/shared/assets-editor.component.ts b/src/Squidex/app/features/content/shared/assets-editor.component.ts index f00531292..3a8505fb9 100644 --- a/src/Squidex/app/features/content/shared/assets-editor.component.ts +++ b/src/Squidex/app/features/content/shared/assets-editor.component.ts @@ -12,15 +12,11 @@ import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { Subscription } from 'rxjs'; import { - AppComponentBase, - AppsStoreService, + AppContext, AssetDto, AssetsService, AssetUpdated, - AuthService, - DialogService, ImmutableArray, - MessageBus, Types } from 'shared'; @@ -32,9 +28,12 @@ export const SQX_ASSETS_EDITOR_CONTROL_VALUE_ACCESSOR: any = { selector: 'sqx-assets-editor', styleUrls: ['./assets-editor.component.scss'], templateUrl: './assets-editor.component.html', - providers: [SQX_ASSETS_EDITOR_CONTROL_VALUE_ACCESSOR] + providers: [ + AppContext, + SQX_ASSETS_EDITOR_CONTROL_VALUE_ACCESSOR + ] }) -export class AssetsEditorComponent extends AppComponentBase implements ControlValueAccessor, OnDestroy, OnInit { +export class AssetsEditorComponent implements ControlValueAccessor, OnDestroy, OnInit { private assetUpdatedSubscription: Subscription; private callChange = (v: any) => { /* NOOP */ }; private callTouched = () => { /* NOOP */ }; @@ -44,11 +43,9 @@ export class AssetsEditorComponent extends AppComponentBase implements ControlVa public isDisabled = false; - constructor(apps: AppsStoreService, dialogs: DialogService, authService: AuthService, - private readonly assetsService: AssetsService, - private readonly messageBus: MessageBus + constructor(public readonly ctx: AppContext, + private readonly assetsService: AssetsService ) { - super(dialogs, apps, authService); } public ngOnDestroy() { @@ -57,7 +54,7 @@ export class AssetsEditorComponent extends AppComponentBase implements ControlVa public ngOnInit() { this.assetUpdatedSubscription = - this.messageBus.of(AssetUpdated) + this.ctx.bus.of(AssetUpdated) .subscribe(event => { if (event.sender !== this) { this.oldAssets = this.oldAssets.replaceBy('id', event.assetDto); @@ -71,8 +68,7 @@ export class AssetsEditorComponent extends AppComponentBase implements ControlVa if (Types.isArrayOfString(value) && value.length > 0) { const assetIds: string[] = value; - this.appNameOnce() - .switchMap(app => this.assetsService.getAssets(app, 10000, 0, undefined, undefined, value)) + this.assetsService.getAssets(this.ctx.appName, 10000, 0, undefined, undefined, value) .subscribe(dtos => { this.oldAssets = ImmutableArray.of(assetIds.map(id => dtos.items.find(x => x.id === id))); }); @@ -129,7 +125,7 @@ export class AssetsEditorComponent extends AppComponentBase implements ControlVa } public onAssetUpdated(asset: AssetDto) { - this.messageBus.emit(new AssetUpdated(asset, this)); + this.ctx.bus.emit(new AssetUpdated(asset, this)); } public onAssetFailed(file: File) { diff --git a/src/Squidex/app/features/content/shared/content-item.component.ts b/src/Squidex/app/features/content/shared/content-item.component.ts index 9f251d814..32f411b98 100644 --- a/src/Squidex/app/features/content/shared/content-item.component.ts +++ b/src/Squidex/app/features/content/shared/content-item.component.ts @@ -8,11 +8,8 @@ import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core'; import { - AppComponentBase, - AppsStoreService, - AuthService, + AppContext, ContentDto, - DialogService, fadeAnimation, FieldDto, ModalView, @@ -25,11 +22,14 @@ import { selector: '[sqxContent]', styleUrls: ['./content-item.component.scss'], templateUrl: './content-item.component.html', + providers: [ + AppContext + ], animations: [ fadeAnimation ] }) -export class ContentItemComponent extends AppComponentBase implements OnInit, OnChanges { +export class ContentItemComponent implements OnInit, OnChanges { @Output() public publishing = new EventEmitter(); @@ -67,8 +67,8 @@ export class ContentItemComponent extends AppComponentBase implements OnInit, On public values: any[] = []; - constructor(apps: AppsStoreService, dialogs: DialogService, authService: AuthService) { - super(dialogs, apps, authService); + constructor(public readonly ctx: AppContext + ) { } public ngOnChanges() { diff --git a/src/Squidex/app/features/content/shared/references-editor.component.ts b/src/Squidex/app/features/content/shared/references-editor.component.ts index 91b6a159f..5af111897 100644 --- a/src/Squidex/app/features/content/shared/references-editor.component.ts +++ b/src/Squidex/app/features/content/shared/references-editor.component.ts @@ -11,14 +11,12 @@ import { Component, forwardRef, Input, OnInit } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import { - AppComponentBase, - AppsStoreService, - AuthService, + AppContext, ContentDto, ContentsService, - DialogService, FieldDto, ImmutableArray, + MathHelper, SchemaDetailsDto, SchemasService, Types @@ -32,9 +30,12 @@ export const SQX_REFERENCES_EDITOR_CONTROL_VALUE_ACCESSOR: any = { selector: 'sqx-references-editor', styleUrls: ['./references-editor.component.scss'], templateUrl: './references-editor.component.html', - providers: [SQX_REFERENCES_EDITOR_CONTROL_VALUE_ACCESSOR] + providers: [ + AppContext, + SQX_REFERENCES_EDITOR_CONTROL_VALUE_ACCESSOR + ] }) -export class ReferencesEditorComponent extends AppComponentBase implements ControlValueAccessor, OnInit { +export class ReferencesEditorComponent implements ControlValueAccessor, OnInit { private callChange = (v: any) => { /* NOOP */ }; private callTouched = () => { /* NOOP */ }; @@ -54,16 +55,18 @@ export class ReferencesEditorComponent extends AppComponentBase implements Contr public isDisabled = false; public isInvalidSchema = false; - constructor(apps: AppsStoreService, dialogs: DialogService, authService: AuthService, + constructor(public readonly ctx: AppContext, private readonly contentsService: ContentsService, private readonly schemasService: SchemasService ) { - super(dialogs, apps, authService); } public ngOnInit() { - this.appNameOnce() - .switchMap(app => this.schemasService.getSchema(app, this.schemaId)) + if (this.schemaId === MathHelper.EMPTY_GUID) { + return; + } + + this.schemasService.getSchema(this.ctx.appName, this.schemaId) .subscribe(dto => { this.schema = dto; @@ -79,8 +82,7 @@ export class ReferencesEditorComponent extends AppComponentBase implements Contr if (Types.isArrayOfString(value) && value.length > 0) { const contentIds: string[] = value; - this.appNameOnce() - .switchMap(app => this.contentsService.getContents(app, this.schemaId, 10000, 0, undefined, contentIds)) + this.contentsService.getContents(this.ctx.appName, this.schemaId, 10000, 0, undefined, contentIds) .subscribe(dtos => { this.contentItems = ImmutableArray.of(contentIds.map(id => dtos.items.find(c => c.id === id)).filter(c => !!c)); }); diff --git a/src/Squidex/app/features/dashboard/pages/dashboard-page.component.html b/src/Squidex/app/features/dashboard/pages/dashboard-page.component.html index 3630a224a..a311a9be7 100644 --- a/src/Squidex/app/features/dashboard/pages/dashboard-page.component.html +++ b/src/Squidex/app/features/dashboard/pages/dashboard-page.component.html @@ -1,13 +1,13 @@ - +
-

Hi {{profileDisplayName}}

+

Hi {{ctx.user.displayName}}

- Welcome to {{appName() | async}} dashboard. + Welcome to {{ctx.appName}} dashboard.
diff --git a/src/Squidex/app/features/dashboard/pages/dashboard-page.component.ts b/src/Squidex/app/features/dashboard/pages/dashboard-page.component.ts index 15ded7f97..2f798a2f9 100644 --- a/src/Squidex/app/features/dashboard/pages/dashboard-page.component.ts +++ b/src/Squidex/app/features/dashboard/pages/dashboard-page.component.ts @@ -8,11 +8,8 @@ import { Component, OnInit } from '@angular/core'; import { - AppComponentBase, - AppsStoreService, - AuthService, + AppContext, DateTime, - DialogService, fadeAnimation, UsagesService } from 'shared'; @@ -23,11 +20,14 @@ declare var _urq: any; selector: 'sqx-dashboard-page', styleUrls: ['./dashboard-page.component.scss'], templateUrl: './dashboard-page.component.html', + providers: [ + AppContext + ], animations: [ fadeAnimation ] }) -export class DashboardPageComponent extends AppComponentBase implements OnInit { +export class DashboardPageComponent implements OnInit { public profileDisplayName = ''; public chartStorageCount: any; @@ -60,29 +60,25 @@ export class DashboardPageComponent extends AppComponentBase implements OnInit { public callsCurrent = 0; public callsMax = 0; - constructor(apps: AppsStoreService, dialogs: DialogService, authService: AuthService, + constructor(public readonly ctx: AppContext, private readonly usagesService: UsagesService ) { - super(dialogs, apps, authService); } public ngOnInit() { - this.appName() - .switchMap(app => this.usagesService.getTodayStorage(app)) + this.usagesService.getTodayStorage(this.ctx.appName) .subscribe(dto => { this.assetsCurrent = dto.size; this.assetsMax = dto.maxAllowed; }); - this.appName() - .switchMap(app => this.usagesService.getMonthCalls(app)) + this.usagesService.getMonthCalls(this.ctx.appName) .subscribe(dto => { this.callsCurrent = dto.count; this.callsMax = dto.maxAllowed; }); - this.appName() - .switchMap(app => this.usagesService.getStorageUsages(app, DateTime.today().addDays(-20), DateTime.today())) + this.usagesService.getStorageUsages(this.ctx.appName, DateTime.today().addDays(-20), DateTime.today()) .subscribe(dtos => { this.chartStorageCount = { labels: createLabels(dtos), @@ -115,8 +111,7 @@ export class DashboardPageComponent extends AppComponentBase implements OnInit { }; }); - this.appName() - .switchMap(app => this.usagesService.getCallsUsages(app, DateTime.today().addDays(-20), DateTime.today())) + this.usagesService.getCallsUsages(this.ctx.appName, DateTime.today().addDays(-20), DateTime.today()) .subscribe(dtos => { this.chartCallsCount = { labels: createLabels(dtos), @@ -144,8 +139,6 @@ export class DashboardPageComponent extends AppComponentBase implements OnInit { ] }; }); - - this.profileDisplayName = this.authService.user!.displayName; } public showForum() { diff --git a/src/Squidex/app/features/rules/pages/events/rule-events-page.component.html b/src/Squidex/app/features/rules/pages/events/rule-events-page.component.html index bdbf99255..d6c8f5f3a 100644 --- a/src/Squidex/app/features/rules/pages/events/rule-events-page.component.html +++ b/src/Squidex/app/features/rules/pages/events/rule-events-page.component.html @@ -1,6 +1,6 @@ - + - +
diff --git a/src/Squidex/app/features/rules/pages/events/rule-events-page.component.ts b/src/Squidex/app/features/rules/pages/events/rule-events-page.component.ts index 6e5fe2657..eed28b81e 100644 --- a/src/Squidex/app/features/rules/pages/events/rule-events-page.component.ts +++ b/src/Squidex/app/features/rules/pages/events/rule-events-page.component.ts @@ -8,10 +8,7 @@ import { Component, OnInit } from '@angular/core'; import { - AppComponentBase, - AppsStoreService, - AuthService, - DialogService, + AppContext, ImmutableArray, Pager, RuleEventDto, @@ -21,18 +18,20 @@ import { @Component({ selector: 'sqx-rule-events-page', styleUrls: ['./rule-events-page.component.scss'], - templateUrl: './rule-events-page.component.html' + templateUrl: './rule-events-page.component.html', + providers: [ + AppContext + ] }) -export class RuleEventsPageComponent extends AppComponentBase implements OnInit { +export class RuleEventsPageComponent implements OnInit { public eventsItems = ImmutableArray.empty(); public eventsPager = new Pager(0); public selectedEventId: string | null = null; - constructor(dialogs: DialogService, appsStore: AppsStoreService, authService: AuthService, + constructor(public readonly ctx: AppContext, private readonly rulesService: RulesService ) { - super(dialogs, appsStore, authService); } public ngOnInit() { @@ -40,27 +39,25 @@ export class RuleEventsPageComponent extends AppComponentBase implements OnInit } public load(showInfo = false) { - this.appNameOnce() - .switchMap(app => this.rulesService.getEvents(app, this.eventsPager.pageSize, this.eventsPager.skip)) + this.rulesService.getEvents(this.ctx.appName, this.eventsPager.pageSize, this.eventsPager.skip) .subscribe(dtos => { this.eventsItems = ImmutableArray.of(dtos.items); this.eventsPager = this.eventsPager.setCount(dtos.total); if (showInfo) { - this.notifyInfo('Events reloaded.'); + this.ctx.notifyInfo('Events reloaded.'); } }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } public enqueueEvent(event: RuleEventDto) { - this.appNameOnce() - .switchMap(app => this.rulesService.enqueueEvent(app, event.id)) + this.rulesService.enqueueEvent(this.ctx.appName, event.id) .subscribe(() => { - this.notifyInfo('Events enqueued. Will be resend in a few seconds.'); + this.ctx.notifyInfo('Events enqueued. Will be resend in a few seconds.'); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } diff --git a/src/Squidex/app/features/rules/pages/rules/rule-wizard.component.ts b/src/Squidex/app/features/rules/pages/rules/rule-wizard.component.ts index f30dac5d9..f9da79804 100644 --- a/src/Squidex/app/features/rules/pages/rules/rule-wizard.component.ts +++ b/src/Squidex/app/features/rules/pages/rules/rule-wizard.component.ts @@ -8,12 +8,9 @@ import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from '@angular/core'; import { - AppComponentBase, - AppsStoreService, - AuthService, + AppContext, CreateRuleDto, DateTime, - DialogService, fadeAnimation, ruleActions, ruleTriggers, @@ -31,11 +28,14 @@ export const MODE_EDIT_ACTION = 'EditAction'; selector: 'sqx-rule-wizard', styleUrls: ['./rule-wizard.component.scss'], templateUrl: './rule-wizard.component.html', + providers: [ + AppContext + ], animations: [ fadeAnimation ] }) -export class RuleWizardComponent extends AppComponentBase implements OnInit { +export class RuleWizardComponent implements OnInit { public ruleActions = ruleActions; public ruleTriggers = ruleTriggers; @@ -69,10 +69,9 @@ export class RuleWizardComponent extends AppComponentBase implements OnInit { @Input() public mode = MODE_WIZARD; - constructor(apps: AppsStoreService, dialogs: DialogService, authService: AuthService, + constructor(public readonly ctx: AppContext, private readonly rulesService: RulesService ) { - super(dialogs, apps, authService); } public ngOnInit() { @@ -126,39 +125,36 @@ export class RuleWizardComponent extends AppComponentBase implements OnInit { private createRule() { const requestDto = new CreateRuleDto(this.trigger, this.action); - this.appNameOnce() - .switchMap(app => this.rulesService.postRule(app, requestDto, this.authService.user!.id, DateTime.now())) + this.rulesService.postRule(this.ctx.appName, requestDto, this.ctx.userToken, DateTime.now()) .subscribe(dto => { this.created.emit(dto); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } private updateTrigger() { const requestDto = new UpdateRuleDto(this.trigger, null); - this.appNameOnce() - .switchMap(app => this.rulesService.putRule(app, this.rule.id, requestDto, this.rule.version)) + this.rulesService.putRule(this.ctx.appName, this.rule.id, requestDto, this.rule.version) .subscribe(dto => { - const rule = this.rule.updateTrigger(this.trigger, this.authService.user.id, dto.version, DateTime.now()); + const rule = this.rule.updateTrigger(this.trigger, this.ctx.userToken, dto.version, DateTime.now()); this.updated.emit(rule); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } private updateAction() { const requestDto = new UpdateRuleDto(null, this.action); - this.appNameOnce() - .switchMap(app => this.rulesService.putRule(app, this.rule.id, requestDto, this.rule.version)) + this.rulesService.putRule(this.ctx.appName, this.rule.id, requestDto, this.rule.version) .subscribe(dto => { - const rule = this.rule.updateAction(this.action, this.authService.user.id, dto.version, DateTime.now()); + const rule = this.rule.updateAction(this.action, this.ctx.userToken, dto.version, DateTime.now()); this.updated.emit(rule); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } diff --git a/src/Squidex/app/features/rules/pages/rules/rules-page.component.html b/src/Squidex/app/features/rules/pages/rules/rules-page.component.html index 448ecb97e..c57303e10 100644 --- a/src/Squidex/app/features/rules/pages/rules/rules-page.component.html +++ b/src/Squidex/app/features/rules/pages/rules/rules-page.component.html @@ -1,6 +1,6 @@ - + - +
diff --git a/src/Squidex/app/features/rules/pages/rules/rules-page.component.ts b/src/Squidex/app/features/rules/pages/rules/rules-page.component.ts index 4062e78d9..62c491b82 100644 --- a/src/Squidex/app/features/rules/pages/rules/rules-page.component.ts +++ b/src/Squidex/app/features/rules/pages/rules/rules-page.component.ts @@ -8,11 +8,8 @@ import { Component, OnInit } from '@angular/core'; import { - AppComponentBase, - AppsStoreService, - AuthService, + AppContext, DateTime, - DialogService, fadeAnimation, ImmutableArray, ModalView, @@ -28,11 +25,14 @@ import { selector: 'sqx-rules-page', styleUrls: ['./rules-page.component.scss'], templateUrl: './rules-page.component.html', + providers: [ + AppContext + ], animations: [ fadeAnimation ] }) -export class RulesPageComponent extends AppComponentBase implements OnInit { +export class RulesPageComponent implements OnInit { public ruleActions = ruleActions; public ruleTriggers = ruleTriggers; @@ -44,11 +44,10 @@ export class RulesPageComponent extends AppComponentBase implements OnInit { public wizardMode = 'Wizard'; public wizardRule: RuleDto; - constructor(apps: AppsStoreService, dialogs: DialogService, authService: AuthService, + constructor(public readonly ctx: AppContext, private readonly schemasService: SchemasService, private readonly rulesService: RulesService ) { - super(dialogs, apps, authService); } public ngOnInit() { @@ -56,20 +55,17 @@ export class RulesPageComponent extends AppComponentBase implements OnInit { } public load(showInfo = false) { - this.appNameOnce() - .switchMap(app => - this.schemasService.getSchemas(app) - .combineLatest(this.rulesService.getRules(app), - (s, w) => { return { rules: w, schemas: s }; })) + this.schemasService.getSchemas(this.ctx.appName) + .combineLatest(this.rulesService.getRules(this.ctx.appName), (s, w) => { return { rules: w, schemas: s }; }) .subscribe(dtos => { this.schemas = dtos.schemas; this.rules = ImmutableArray.of(dtos.rules); if (showInfo) { - this.notifyInfo('Rules reloaded.'); + this.ctx.notifyInfo('Rules reloaded.'); } }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } @@ -108,31 +104,28 @@ export class RulesPageComponent extends AppComponentBase implements OnInit { public toggleRule(rule: RuleDto) { if (rule.isEnabled) { - this.appNameOnce() - .switchMap(app => this.rulesService.disableRule(app, rule.id, rule.version)) + this.rulesService.disableRule(this.ctx.appName, rule.id, rule.version) .subscribe(dto => { - this.rules = this.rules.replace(rule, rule.disable(this.authService.user.id, dto.version, DateTime.now())); + this.rules = this.rules.replace(rule, rule.disable(this.ctx.userToken, dto.version, DateTime.now())); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } else { - this.appNameOnce() - .switchMap(app => this.rulesService.enableRule(app, rule.id, rule.version)) + this.rulesService.enableRule(this.ctx.appName, rule.id, rule.version) .subscribe(dto => { - this.rules = this.rules.replace(rule, rule.enable(this.authService.user.id, dto.version, DateTime.now())); + this.rules = this.rules.replace(rule, rule.enable(this.ctx.userToken, dto.version, DateTime.now())); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } } public deleteRule(rule: RuleDto) { - this.appNameOnce() - .switchMap(app => this.rulesService.deleteRule(app, rule.id, rule.version)) + this.rulesService.deleteRule(this.ctx.appName, rule.id, rule.version) .subscribe(dto => { this.rules = this.rules.remove(rule); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } } diff --git a/src/Squidex/app/features/schemas/pages/schema/schema-edit-form.component.ts b/src/Squidex/app/features/schemas/pages/schema/schema-edit-form.component.ts index fd9f28897..7cf81e3b9 100644 --- a/src/Squidex/app/features/schemas/pages/schema/schema-edit-form.component.ts +++ b/src/Squidex/app/features/schemas/pages/schema/schema-edit-form.component.ts @@ -9,8 +9,7 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { FormBuilder, Validators } from '@angular/forms'; import { - ComponentBase, - DialogService, + AppContext, SchemaPropertiesDto, SchemasService, Version @@ -19,9 +18,12 @@ import { @Component({ selector: 'sqx-schema-edit-form', styleUrls: ['./schema-edit-form.component.scss'], - templateUrl: './schema-edit-form.component.html' + templateUrl: './schema-edit-form.component.html', + providers: [ + AppContext + ] }) -export class SchemaEditFormComponent extends ComponentBase implements OnInit { +export class SchemaEditFormComponent implements OnInit { @Output() public saved = new EventEmitter(); @@ -37,9 +39,6 @@ export class SchemaEditFormComponent extends ComponentBase implements OnInit { @Input() public version: Version; - @Input() - public appName: string; - public editFormSubmitted = false; public editForm = this.formBuilder.group({ @@ -53,11 +52,10 @@ export class SchemaEditFormComponent extends ComponentBase implements OnInit { ]] }); - constructor(dialogs: DialogService, + constructor(public readonly ctx: AppContext, private readonly schemas: SchemasService, private readonly formBuilder: FormBuilder ) { - super(dialogs); } public ngOnInit() { @@ -77,12 +75,12 @@ export class SchemaEditFormComponent extends ComponentBase implements OnInit { const requestDto = this.editForm.value; - this.schemas.putSchema(this.appName, this.name, requestDto, this.version) + this.schemas.putSchema(this.ctx.appName, this.name, requestDto, this.version) .subscribe(dto => { this.emitSaved(requestDto); this.resetEditForm(); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); this.enableEditForm(); }); } diff --git a/src/Squidex/app/features/schemas/pages/schema/schema-page.component.html b/src/Squidex/app/features/schemas/pages/schema/schema-page.component.html index 056a1f665..3569894ae 100644 --- a/src/Squidex/app/features/schemas/pages/schema/schema-page.component.html +++ b/src/Squidex/app/features/schemas/pages/schema/schema-page.component.html @@ -1,6 +1,6 @@ - + - +
@@ -138,7 +138,7 @@
@@ -167,7 +167,7 @@
diff --git a/src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts b/src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts index 5cbbca5d7..69d6c8955 100644 --- a/src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts +++ b/src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts @@ -7,22 +7,18 @@ import { Component, OnDestroy, OnInit } from '@angular/core'; import { FormBuilder, Validators } from '@angular/forms'; -import { ActivatedRoute, Router } from '@angular/router'; +import { Router } from '@angular/router'; import { Subscription } from 'rxjs'; import { AddFieldDto, - AppComponentBase, - AppsStoreService, - AuthService, + AppContext, createProperties, - DialogService, fadeAnimation, FieldDto, fieldTypes, HistoryChannelUpdated, ImmutableArray, - MessageBus, ModalView, SchemaDetailsDto, SchemaDto, @@ -44,11 +40,14 @@ import { selector: 'sqx-schema-page', styleUrls: ['./schema-page.component.scss'], templateUrl: './schema-page.component.html', + providers: [ + AppContext + ], animations: [ fadeAnimation ] }) -export class SchemaPageComponent extends AppComponentBase implements OnDestroy, OnInit { +export class SchemaPageComponent implements OnDestroy, OnInit { private schemaCreatedSubscription: Subscription; public fieldTypes = fieldTypes; @@ -83,14 +82,11 @@ export class SchemaPageComponent extends AppComponentBase implements OnDestroy, return this.addFieldForm.controls['name'].value && this.addFieldForm.controls['name'].value.length > 0; } - constructor(apps: AppsStoreService, dialogs: DialogService, authService: AuthService, + constructor(public readonly ctx: AppContext, private readonly formBuilder: FormBuilder, - private readonly messageBus: MessageBus, - private readonly route: ActivatedRoute, private readonly router: Router, private readonly schemasService: SchemasService ) { - super(dialogs, apps, authService); } public ngOnDestroy() { @@ -99,14 +95,14 @@ export class SchemaPageComponent extends AppComponentBase implements OnDestroy, public ngOnInit() { this.schemaCreatedSubscription = - this.messageBus.of(SchemaCreated) + this.ctx.bus.of(SchemaCreated) .subscribe(message => { if (this.schemas) { this.schemas = this.schemas.push(message.schema); } }); - this.route.data.map(p => p['schema']) + this.ctx.route.data.map(d => d.schema) .subscribe((schema: SchemaDetailsDto) => { this.schema = schema; @@ -117,125 +113,113 @@ export class SchemaPageComponent extends AppComponentBase implements OnDestroy, } private load() { - this.appNameOnce() - .switchMap(app => this.schemasService.getSchemas(app)) + this.schemasService.getSchemas(this.ctx.appName) .subscribe(dtos => { this.schemas = ImmutableArray.of(dtos); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } public publish() { - this.appNameOnce() - .switchMap(app => this.schemasService.publishSchema(app, this.schema.name, this.schema.version)).retry(2) + this.schemasService.publishSchema(this.ctx.appName, this.schema.name, this.schema.version) .subscribe(dto => { - this.updateSchema(this.schema.publish(this.userToken, dto.version)); + this.updateSchema(this.schema.publish(this.ctx.userToken, dto.version)); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } public unpublish() { - this.appNameOnce() - .switchMap(app => this.schemasService.unpublishSchema(app, this.schema.name, this.schema.version)).retry(2) + this.schemasService.unpublishSchema(this.ctx.appName, this.schema.name, this.schema.version) .subscribe(dto => { - this.updateSchema(this.schema.unpublish(this.userToken, dto.version)); + this.updateSchema(this.schema.unpublish(this.ctx.userToken, dto.version)); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } public enableField(field: FieldDto) { - this.appNameOnce() - .switchMap(app => this.schemasService.enableField(app, this.schema.name, field.fieldId, this.schema.version)).retry(2) + this.schemasService.enableField(this.ctx.appName, this.schema.name, field.fieldId, this.schema.version) .subscribe(dto => { - this.updateSchema(this.schema.updateField(field.enable(), this.userToken, dto.version)); + this.updateSchema(this.schema.updateField(field.enable(), this.ctx.userToken, dto.version)); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } public disableField(field: FieldDto) { - this.appNameOnce() - .switchMap(app => this.schemasService.disableField(app, this.schema.name, field.fieldId, this.schema.version)).retry(2) + this.schemasService.disableField(this.ctx.appName, this.schema.name, field.fieldId, this.schema.version) .subscribe(dto => { - this.updateSchema(this.schema.updateField(field.disable(), this.userToken, dto.version)); + this.updateSchema(this.schema.updateField(field.disable(), this.ctx.userToken, dto.version)); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } public lockField(field: FieldDto) { - this.appNameOnce() - .switchMap(app => this.schemasService.lockField(app, this.schema.name, field.fieldId, this.schema.version)).retry(2) + this.schemasService.lockField(this.ctx.appName, this.schema.name, field.fieldId, this.schema.version) .subscribe(dto => { - this.updateSchema(this.schema.updateField(field.lock(), this.userToken, dto.version)); + this.updateSchema(this.schema.updateField(field.lock(), this.ctx.userToken, dto.version)); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } public showField(field: FieldDto) { - this.appNameOnce() - .switchMap(app => this.schemasService.showField(app, this.schema.name, field.fieldId, this.schema.version)).retry(2) + this.schemasService.showField(this.ctx.appName, this.schema.name, field.fieldId, this.schema.version) .subscribe(dto => { - this.updateSchema(this.schema.updateField(field.show(), this.userToken, dto.version)); + this.updateSchema(this.schema.updateField(field.show(), this.ctx.userToken, dto.version)); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } public hideField(field: FieldDto) { - this.appNameOnce() - .switchMap(app => this.schemasService.hideField(app, this.schema.name, field.fieldId, this.schema.version)).retry(2) + this.schemasService.hideField(this.ctx.appName, this.schema.name, field.fieldId, this.schema.version) .subscribe(dto => { - this.updateSchema(this.schema.updateField(field.hide(), this.userToken, dto.version)); + this.updateSchema(this.schema.updateField(field.hide(), this.ctx.userToken, dto.version)); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } public deleteField(field: FieldDto) { - this.appNameOnce() - .switchMap(app => this.schemasService.deleteField(app, this.schema.name, field.fieldId, this.schema.version)).retry(2) + this.schemasService.deleteField(this.ctx.appName, this.schema.name, field.fieldId, this.schema.version) .subscribe(dto => { - this.updateSchema(this.schema.removeField(field, this.userToken, dto.version)); + this.updateSchema(this.schema.removeField(field, this.ctx.userToken, dto.version)); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } public sortFields(fields: FieldDto[]) { - this.appNameOnce() - .switchMap(app => this.schemasService.putFieldOrdering(app, this.schema.name, fields.map(t => t.fieldId), this.schema.version)).retry(2) + this.schemasService.putFieldOrdering(this.ctx.appName, this.schema.name, fields.map(t => t.fieldId), this.schema.version) .subscribe(dto => { - this.updateSchema(this.schema.replaceFields(fields, this.userToken, dto.version)); + this.updateSchema(this.schema.replaceFields(fields, this.ctx.userToken, dto.version)); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } public saveField(field: FieldDto) { const requestDto = new UpdateFieldDto(field.properties); - this.appNameOnce() - .switchMap(app => this.schemasService.putField(app, this.schema.name, field.fieldId, requestDto, this.schema.version)).retry(2) + this.schemasService.putField(this.ctx.appName, this.schema.name, field.fieldId, requestDto, this.schema.version) .subscribe(dto => { - this.updateSchema(this.schema.updateField(field, this.userToken, dto.version)); + this.updateSchema(this.schema.updateField(field, this.ctx.userToken, dto.version)); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } public deleteSchema() { - this.appNameOnce() - .switchMap(app => this.schemasService.deleteSchema(app, this.schema.name, this.schema.version)).retry(2) + this.schemasService.deleteSchema(this.ctx.appName, this.schema.name, this.schema.version) .subscribe(() => { this.onSchemaRemoved(this.schema); this.back(); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); }); } @@ -250,13 +234,12 @@ export class SchemaPageComponent extends AppComponentBase implements OnDestroy, const requestDto = new AddFieldDto(this.addFieldForm.controls['name'].value, partitioning, properties); - this.appNameOnce() - .switchMap(app => this.schemasService.postField(app, this.schema.name, requestDto, this.schema.version)) + this.schemasService.postField(this.ctx.appName, this.schema.name, requestDto, this.schema.version) .subscribe(dto => { - this.updateSchema(this.schema.addField(dto.payload, this.userToken, dto.version)); + this.updateSchema(this.schema.addField(dto.payload, this.ctx.userToken, dto.version)); this.resetFieldForm(); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); this.resetFieldForm(); }); } @@ -267,13 +250,13 @@ export class SchemaPageComponent extends AppComponentBase implements OnDestroy, } public onSchemaSaved(properties: SchemaPropertiesDto, version: Version) { - this.updateSchema(this.schema.update(properties, this.userToken, version)); + this.updateSchema(this.schema.update(properties, this.ctx.userToken, version)); this.editSchemaDialog.hide(); } public onSchemaScriptsSaved(scripts: UpdateSchemaScriptsDto, version: Version) { - this.updateSchema(this.schema.configureScripts(scripts, this.userToken, version)); + this.updateSchema(this.schema.configureScripts(scripts, this.ctx.userToken, version)); this.configureScriptsDialog.hide(); } @@ -295,7 +278,7 @@ export class SchemaPageComponent extends AppComponentBase implements OnDestroy, this.schemas = this.schemas.replaceBy('id', schema); this.emitSchemaUpdated(schema); - this.notify(); + this.emitHistoryUpdate(); this.export(); } @@ -331,19 +314,19 @@ export class SchemaPageComponent extends AppComponentBase implements OnDestroy, } private back() { - this.router.navigate(['../'], { relativeTo: this.route }); + this.router.navigate(['../'], { relativeTo: this.ctx.route }); } private emitSchemaDeleted(schema: SchemaDto) { - this.messageBus.emit(new SchemaDeleted(schema)); + this.ctx.bus.emit(new SchemaDeleted(schema)); } private emitSchemaUpdated(schema: SchemaDto) { - this.messageBus.emit(new SchemaUpdated(schema)); + this.ctx.bus.emit(new SchemaUpdated(schema)); } - private notify() { - this.messageBus.emit(new HistoryChannelUpdated()); + private emitHistoryUpdate() { + this.ctx.bus.emit(new HistoryChannelUpdated()); } } diff --git a/src/Squidex/app/features/schemas/pages/schema/schema-scripts-form.component.ts b/src/Squidex/app/features/schemas/pages/schema/schema-scripts-form.component.ts index 5d5c602f8..d9315eba1 100644 --- a/src/Squidex/app/features/schemas/pages/schema/schema-scripts-form.component.ts +++ b/src/Squidex/app/features/schemas/pages/schema/schema-scripts-form.component.ts @@ -9,8 +9,7 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { FormBuilder } from '@angular/forms'; import { - ComponentBase, - DialogService, + AppContext, SchemaDetailsDto, SchemasService, UpdateSchemaScriptsDto @@ -19,9 +18,12 @@ import { @Component({ selector: 'sqx-schema-scripts-form', styleUrls: ['./schema-scripts-form.component.scss'], - templateUrl: './schema-scripts-form.component.html' + templateUrl: './schema-scripts-form.component.html', + providers: [ + AppContext + ] }) -export class SchemaScriptsFormComponent extends ComponentBase implements OnInit { +export class SchemaScriptsFormComponent implements OnInit { @Output() public saved = new EventEmitter(); @@ -31,9 +33,6 @@ export class SchemaScriptsFormComponent extends ComponentBase implements OnInit @Input() public schema: SchemaDetailsDto; - @Input() - public appName: string; - public selectedField = 'scriptQuery'; public scripts = [ @@ -54,11 +53,10 @@ export class SchemaScriptsFormComponent extends ComponentBase implements OnInit scriptChange: '' }); - constructor(dialogs: DialogService, + constructor(public readonly ctx: AppContext, private readonly schemas: SchemasService, private readonly formBuilder: FormBuilder ) { - super(dialogs); } public ngOnInit() { @@ -84,12 +82,12 @@ export class SchemaScriptsFormComponent extends ComponentBase implements OnInit this.editForm.controls['scriptDelete'].value, this.editForm.controls['scriptChange'].value); - this.schemas.putSchemaScripts(this.appName, this.schema.name, requestDto, this.schema.version) + this.schemas.putSchemaScripts(this.ctx.appName, this.schema.name, requestDto, this.schema.version) .subscribe(dto => { this.emitSaved(requestDto); this.resetEditForm(); }, error => { - this.notifyError(error); + this.ctx.notifyError(error); this.enableEditForm(); }); } diff --git a/src/Squidex/app/features/schemas/pages/schemas/schemas-page.component.html b/src/Squidex/app/features/schemas/pages/schemas/schemas-page.component.html index 05c321f29..39ce9a103 100644 --- a/src/Squidex/app/features/schemas/pages/schemas/schemas-page.component.html +++ b/src/Squidex/app/features/schemas/pages/schemas/schemas-page.component.html @@ -1,6 +1,6 @@ - + - +

Schemas

@@ -66,7 +66,7 @@