Browse Source

DialogService and NotificationService unified

pull/100/head
Sebastian Stehle 9 years ago
parent
commit
35150fda81
  1. 8
      src/Squidex/app/features/administration/pages/event-consumers/event-consumers-page.component.ts
  2. 6
      src/Squidex/app/features/administration/pages/users/user-page.component.ts
  3. 6
      src/Squidex/app/features/administration/pages/users/users-page.component.ts
  4. 6
      src/Squidex/app/features/api/api-area.component.ts
  5. 8
      src/Squidex/app/features/api/pages/graphql/graphql-page.component.ts
  6. 6
      src/Squidex/app/features/assets/pages/assets-page.component.ts
  7. 6
      src/Squidex/app/features/content/pages/content/content-page.component.ts
  8. 6
      src/Squidex/app/features/content/pages/contents/contents-page.component.ts
  9. 6
      src/Squidex/app/features/content/pages/schemas/schemas-page.component.ts
  10. 8
      src/Squidex/app/features/content/shared/assets-editor.component.ts
  11. 6
      src/Squidex/app/features/content/shared/content-item.component.ts
  12. 6
      src/Squidex/app/features/content/shared/references-editor.component.ts
  13. 6
      src/Squidex/app/features/dashboard/pages/dashboard-page.component.ts
  14. 6
      src/Squidex/app/features/schemas/pages/schema/schema-edit-form.component.ts
  15. 2
      src/Squidex/app/features/schemas/pages/schema/schema-page.component.html
  16. 6
      src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts
  17. 6
      src/Squidex/app/features/schemas/pages/schemas/schemas-page.component.ts
  18. 8
      src/Squidex/app/features/settings/pages/clients/client.component.ts
  19. 6
      src/Squidex/app/features/settings/pages/clients/clients-page.component.ts
  20. 6
      src/Squidex/app/features/settings/pages/contributors/contributors-page.component.ts
  21. 6
      src/Squidex/app/features/settings/pages/languages/languages-page.component.ts
  22. 6
      src/Squidex/app/features/settings/pages/plans/plans-page.component.ts
  23. 6
      src/Squidex/app/features/settings/settings-area.component.ts
  24. 6
      src/Squidex/app/features/webhooks/pages/webhook-events-page.component.ts
  25. 6
      src/Squidex/app/features/webhooks/pages/webhooks-page.component.ts
  26. 53
      src/Squidex/app/framework/angular/confirm-click.directive.ts
  27. 6
      src/Squidex/app/framework/angular/copy.directive.ts
  28. 27
      src/Squidex/app/framework/angular/dialog-renderer.component.html
  29. 28
      src/Squidex/app/framework/angular/dialog-renderer.component.scss
  30. 92
      src/Squidex/app/framework/angular/dialog-renderer.component.ts
  31. 2
      src/Squidex/app/framework/angular/root-view.directive.ts
  32. 4
      src/Squidex/app/framework/declarations.ts
  33. 10
      src/Squidex/app/framework/module.ts
  34. 94
      src/Squidex/app/framework/services/dialog.service.spec.ts
  35. 38
      src/Squidex/app/framework/services/dialog.service.ts
  36. 3
      src/Squidex/app/framework/services/local-cache.service.ts
  37. 57
      src/Squidex/app/framework/services/notification.service.spec.ts
  38. 3
      src/Squidex/app/framework/services/resource-loader.service.ts
  39. 6
      src/Squidex/app/shared/components/app.component-base.ts
  40. 6
      src/Squidex/app/shared/components/asset.component.ts
  41. 12
      src/Squidex/app/shared/components/component-base.ts
  42. 6
      src/Squidex/app/shared/components/history.component.ts
  43. 9
      src/Squidex/app/shell/pages/internal/internal-area.component.html
  44. 9
      src/Squidex/app/shell/pages/internal/internal-area.component.scss
  45. 34
      src/Squidex/app/shell/pages/internal/internal-area.component.ts

8
src/Squidex/app/features/administration/pages/event-consumers/event-consumers-page.component.ts

@ -10,12 +10,12 @@ import { Observable, Subscription } from 'rxjs';
import { import {
ComponentBase, ComponentBase,
DialogService,
EventConsumerDto, EventConsumerDto,
EventConsumersService, EventConsumersService,
fadeAnimation, fadeAnimation,
ImmutableArray, ImmutableArray,
ModalView, ModalView
NotificationService
} from 'shared'; } from 'shared';
@Component({ @Component({
@ -33,10 +33,10 @@ export class EventConsumersPageComponent extends ComponentBase implements OnInit
public eventConsumerError = ''; public eventConsumerError = '';
public eventConsumers = ImmutableArray.empty<EventConsumerDto>(); public eventConsumers = ImmutableArray.empty<EventConsumerDto>();
constructor(notifications: NotificationService, constructor(dialogs: DialogService,
private readonly eventConsumersService: EventConsumersService private readonly eventConsumersService: EventConsumersService
) { ) {
super(notifications); super(dialogs);
} }
public ngOnInit() { public ngOnInit() {

6
src/Squidex/app/features/administration/pages/users/user-page.component.ts

@ -12,8 +12,8 @@ import { ActivatedRoute, Router } from '@angular/router';
import { import {
AuthService, AuthService,
ComponentBase, ComponentBase,
DialogService,
MessageBus, MessageBus,
NotificationService,
UserDto, UserDto,
UserManagementService, UserManagementService,
ValidatorsEx ValidatorsEx
@ -38,7 +38,7 @@ export class UserPageComponent extends ComponentBase implements OnInit {
public isCurrentUser = false; public isCurrentUser = false;
public isNewMode = false; public isNewMode = false;
constructor(notifications: NotificationService, constructor(dialogs: DialogService,
private readonly authService: AuthService, private readonly authService: AuthService,
private readonly formBuilder: FormBuilder, private readonly formBuilder: FormBuilder,
private readonly messageBus: MessageBus, private readonly messageBus: MessageBus,
@ -46,7 +46,7 @@ export class UserPageComponent extends ComponentBase implements OnInit {
private readonly router: Router, private readonly router: Router,
private readonly userManagementService: UserManagementService private readonly userManagementService: UserManagementService
) { ) {
super(notifications); super(dialogs);
} }
public ngOnInit() { public ngOnInit() {

6
src/Squidex/app/features/administration/pages/users/users-page.component.ts

@ -12,9 +12,9 @@ import { Subscription } from 'rxjs';
import { import {
AuthService, AuthService,
ComponentBase, ComponentBase,
DialogService,
ImmutableArray, ImmutableArray,
MessageBus, MessageBus,
NotificationService,
Pager, Pager,
UserDto, UserDto,
UserManagementService UserManagementService
@ -38,12 +38,12 @@ export class UsersPageComponent extends ComponentBase implements OnDestroy, OnIn
public usersFilter = new FormControl(); public usersFilter = new FormControl();
public usersQuery = ''; public usersQuery = '';
constructor(notifications: NotificationService, constructor(dialogs: DialogService,
private readonly userManagementService: UserManagementService, private readonly userManagementService: UserManagementService,
private readonly authService: AuthService, private readonly authService: AuthService,
private readonly messageBus: MessageBus private readonly messageBus: MessageBus
) { ) {
super(notifications); super(dialogs);
} }
public ngOnDestroy() { public ngOnDestroy() {

6
src/Squidex/app/features/api/api-area.component.ts

@ -10,7 +10,7 @@ import { Component } from '@angular/core';
import { import {
AppComponentBase, AppComponentBase,
AppsStoreService, AppsStoreService,
NotificationService DialogService
} from 'shared'; } from 'shared';
@Component({ @Component({
@ -19,8 +19,8 @@ import {
templateUrl: './api-area.component.html' templateUrl: './api-area.component.html'
}) })
export class ApiAreaComponent extends AppComponentBase { export class ApiAreaComponent extends AppComponentBase {
constructor(apps: AppsStoreService, notifications: NotificationService constructor(apps: AppsStoreService, dialogs: DialogService
) { ) {
super(notifications, apps); super(dialogs, apps);
} }
} }

8
src/Squidex/app/features/api/pages/graphql/graphql-page.component.ts

@ -18,9 +18,9 @@ const GraphiQL = require('graphiql');
import { import {
AppComponentBase, AppComponentBase,
AppsStoreService, AppsStoreService,
DialogService,
GraphQlService, GraphQlService,
LocalStoreService, LocalStoreService
NotificationService
} from 'shared'; } from 'shared';
@Component({ @Component({
@ -33,11 +33,11 @@ export class GraphQLPageComponent extends AppComponentBase implements OnInit {
@ViewChild('graphiQLContainer') @ViewChild('graphiQLContainer')
public graphiQLContainer: ElementRef; public graphiQLContainer: ElementRef;
constructor(apps: AppsStoreService, notifications: NotificationService, constructor(apps: AppsStoreService, dialogs: DialogService,
private readonly graphQlService: GraphQlService, private readonly graphQlService: GraphQlService,
private readonly localStoreService: LocalStoreService private readonly localStoreService: LocalStoreService
) { ) {
super(notifications, apps); super(dialogs, apps);
} }
public ngOnInit() { public ngOnInit() {

6
src/Squidex/app/features/assets/pages/assets-page.component.ts

@ -17,9 +17,9 @@ import {
AssetDto, AssetDto,
AssetsService, AssetsService,
AssetUpdated, AssetUpdated,
DialogService,
ImmutableArray, ImmutableArray,
MessageBus, MessageBus,
NotificationService,
Pager Pager
} from 'shared'; } from 'shared';
@ -38,11 +38,11 @@ export class AssetsPageComponent extends AppComponentBase implements OnDestroy,
public assetsFilter = new FormControl(); public assetsFilter = new FormControl();
public assertQuery = ''; public assertQuery = '';
constructor(apps: AppsStoreService, notifications: NotificationService, constructor(apps: AppsStoreService, dialogs: DialogService,
private readonly assetsService: AssetsService, private readonly assetsService: AssetsService,
private readonly messageBus: MessageBus private readonly messageBus: MessageBus
) { ) {
super(notifications, apps); super(dialogs, apps);
} }
public ngOnInit() { public ngOnInit() {

6
src/Squidex/app/features/content/pages/content/content-page.component.ts

@ -25,10 +25,10 @@ import {
CanComponentDeactivate, CanComponentDeactivate,
ContentDto, ContentDto,
ContentsService, ContentsService,
DialogService,
fadeAnimation, fadeAnimation,
ModalView, ModalView,
MessageBus, MessageBus,
NotificationService,
SchemaDetailsDto, SchemaDetailsDto,
Version Version
} from 'shared'; } from 'shared';
@ -59,14 +59,14 @@ export class ContentPageComponent extends AppComponentBase implements CanCompone
public languages: AppLanguageDto[] = []; public languages: AppLanguageDto[] = [];
constructor(apps: AppsStoreService, notifications: NotificationService, constructor(apps: AppsStoreService, dialogs: DialogService,
private readonly authService: AuthService, private readonly authService: AuthService,
private readonly contentsService: ContentsService, private readonly contentsService: ContentsService,
private readonly route: ActivatedRoute, private readonly route: ActivatedRoute,
private readonly router: Router, private readonly router: Router,
private readonly messageBus: MessageBus private readonly messageBus: MessageBus
) { ) {
super(notifications, apps); super(dialogs, apps);
} }
public ngOnDestroy() { public ngOnDestroy() {

6
src/Squidex/app/features/content/pages/contents/contents-page.component.ts

@ -24,10 +24,10 @@ import {
AuthService, AuthService,
ContentDto, ContentDto,
ContentsService, ContentsService,
DialogService,
FieldDto, FieldDto,
ImmutableArray, ImmutableArray,
MessageBus, MessageBus,
NotificationService,
Pager, Pager,
SchemaDetailsDto SchemaDetailsDto
} from 'shared'; } from 'shared';
@ -57,13 +57,13 @@ export class ContentsPageComponent extends AppComponentBase implements OnDestroy
public columnWidth: number; public columnWidth: number;
constructor(apps: AppsStoreService, notifications: NotificationService, constructor(apps: AppsStoreService, dialogs: DialogService,
private readonly authService: AuthService, private readonly authService: AuthService,
private readonly contentsService: ContentsService, private readonly contentsService: ContentsService,
private readonly route: ActivatedRoute, private readonly route: ActivatedRoute,
private readonly messageBus: MessageBus private readonly messageBus: MessageBus
) { ) {
super(notifications, apps); super(dialogs, apps);
} }
public ngOnDestroy() { public ngOnDestroy() {

6
src/Squidex/app/features/content/pages/schemas/schemas-page.component.ts

@ -12,7 +12,7 @@ import { Observable } from 'rxjs';
import { import {
AppComponentBase, AppComponentBase,
AppsStoreService, AppsStoreService,
NotificationService, DialogService,
SchemaDto, SchemaDto,
SchemasService SchemasService
} from 'shared'; } from 'shared';
@ -52,10 +52,10 @@ export class SchemasPageComponent extends AppComponentBase {
}); });
}); });
constructor(apps: AppsStoreService, notifications: NotificationService, constructor(apps: AppsStoreService, dialogs: DialogService,
private readonly schemasService: SchemasService private readonly schemasService: SchemasService
) { ) {
super(notifications, apps); super(dialogs, apps);
} }
private loadSchemas(): Observable<SchemaDto[]> { private loadSchemas(): Observable<SchemaDto[]> {

8
src/Squidex/app/features/content/shared/assets-editor.component.ts

@ -17,9 +17,9 @@ import {
AssetDto, AssetDto,
AssetsService, AssetsService,
AssetUpdated, AssetUpdated,
DialogService,
ImmutableArray, ImmutableArray,
MessageBus, MessageBus
NotificationService
} from 'shared'; } from 'shared';
const NOOP = () => { /* NOOP */ }; const NOOP = () => { /* NOOP */ };
@ -44,11 +44,11 @@ export class AssetsEditorComponent extends AppComponentBase implements ControlVa
public isDisabled = false; public isDisabled = false;
constructor(apps: AppsStoreService, notifications: NotificationService, constructor(apps: AppsStoreService, dialogs: DialogService,
private readonly assetsService: AssetsService, private readonly assetsService: AssetsService,
private readonly messageBus: MessageBus private readonly messageBus: MessageBus
) { ) {
super(notifications, apps); super(dialogs, apps);
} }
public ngOnInit() { public ngOnInit() {

6
src/Squidex/app/features/content/shared/content-item.component.ts

@ -11,10 +11,10 @@ import {
AppComponentBase, AppComponentBase,
AppsStoreService, AppsStoreService,
ContentDto, ContentDto,
DialogService,
fadeAnimation, fadeAnimation,
FieldDto, FieldDto,
ModalView, ModalView,
NotificationService,
SchemaDto SchemaDto
} from 'shared'; } from 'shared';
@ -60,8 +60,8 @@ export class ContentItemComponent extends AppComponentBase implements OnInit, On
public values: any[] = []; public values: any[] = [];
constructor(apps: AppsStoreService, notifications: NotificationService) { constructor(apps: AppsStoreService, dialogs: DialogService) {
super(notifications, apps); super(dialogs, apps);
} }
public ngOnChanges() { public ngOnChanges() {

6
src/Squidex/app/features/content/shared/references-editor.component.ts

@ -15,9 +15,9 @@ import {
AppsStoreService, AppsStoreService,
ContentDto, ContentDto,
ContentsService, ContentsService,
DialogService,
FieldDto, FieldDto,
ImmutableArray, ImmutableArray,
NotificationService,
SchemaDetailsDto, SchemaDetailsDto,
SchemasService SchemasService
} from 'shared'; } from 'shared';
@ -54,11 +54,11 @@ export class ReferencesEditorComponent extends AppComponentBase implements Contr
public isDisabled = false; public isDisabled = false;
public isInvalidSchema = false; public isInvalidSchema = false;
constructor(apps: AppsStoreService, notifications: NotificationService, constructor(apps: AppsStoreService, dialogs: DialogService,
private readonly contentsService: ContentsService, private readonly contentsService: ContentsService,
private readonly schemasService: SchemasService private readonly schemasService: SchemasService
) { ) {
super(notifications, apps); super(dialogs, apps);
} }
public ngOnInit() { public ngOnInit() {

6
src/Squidex/app/features/dashboard/pages/dashboard-page.component.ts

@ -12,8 +12,8 @@ import {
AppsStoreService, AppsStoreService,
AuthService, AuthService,
DateTime, DateTime,
DialogService,
fadeAnimation, fadeAnimation,
NotificationService,
UsagesService UsagesService
} from 'shared'; } from 'shared';
@ -60,11 +60,11 @@ export class DashboardPageComponent extends AppComponentBase implements OnInit {
public callsCurrent = 0; public callsCurrent = 0;
public callsMax = 0; public callsMax = 0;
constructor(apps: AppsStoreService, notifications: NotificationService, constructor(apps: AppsStoreService, dialogs: DialogService,
private readonly authService: AuthService, private readonly authService: AuthService,
private readonly usagesService: UsagesService private readonly usagesService: UsagesService
) { ) {
super(notifications, apps); super(dialogs, apps);
} }
public ngOnInit() { public ngOnInit() {

6
src/Squidex/app/features/schemas/pages/schema/schema-edit-form.component.ts

@ -10,7 +10,7 @@ import { FormBuilder, Validators } from '@angular/forms';
import { import {
ComponentBase, ComponentBase,
NotificationService, DialogService,
SchemaPropertiesDto, SchemaPropertiesDto,
SchemasService, SchemasService,
Version Version
@ -53,11 +53,11 @@ export class SchemaEditFormComponent extends ComponentBase implements OnInit {
]] ]]
}); });
constructor(notifications: NotificationService, constructor(dialogs: DialogService,
private readonly schemas: SchemasService, private readonly schemas: SchemasService,
private readonly formBuilder: FormBuilder private readonly formBuilder: FormBuilder
) { ) {
super(notifications); super(dialogs);
} }
public ngOnInit() { public ngOnInit() {

2
src/Squidex/app/features/schemas/pages/schema/schema-page.component.html

@ -22,7 +22,7 @@
<i class="icon-dots"></i> <i class="icon-dots"></i>
</button> </button>
<div class="dropdown-menu" *sqxModalView="editOptionsDropdown" closeAlways="true" [sqxModalTarget]="optionsButton" position="right" [@fade]> <div class="dropdown-menu" *sqxModalView="editOptionsDropdown" closeAlways="true" [sqxModalTarget]="optionsButton" position="right" [@fade]>
<a class="dropdown-item dropdown-item-delete" (click)="confirmDeleteDialog.show()"> <a class="dropdown-item dropdown-item-delete" (sqxConfirmClick)="deleteSchema()" confirmTitle="Delete schema" confirmText="Do you really want to delete the schema?">
Delete Delete
</a> </a>
</div> </div>

6
src/Squidex/app/features/schemas/pages/schema/schema-page.component.ts

@ -15,13 +15,13 @@ import {
AppsStoreService, AppsStoreService,
AuthService, AuthService,
createProperties, createProperties,
DialogService,
fadeAnimation, fadeAnimation,
FieldDto, FieldDto,
fieldTypes, fieldTypes,
HistoryChannelUpdated, HistoryChannelUpdated,
MessageBus, MessageBus,
ModalView, ModalView,
NotificationService,
SchemaDetailsDto, SchemaDetailsDto,
SchemaDto, SchemaDto,
SchemaPropertiesDto, SchemaPropertiesDto,
@ -73,7 +73,7 @@ export class SchemaPageComponent extends AppComponentBase implements OnInit {
return this.addFieldForm.controls['name'].value && this.addFieldForm.controls['name'].value.length > 0; return this.addFieldForm.controls['name'].value && this.addFieldForm.controls['name'].value.length > 0;
} }
constructor(apps: AppsStoreService, notifications: NotificationService, constructor(apps: AppsStoreService, dialogs: DialogService,
private readonly authService: AuthService, private readonly authService: AuthService,
private readonly formBuilder: FormBuilder, private readonly formBuilder: FormBuilder,
private readonly messageBus: MessageBus, private readonly messageBus: MessageBus,
@ -81,7 +81,7 @@ export class SchemaPageComponent extends AppComponentBase implements OnInit {
private readonly router: Router, private readonly router: Router,
private readonly schemasService: SchemasService private readonly schemasService: SchemasService
) { ) {
super(notifications, apps); super(dialogs, apps);
} }
public ngOnInit() { public ngOnInit() {

6
src/Squidex/app/features/schemas/pages/schemas/schemas-page.component.ts

@ -13,11 +13,11 @@ import { Subscription } from 'rxjs';
import { import {
AppComponentBase, AppComponentBase,
AppsStoreService, AppsStoreService,
DialogService,
fadeAnimation, fadeAnimation,
ImmutableArray, ImmutableArray,
MessageBus, MessageBus,
ModalView, ModalView,
NotificationService,
SchemaDto, SchemaDto,
SchemasService SchemasService
} from 'shared'; } from 'shared';
@ -43,12 +43,12 @@ export class SchemasPageComponent extends AppComponentBase implements OnDestroy,
public schemasFilter = new FormControl(); public schemasFilter = new FormControl();
public schemasFiltered = ImmutableArray.empty<SchemaDto>(); public schemasFiltered = ImmutableArray.empty<SchemaDto>();
constructor(apps: AppsStoreService, notifications: NotificationService, constructor(apps: AppsStoreService, dialogs: DialogService,
private readonly schemasService: SchemasService, private readonly schemasService: SchemasService,
private readonly messageBus: MessageBus, private readonly messageBus: MessageBus,
private readonly route: ActivatedRoute private readonly route: ActivatedRoute
) { ) {
super(notifications, apps); super(dialogs, apps);
} }
public ngOnDestroy() { public ngOnDestroy() {

8
src/Squidex/app/features/settings/pages/clients/client.component.ts

@ -13,9 +13,9 @@ import {
AppClientDto, AppClientDto,
AppClientsService, AppClientsService,
ComponentBase, ComponentBase,
DialogService,
fadeAnimation, fadeAnimation,
ModalView, ModalView
NotificationService
} from 'shared'; } from 'shared';
const ESCAPE_KEY = 27; const ESCAPE_KEY = 27;
@ -60,11 +60,11 @@ export class ClientComponent extends ComponentBase {
return this.renameForm.controls['name'].value !== this.client.name; return this.renameForm.controls['name'].value !== this.client.name;
} }
constructor(notifications: NotificationService, constructor(dialogs: DialogService,
private readonly appClientsService: AppClientsService, private readonly appClientsService: AppClientsService,
private readonly formBuilder: FormBuilder private readonly formBuilder: FormBuilder
) { ) {
super(notifications); super(dialogs);
} }
public cancelRename() { public cancelRename() {

6
src/Squidex/app/features/settings/pages/clients/clients-page.component.ts

@ -14,10 +14,10 @@ import {
AppComponentBase, AppComponentBase,
AppsStoreService, AppsStoreService,
CreateAppClientDto, CreateAppClientDto,
DialogService,
HistoryChannelUpdated, HistoryChannelUpdated,
ImmutableArray, ImmutableArray,
MessageBus, MessageBus,
NotificationService,
UpdateAppClientDto, UpdateAppClientDto,
ValidatorsEx, ValidatorsEx,
Version Version
@ -47,12 +47,12 @@ export class ClientsPageComponent extends AppComponentBase implements OnInit {
return this.addClientForm.controls['name'].value && this.addClientForm.controls['name'].value.length > 0; return this.addClientForm.controls['name'].value && this.addClientForm.controls['name'].value.length > 0;
} }
constructor(apps: AppsStoreService, notifications: NotificationService, constructor(apps: AppsStoreService, dialogs: DialogService,
private readonly appClientsService: AppClientsService, private readonly appClientsService: AppClientsService,
private readonly messageBus: MessageBus, private readonly messageBus: MessageBus,
private readonly formBuilder: FormBuilder private readonly formBuilder: FormBuilder
) { ) {
super(notifications, apps); super(dialogs, apps);
} }
public ngOnInit() { public ngOnInit() {

6
src/Squidex/app/features/settings/pages/contributors/contributors-page.component.ts

@ -17,10 +17,10 @@ import {
AppsStoreService, AppsStoreService,
AuthService, AuthService,
AutocompleteSource, AutocompleteSource,
DialogService,
HistoryChannelUpdated, HistoryChannelUpdated,
ImmutableArray, ImmutableArray,
MessageBus, MessageBus,
NotificationService,
UsersService, UsersService,
Version Version
} from 'shared'; } from 'shared';
@ -81,13 +81,13 @@ export class ContributorsPageComponent extends AppComponentBase implements OnIni
]] ]]
}); });
constructor(apps: AppsStoreService, notifications: NotificationService, usersService: UsersService, constructor(apps: AppsStoreService, dialogs: DialogService, usersService: UsersService,
private readonly appContributorsService: AppContributorsService, private readonly appContributorsService: AppContributorsService,
private readonly messageBus: MessageBus, private readonly messageBus: MessageBus,
private readonly authService: AuthService, private readonly authService: AuthService,
private readonly formBuilder: FormBuilder private readonly formBuilder: FormBuilder
) { ) {
super(notifications, apps); super(dialogs, apps);
this.usersDataSource = new UsersDataSource(usersService, this); this.usersDataSource = new UsersDataSource(usersService, this);
} }

6
src/Squidex/app/features/settings/pages/languages/languages-page.component.ts

@ -14,12 +14,12 @@ import {
AppLanguageDto, AppLanguageDto,
AppLanguagesService, AppLanguagesService,
AppsStoreService, AppsStoreService,
DialogService,
HistoryChannelUpdated, HistoryChannelUpdated,
ImmutableArray, ImmutableArray,
MessageBus, MessageBus,
LanguageDto, LanguageDto,
LanguagesService, LanguagesService,
NotificationService,
Version Version
} from 'shared'; } from 'shared';
@ -42,13 +42,13 @@ export class LanguagesPageComponent extends AppComponentBase implements OnInit {
] ]
}); });
constructor(apps: AppsStoreService, notifications: NotificationService, constructor(apps: AppsStoreService, dialogs: DialogService,
private readonly appLanguagesService: AppLanguagesService, private readonly appLanguagesService: AppLanguagesService,
private readonly languagesService: LanguagesService, private readonly languagesService: LanguagesService,
private readonly messageBus: MessageBus, private readonly messageBus: MessageBus,
private readonly formBuilder: FormBuilder private readonly formBuilder: FormBuilder
) { ) {
super(notifications, apps); super(dialogs, apps);
} }
public ngOnInit() { public ngOnInit() {

6
src/Squidex/app/features/settings/pages/plans/plans-page.component.ts

@ -16,7 +16,7 @@ import {
AppsStoreService, AppsStoreService,
AuthService, AuthService,
ChangePlanDto, ChangePlanDto,
NotificationService, DialogService,
PlansService, PlansService,
Version Version
} from 'shared'; } from 'shared';
@ -38,13 +38,13 @@ export class PlansPageComponent extends AppComponentBase implements OnDestroy, O
public isDisabled = false; public isDisabled = false;
constructor(apps: AppsStoreService, notifications: NotificationService, constructor(apps: AppsStoreService, dialogs: DialogService,
private readonly authService: AuthService, private readonly authService: AuthService,
private readonly plansService: PlansService, private readonly plansService: PlansService,
private readonly route: ActivatedRoute, private readonly route: ActivatedRoute,
private readonly apiUrl: ApiUrlConfig private readonly apiUrl: ApiUrlConfig
) { ) {
super(notifications, apps); super(dialogs, apps);
} }
public ngOnDestroy() { public ngOnDestroy() {

6
src/Squidex/app/features/settings/settings-area.component.ts

@ -10,7 +10,7 @@ import { Component } from '@angular/core';
import { import {
AppComponentBase, AppComponentBase,
AppsStoreService, AppsStoreService,
NotificationService DialogService
} from 'shared'; } from 'shared';
@Component({ @Component({
@ -19,8 +19,8 @@ import {
templateUrl: './settings-area.component.html' templateUrl: './settings-area.component.html'
}) })
export class SettingsAreaComponent extends AppComponentBase { export class SettingsAreaComponent extends AppComponentBase {
constructor(apps: AppsStoreService, notifications: NotificationService constructor(apps: AppsStoreService, dialogs: DialogService
) { ) {
super(notifications, apps); super(dialogs, apps);
} }
} }

6
src/Squidex/app/features/webhooks/pages/webhook-events-page.component.ts

@ -10,8 +10,8 @@ import { Component, OnInit } from '@angular/core';
import { import {
AppComponentBase, AppComponentBase,
AppsStoreService, AppsStoreService,
DialogService,
ImmutableArray, ImmutableArray,
NotificationService,
Pager, Pager,
WebhookEventDto, WebhookEventDto,
WebhooksService WebhooksService
@ -28,10 +28,10 @@ export class WebhookEventsPageComponent extends AppComponentBase implements OnIn
public selectedEventId: string; public selectedEventId: string;
constructor(notifications: NotificationService, appsStore: AppsStoreService, constructor(dialogs: DialogService, appsStore: AppsStoreService,
private readonly webhooksService: WebhooksService private readonly webhooksService: WebhooksService
) { ) {
super(notifications, appsStore); super(dialogs, appsStore);
} }
public ngOnInit() { public ngOnInit() {

6
src/Squidex/app/features/webhooks/pages/webhooks-page.component.ts

@ -12,8 +12,8 @@ import {
AppComponentBase, AppComponentBase,
AppsStoreService, AppsStoreService,
CreateWebhookDto, CreateWebhookDto,
DialogService,
ImmutableArray, ImmutableArray,
NotificationService,
SchemaDto, SchemaDto,
SchemasService, SchemasService,
Version, Version,
@ -52,12 +52,12 @@ export class WebhooksPageComponent extends AppComponentBase implements OnInit {
return this.addWebhookForm.controls['url'].value && this.addWebhookForm.controls['url'].value.length > 0; return this.addWebhookForm.controls['url'].value && this.addWebhookForm.controls['url'].value.length > 0;
} }
constructor(apps: AppsStoreService, notifications: NotificationService, constructor(apps: AppsStoreService, dialogs: DialogService,
private readonly schemasService: SchemasService, private readonly schemasService: SchemasService,
private readonly webhooksService: WebhooksService, private readonly webhooksService: WebhooksService,
private readonly formBuilder: FormBuilder private readonly formBuilder: FormBuilder
) { ) {
super(notifications, apps); super(dialogs, apps);
} }
public ngOnInit() { public ngOnInit() {

53
src/Squidex/app/framework/angular/confirm-click.directive.ts

@ -0,0 +1,53 @@
/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Sebastian Stehle. All rights reserved
*/
import { Directive, EventEmitter, HostListener, Input, Output } from '@angular/core';
import { DialogService } from './../services/dialog.service';
@Directive({
selector: '[sqxConfirmClick]'
})
export class ConfirmClickDirective {
@Input()
public confirmTitle: string;
@Input()
public confirmText: string;
@Output('sqxConfirmClick')
public click = new EventEmitter();
constructor(
private readonly dialogService: DialogService
) {
}
@HostListener('click', ['$event'])
public onClick(event: Event) {
if (this.confirmTitle &&
this.confirmTitle.length > 0 &&
this.confirmText &&
this.confirmText.length > 0) {
let subscription =
this.dialogService.confirm(this.confirmTitle, this.confirmText)
.subscribe(result => {
if (result) {
this.click.emit();
}
subscription.unsubscribe();
});
} else {
this.click.emit();
}
event.stopPropagation();
event.preventDefault();
}
}

6
src/Squidex/app/framework/angular/copy.directive.ts

@ -7,7 +7,7 @@
import { Directive, HostListener, Input } from '@angular/core'; import { Directive, HostListener, Input } from '@angular/core';
import { Notification, NotificationService } from './../services/notification.service'; import { DialogService, Notification } from './../services/dialog.service';
@Directive({ @Directive({
selector: '[sqxCopy]' selector: '[sqxCopy]'
@ -17,7 +17,7 @@ export class CopyDirective {
public inputElement: any; public inputElement: any;
constructor( constructor(
private readonly notifications: NotificationService private readonly dialogs: DialogService
) { ) {
} }
@ -43,7 +43,7 @@ export class CopyDirective {
try { try {
document.execCommand('copy'); document.execCommand('copy');
this.notifications.notify(Notification.info('Value has been added to your clipboard.')); this.dialogs.notify(Notification.info('Value has been added to your clipboard.'));
} catch (e) { } catch (e) {
console.log('Copy failed'); console.log('Copy failed');
} }

27
src/Squidex/app/framework/angular/dialog-renderer.component.html

@ -0,0 +1,27 @@
<div class="modal" *sqxModalView="dialogView;onRoot:true" [@fade]>
<div class="modal-backdrop"></div>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">{{dialogRequest.title}}</h4>
</div>
<div class="modal-body">
{{dialogRequest.text}}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" (click)="confirm()">Yes</button>
<button type="button" class="btn btn-secondary" (click)="cancel()">No</button>
</div>
</div>
</div>
</div>
<div class="notification-container notification-container-{{position}}">
<div class="alert alert-dismissible alert-{{notification.messageType}}" *ngFor="let notification of notifications" (click)="close(notification)" [@fade]>
<button type="button" class="close" data-dismiss="alert" (close)="close(notification)">&times;</button>
{{notification.message}}
</div>
</div>

28
src/Squidex/app/framework/angular/dialog-renderer.component.scss

@ -0,0 +1,28 @@
@import '_mixins';
@import '_vars';
.notification-container {
& {
margin: .625rem;
max-width: 20rem;
min-width: 20rem;
position: fixed;
z-index: 100000;
}
&-righttop {
@include fixed(0, 0, auto, auto);
}
&-rightbottom {
@include fixed(auto, 0, 0, auto);
}
&-lefttop {
@include fixed(0, auto, auto, 0);
}
&-leftbottom {
@include fixed(auto, auto, 0, 0);
}
}

92
src/Squidex/app/framework/angular/dialog-renderer.component.ts

@ -0,0 +1,92 @@
/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Sebastian Stehle. All rights r vbeserved
*/
import { Component, Input, OnDestroy, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { fadeAnimation } from './animations';
import {
DialogRequest,
DialogService,
Notification
} from './../services/dialog.service';
import { ModalView } from './../utils/modal-view';
@Component({
selector: 'sqx-dialog-renderer',
styleUrls: ['./dialog-renderer.component.scss'],
templateUrl: './dialog-renderer.component.html',
animations: [
fadeAnimation
]
})
export class DialogRendererComponent implements OnDestroy, OnInit {
private dialogsSubscription: Subscription;
private notificationsSubscription: Subscription;
public dialogView = new ModalView(false, true);
public dialogRequest: DialogRequest;
public notifications: Notification[] = [];
@Input()
public position = 'bottomright';
constructor(
private readonly dialogService: DialogService
) {
}
public ngOnDestroy() {
this.notificationsSubscription.unsubscribe();
this.dialogsSubscription.unsubscribe();
}
public ngOnInit() {
this.notificationsSubscription =
this.dialogService.notifications.subscribe(notification => {
this.notifications.push(notification);
if (notification.displayTime > 0) {
setTimeout(() => {
this.close(notification);
}, notification.displayTime);
}
});
this.dialogsSubscription =
this.dialogService.dialogs
.subscribe(request => {
this.cancel();
this.dialogRequest = request;
this.dialogView.show();
});
}
public cancel() {
if (this.dialogRequest) {
this.dialogRequest.complete(false);
this.dialogRequest = null;
this.dialogView.hide();
}
}
public confirm() {
if (this.dialogRequest) {
this.dialogRequest.complete(true);
this.dialogRequest = null;
this.dialogView.hide();
}
}
public close(notification: Notification) {
this.notifications.splice(this.notifications.indexOf(notification), 1);
}
}

2
src/Squidex/app/framework/angular/root-view.directive.ts

@ -13,7 +13,7 @@ import { RootViewService } from './../services/root-view.service';
selector: '[sqxRootView]' selector: '[sqxRootView]'
}) })
export class RootViewDirective { export class RootViewDirective {
constructor(viewContainer: ViewContainerRef, rootViewService: RootViewService) { constructor(public viewContainer: ViewContainerRef, rootViewService: RootViewService) {
rootViewService.init(viewContainer); rootViewService.init(viewContainer);
} }
} }

4
src/Squidex/app/framework/declarations.ts

@ -8,10 +8,12 @@
export * from './angular/animations'; export * from './angular/animations';
export * from './angular/autocomplete.component'; export * from './angular/autocomplete.component';
export * from './angular/can-deactivate.guard'; export * from './angular/can-deactivate.guard';
export * from './angular/confirm-click.directive';
export * from './angular/control-errors.component'; export * from './angular/control-errors.component';
export * from './angular/copy.directive'; export * from './angular/copy.directive';
export * from './angular/date-time-editor.component'; export * from './angular/date-time-editor.component';
export * from './angular/date-time.pipes'; export * from './angular/date-time.pipes';
export * from './angular/dialog-renderer.component';
export * from './angular/dropdown.component'; export * from './angular/dropdown.component';
export * from './angular/file-drop.directive'; export * from './angular/file-drop.directive';
export * from './angular/focus-on-init.directive'; export * from './angular/focus-on-init.directive';
@ -49,10 +51,10 @@ export * from './angular/validators';
export * from './configurations'; export * from './configurations';
export * from './services/clipboard.service'; export * from './services/clipboard.service';
export * from './services/dialog.service';
export * from './services/local-store.service'; export * from './services/local-store.service';
export * from './services/local-cache.service'; export * from './services/local-cache.service';
export * from './services/message-bus'; export * from './services/message-bus';
export * from './services/notification.service';
export * from './services/resource-loader.service'; export * from './services/resource-loader.service';
export * from './services/root-view.service'; export * from './services/root-view.service';
export * from './services/shortcut.service'; export * from './services/shortcut.service';

10
src/Squidex/app/framework/module.ts

@ -15,11 +15,14 @@ import {
AutocompleteComponent, AutocompleteComponent,
CanDeactivateGuard, CanDeactivateGuard,
ClipboardService, ClipboardService,
ConfirmClickDirective,
ControlErrorsComponent, ControlErrorsComponent,
CopyDirective, CopyDirective,
DateTimeEditorComponent, DateTimeEditorComponent,
DayOfWeekPipe, DayOfWeekPipe,
DayPipe, DayPipe,
DialogService,
DialogRendererComponent,
DisplayNamePipe, DisplayNamePipe,
DropdownComponent, DropdownComponent,
DurationPipe, DurationPipe,
@ -41,7 +44,6 @@ import {
ModalViewDirective, ModalViewDirective,
MoneyPipe, MoneyPipe,
MonthPipe, MonthPipe,
NotificationService,
PanelContainerDirective, PanelContainerDirective,
PanelComponent, PanelComponent,
ParentLinkDirective, ParentLinkDirective,
@ -77,11 +79,13 @@ import {
], ],
declarations: [ declarations: [
AutocompleteComponent, AutocompleteComponent,
ConfirmClickDirective,
ControlErrorsComponent, ControlErrorsComponent,
CopyDirective, CopyDirective,
DateTimeEditorComponent, DateTimeEditorComponent,
DayOfWeekPipe, DayOfWeekPipe,
DayPipe, DayPipe,
DialogRendererComponent,
DisplayNamePipe, DisplayNamePipe,
DropdownComponent, DropdownComponent,
DurationPipe, DurationPipe,
@ -122,11 +126,13 @@ import {
], ],
exports: [ exports: [
AutocompleteComponent, AutocompleteComponent,
ConfirmClickDirective,
ControlErrorsComponent, ControlErrorsComponent,
CopyDirective, CopyDirective,
DateTimeEditorComponent, DateTimeEditorComponent,
DayOfWeekPipe, DayOfWeekPipe,
DayPipe, DayPipe,
DialogRendererComponent,
DisplayNamePipe, DisplayNamePipe,
DropdownComponent, DropdownComponent,
DurationPipe, DurationPipe,
@ -178,10 +184,10 @@ export class SqxFrameworkModule {
providers: [ providers: [
CanDeactivateGuard, CanDeactivateGuard,
ClipboardService, ClipboardService,
DialogService,
LocalCacheService, LocalCacheService,
LocalStoreService, LocalStoreService,
MessageBus, MessageBus,
NotificationService,
ResourceLoaderService, ResourceLoaderService,
RootViewService, RootViewService,
ShortcutService, ShortcutService,

94
src/Squidex/app/framework/services/dialog.service.spec.ts

@ -0,0 +1,94 @@
/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Sebastian Stehle. All rights reserved
*/
import {
Notification,
DialogRequest,
DialogService,
DialogServiceFactory
} from './../';
describe('DialogService', () => {
it('should instantiate from factory', () => {
const dialogService = DialogServiceFactory();
expect(dialogService).toBeDefined();
});
it('should instantiate', () => {
const dialogService = new DialogService();
expect(dialogService).toBeDefined();
});
it('should create error notification', () => {
const notification = Notification.error('MyError');
expect(notification.displayTime).toBe(5000);
expect(notification.message).toBe('MyError');
expect(notification.messageType).toBe('danger');
});
it('should create info notification', () => {
const notification = Notification.info('MyInfo');
expect(notification.displayTime).toBe(5000);
expect(notification.message).toBe('MyInfo');
expect(notification.messageType).toBe('info');
});
it('should create dialog request', () => {
const dialog = new DialogRequest('MyTitle', 'MyText');
expect(dialog.title).toBe('MyTitle');
expect(dialog.text).toBe('MyText');
});
it('should confirm dialog', () => {
const dialog = new DialogRequest('MyTitle', 'MyText');
let isCompleted = false;
let isNext = false;
dialog.closed.subscribe(result => {
isNext = result;
}, undefined, () => {
isCompleted = true;
})
expect(isCompleted).toBeTruthy();
expect(isNext).toBeTruthy();
});
it('should publish notification', () => {
const dialogService = new DialogService();
const notification = Notification.error('Message');
let publishedNotification: Notification | null = null;
dialogService.notifications.subscribe(result => {
publishedNotification = result;
});
dialogService.notify(notification);
expect(publishedNotification).toBe(notification);
});
it('should publish dialog request', () => {
const dialogService = new DialogService();
let pushedDialog: DialogRequest | null = null;
dialogService.dialogs.subscribe(result => {
pushedDialog = result;
});
dialogService.confirm('MyTitle', 'MyText');
expect(pushedDialog).toEqual(new DialogRequest('MyTitle', 'MyText'));
});
});

38
src/Squidex/app/framework/services/notification.service.ts → src/Squidex/app/framework/services/dialog.service.ts

@ -8,10 +8,29 @@
import { Injectable } from '@angular/core'; import { Injectable } from '@angular/core';
import { Observable, Subject } from 'rxjs'; import { Observable, Subject } from 'rxjs';
export const NotificationServiceFactory = () => { export const DialogServiceFactory = () => {
return new NotificationService(); return new DialogService();
}; };
export class DialogRequest {
private readonly resultStream$ = new Subject<boolean>();
public get closed(): Observable<boolean> {
return this.resultStream$;
}
constructor(
public readonly title: string,
public readonly text: string
) {
}
public complete(value: boolean) {
this.resultStream$.next(value);
this.resultStream$.complete();
}
}
export class Notification { export class Notification {
constructor( constructor(
public readonly message: string, public readonly message: string,
@ -30,9 +49,14 @@ export class Notification {
} }
@Injectable() @Injectable()
export class NotificationService { export class DialogService {
private readonly requestStream$ = new Subject<DialogRequest>();
private readonly notificationsStream$ = new Subject<Notification>(); private readonly notificationsStream$ = new Subject<Notification>();
public get dialogs(): Observable<DialogRequest> {
return this.requestStream$;
}
public get notifications(): Observable<Notification> { public get notifications(): Observable<Notification> {
return this.notificationsStream$; return this.notificationsStream$;
} }
@ -40,4 +64,12 @@ export class NotificationService {
public notify(notification: Notification) { public notify(notification: Notification) {
this.notificationsStream$.next(notification); this.notificationsStream$.next(notification);
} }
public confirm(title: string, text: string): Observable<boolean> {
const request = new DialogRequest(title, text);
this.requestStream$.next(request);
return request.closed;
}
} }

3
src/Squidex/app/framework/services/local-cache.service.ts

@ -5,12 +5,15 @@
* Copyright (c) Sebastian Stehle. All rights reserved * Copyright (c) Sebastian Stehle. All rights reserved
*/ */
import { Injectable } from '@angular/core';
interface Entry { value: any, expires: number }; interface Entry { value: any, expires: number };
export const LocalCacheServiceFactory = () => { export const LocalCacheServiceFactory = () => {
return new LocalCacheService(); return new LocalCacheService();
}; };
@Injectable()
export class LocalCacheService { export class LocalCacheService {
private readonly entries: { [key: string]: Entry } = {}; private readonly entries: { [key: string]: Entry } = {};

57
src/Squidex/app/framework/services/notification.service.spec.ts

@ -1,57 +0,0 @@
/*
* Squidex Headless CMS
*
* @license
* Copyright (c) Sebastian Stehle. All rights reserved
*/
import {
Notification,
NotificationService,
NotificationServiceFactory
} from './../';
describe('NotificationService', () => {
it('should instantiate from factory', () => {
const notificationService = NotificationServiceFactory();
expect(notificationService).toBeDefined();
});
it('should instantiate', () => {
const notificationService = new NotificationService();
expect(notificationService).toBeDefined();
});
it('should create error', () => {
const notification = Notification.error('MyError');
expect(notification.displayTime).toBe(5000);
expect(notification.message).toBe('MyError');
expect(notification.messageType).toBe('danger');
});
it('should create info', () => {
const notification = Notification.info('MyInfo');
expect(notification.displayTime).toBe(5000);
expect(notification.message).toBe('MyInfo');
expect(notification.messageType).toBe('info');
});
it('should publish notification', () => {
const notificationService = new NotificationService();
const notification = Notification.error('Message');
let publishedNotification: Notification | null = null;
notificationService.notifications.subscribe(result => {
publishedNotification = result;
});
notificationService.notify(notification);
expect(publishedNotification).toBe(notification);
});
});

3
src/Squidex/app/framework/services/resource-loader.service.ts

@ -5,6 +5,9 @@
* Copyright (c) Sebastian Stehle. All rights reserved * Copyright (c) Sebastian Stehle. All rights reserved
*/ */
import { Injectable } from '@angular/core';
@Injectable()
export class ResourceLoaderService { export class ResourceLoaderService {
private cache: { [path: string]: Promise<any> } = {}; private cache: { [path: string]: Promise<any> } = {};

6
src/Squidex/app/shared/components/app.component-base.ts

@ -7,17 +7,17 @@
import { Observable } from 'rxjs'; import { Observable } from 'rxjs';
import { AppsStoreService, NotificationService } from './../declarations-base'; import { AppsStoreService, DialogService } from './../declarations-base';
import { ComponentBase } from './component-base'; import { ComponentBase } from './component-base';
export abstract class AppComponentBase extends ComponentBase { export abstract class AppComponentBase extends ComponentBase {
private appName$: Observable<string>; private appName$: Observable<string>;
constructor(notifications: NotificationService, constructor(dialogs: DialogService,
private readonly appsStore: AppsStoreService private readonly appsStore: AppsStoreService
) { ) {
super(notifications); super(dialogs);
this.appName$ = this.appsStore.selectedApp.filter(a => !!a).map(a => a!.name); this.appName$ = this.appsStore.selectedApp.filter(a => !!a).map(a => a!.name);
} }

6
src/Squidex/app/shared/components/asset.component.ts

@ -16,9 +16,9 @@ import {
AssetReplacedDto, AssetReplacedDto,
AssetsService, AssetsService,
AuthService, AuthService,
DialogService,
fadeAnimation, fadeAnimation,
ModalView, ModalView,
NotificationService,
UpdateAssetDto, UpdateAssetDto,
Version Version
} from './../declarations-base'; } from './../declarations-base';
@ -70,12 +70,12 @@ export class AssetComponent extends AppComponentBase implements OnInit {
public progress = 0; public progress = 0;
constructor(apps: AppsStoreService, notifications: NotificationService, constructor(apps: AppsStoreService, dialogs: DialogService,
private readonly formBuilder: FormBuilder, private readonly formBuilder: FormBuilder,
private readonly assetsService: AssetsService, private readonly assetsService: AssetsService,
private readonly authService: AuthService private readonly authService: AuthService
) { ) {
super(notifications, apps); super(dialogs, apps);
} }
public ngOnInit() { public ngOnInit() {

12
src/Squidex/app/shared/components/component-base.ts

@ -6,26 +6,26 @@
*/ */
import { import {
DialogService,
ErrorDto, ErrorDto,
Notification, Notification
NotificationService
} from './../declarations-base'; } from './../declarations-base';
export abstract class ComponentBase { export abstract class ComponentBase {
constructor( constructor(
private readonly notifications: NotificationService private readonly dialogs: DialogService
) { ) {
} }
protected notifyError(error: string | ErrorDto) { protected notifyError(error: string | ErrorDto) {
if (error instanceof ErrorDto) { if (error instanceof ErrorDto) {
this.notifications.notify(Notification.error(error.displayMessage)); this.dialogs.notify(Notification.error(error.displayMessage));
} else { } else {
this.notifications.notify(Notification.error(error)); this.dialogs.notify(Notification.error(error));
} }
} }
protected notifyInfo(error: string) { protected notifyInfo(error: string) {
this.notifications.notify(Notification.info(error)); this.dialogs.notify(Notification.info(error));
} }
} }

6
src/Squidex/app/shared/components/history.component.ts

@ -14,11 +14,11 @@ import { AppComponentBase } from './app.component-base';
import { import {
allParams, allParams,
AppsStoreService, AppsStoreService,
DialogService,
HistoryChannelUpdated, HistoryChannelUpdated,
HistoryEventDto, HistoryEventDto,
HistoryService, HistoryService,
MessageBus, MessageBus,
NotificationService,
UsersProviderService UsersProviderService
} from './../declarations-base'; } from './../declarations-base';
@ -54,13 +54,13 @@ export class HistoryComponent extends AppComponentBase {
.switchMap(() => this.appNameOnce()) .switchMap(() => this.appNameOnce())
.switchMap(app => this.historyService.getHistory(app, this.channel).retry(2)); .switchMap(app => this.historyService.getHistory(app, this.channel).retry(2));
constructor(appsStore: AppsStoreService, notifications: NotificationService, constructor(appsStore: AppsStoreService, dialogs: DialogService,
private readonly users: UsersProviderService, private readonly users: UsersProviderService,
private readonly historyService: HistoryService, private readonly historyService: HistoryService,
private readonly messageBus: MessageBus, private readonly messageBus: MessageBus,
private readonly route: ActivatedRoute private readonly route: ActivatedRoute
) { ) {
super(notifications, appsStore); super(dialogs, appsStore);
} }
private userName(userId: string): Observable<string> { private userName(userId: string): Observable<string> {

9
src/Squidex/app/shell/pages/internal/internal-area.component.html

@ -16,14 +16,6 @@
<router-outlet></router-outlet> <router-outlet></router-outlet>
</div> </div>
<div class="notification-container">
<div class="alert alert-dismissible alert-{{notification.messageType}}" *ngFor="let notification of notifications" (click)="close(notification)" [@fade]>
<button type="button" class="close" data-dismiss="alert" (close)="close(notification)">&times;</button>
{{notification.message}}
</div>
</div>
<a class="github-button" href="https://github.com/Squidex/squidex/issues" target="_blank"> <a class="github-button" href="https://github.com/Squidex/squidex/issues" target="_blank">
<i class="icon-github github-icon"></i> <i class="icon-github github-icon"></i>
@ -31,5 +23,6 @@
</a> </a>
<sqx-user-report></sqx-user-report> <sqx-user-report></sqx-user-report>
<sqx-dialog-renderer></sqx-dialog-renderer>
<div sqxRootView></div> <div sqxRootView></div>

9
src/Squidex/app/shell/pages/internal/internal-area.component.scss

@ -64,13 +64,4 @@
text-align: center; text-align: center;
color: $color-dark-foreground; color: $color-dark-foreground;
} }
}
.notification {
&-container {
@include fixed(auto, .625rem, .625rem, auto);
max-width: 20rem;
min-width: 20rem;
z-index: 100000;
}
} }

34
src/Squidex/app/shell/pages/internal/internal-area.component.ts

@ -9,66 +9,42 @@ import { Component, OnDestroy, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { import { DialogService, Notification } from 'shared';
fadeAnimation,
Notification,
NotificationService
} from 'shared';
@Component({ @Component({
selector: 'sqx-internal-area', selector: 'sqx-internal-area',
styleUrls: ['./internal-area.component.scss'], styleUrls: ['./internal-area.component.scss'],
templateUrl: './internal-area.component.html', templateUrl: './internal-area.component.html'
animations: [
fadeAnimation
]
}) })
export class InternalAreaComponent implements OnInit, OnDestroy { export class InternalAreaComponent implements OnInit, OnDestroy {
private notificationsSubscription: Subscription;
private queryParamsSubscription: Subscription; private queryParamsSubscription: Subscription;
public notifications: Notification[] = []; public notifications: Notification[] = [];
constructor( constructor(
private readonly notificationService: NotificationService, private readonly dialogs: DialogService,
private readonly route: ActivatedRoute private readonly route: ActivatedRoute
) { ) {
} }
public ngOnDestroy() { public ngOnDestroy() {
this.queryParamsSubscription.unsubscribe(); this.queryParamsSubscription.unsubscribe();
this.notificationsSubscription.unsubscribe();
} }
public ngOnInit() { public ngOnInit() {
this.notificationsSubscription =
this.notificationService.notifications.subscribe(notification => {
this.notifications.push(notification);
if (notification.displayTime > 0) {
setTimeout(() => {
this.close(notification);
}, notification.displayTime);
}
});
this.queryParamsSubscription = this.queryParamsSubscription =
this.route.queryParams.subscribe(params => { this.route.queryParams.subscribe(params => {
const successMessage = params['successMessage']; const successMessage = params['successMessage'];
if (successMessage) { if (successMessage) {
this.notificationService.notify(Notification.info(successMessage)); this.dialogs.notify(Notification.info(successMessage));
} }
const errorMessage = params['errorMessage']; const errorMessage = params['errorMessage'];
if (errorMessage) { if (errorMessage) {
this.notificationService.notify(Notification.error(errorMessage)); this.dialogs.notify(Notification.error(errorMessage));
} }
}); });
} }
public close(notification: Notification) {
this.notifications.splice(this.notifications.indexOf(notification), 1);
}
} }
Loading…
Cancel
Save