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 137223632..6f450329b 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 @@ -72,14 +72,14 @@ -
+
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 7f5c44dc4..75b8f7530 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 @@ -13,6 +13,7 @@ import { ComponentBase, ImmutableArray, NotificationService, + Pager, UserDto, UserManagementService, UsersProviderService @@ -27,20 +28,9 @@ export class UsersPageComponent extends ComponentBase implements OnInit { public currentUserId: string; public usersItems = ImmutableArray.empty(); - public usersTotal = 0; - - public pageSize = 10; - - public canGoNext = false; - public canGoPrev = false; - - public itemFirst = 0; - public itemLast = 0; - - public currentPage = 0; - public currentQuery = ''; - + public usersPager = new Pager(0); public usersFilter = new FormControl(); + public usersQuery = ''; constructor(notifications: NotificationService, users: UsersProviderService, private readonly userManagementService: UserManagementService, @@ -56,19 +46,17 @@ export class UsersPageComponent extends ComponentBase implements OnInit { } public search() { - this.currentPage = 0; - this.currentQuery = this.usersFilter.value; + this.usersPager = new Pager(0); + this.usersQuery = this.usersFilter.value; this.load(); } private load() { - this.userManagementService.getUsers(this.pageSize, this.currentPage * this.pageSize, this.currentQuery) + this.userManagementService.getUsers(this.usersPager.pageSize, this.usersPager.skip, this.usersQuery) .subscribe(dtos => { this.usersItems = ImmutableArray.of(dtos.items); - this.usersTotal = dtos.total; - - this.updatePaging(); + this.usersPager = this.usersPager.setCount(dtos.total); }, error => { this.notifyError(error); }); @@ -105,31 +93,15 @@ export class UsersPageComponent extends ComponentBase implements OnInit { } public goNext() { - if (this.canGoNext) { - this.currentPage++; + this.usersPager = this.usersPager.goNext(); - this.updatePaging(); - this.load(); - } + this.load(); } public goPrev() { - if (this.canGoPrev) { - this.currentPage--; - - this.updatePaging(); - this.load(); - } - } + this.usersPager = this.usersPager.goPrev(); - private updatePaging() { - const totalPages = Math.ceil(this.usersTotal / this.pageSize); - - this.itemFirst = this.currentPage * this.pageSize + 1; - this.itemLast = Math.min(this.usersTotal, (this.currentPage + 1) * this.pageSize); - - this.canGoNext = this.currentPage < totalPages - 1; - this.canGoPrev = this.currentPage > 0; + this.load(); } } 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 4fbdc2187..f0836b099 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 @@ -67,14 +67,14 @@ -
+
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 eae9f9af7..4e8c89e4d 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 @@ -28,6 +28,7 @@ import { ImmutableArray, MessageBus, NotificationService, + Pager, SchemaDetailsDto, UsersProviderService, Version @@ -46,24 +47,13 @@ export class ContentsPageComponent extends AppComponentBase implements OnDestroy public contentItems: ImmutableArray; public contentFields: FieldDto[]; - public contentTotal = 0; + public contentsFilter = new FormControl(); + public contentsQuery = ''; + public contentsPager = new Pager(0); public languages: AppLanguageDto[] = []; public languageSelected: AppLanguageDto; - public contentsFilter = new FormControl(); - - public pageSize = 10; - - public canGoNext = false; - public canGoPrev = false; - - public itemFirst = 0; - public itemLast = 0; - - public currentPage = 0; - public currentQuery = ''; - public get columnWidth() { return 100 / this.contentFields.length; } @@ -86,9 +76,8 @@ export class ContentsPageComponent extends AppComponentBase implements OnDestroy this.messageCreatedSubscription = this.messageBus.of(ContentCreated) .subscribe(message => { - this.itemLast++; - this.contentTotal++; this.contentItems = this.contentItems.pushFront(this.createContent(message.id, message.data, message.version)); + this.contentsPager = this.contentsPager.incrementCount(); }); this.messageUpdatedSubscription = @@ -112,12 +101,20 @@ export class ContentsPageComponent extends AppComponentBase implements OnDestroy } public search() { - this.currentPage = 0; - this.currentQuery = this.contentsFilter.value; + this.contentsQuery = this.contentsFilter.value; + this.contentsPager = new Pager(0); this.load(); } + private reset() { + this.contentItems = ImmutableArray.empty(); + this.contentsFilter.setValue(''); + this.contentsPager = new Pager(0); + + this.loadFields(); + } + public publishContent(content: ContentDto) { this.appName() .switchMap(app => this.contentsService.publishContent(app, this.schema.name, content.id, content.version)) @@ -143,9 +140,7 @@ export class ContentsPageComponent extends AppComponentBase implements OnDestroy .switchMap(app => this.contentsService.deleteContent(app, this.schema.name, content.id, content.version)) .subscribe(() => { this.contentItems = this.contentItems.removeAll(x => x.id === content.id); - this.contentTotal--; - - this.updatePaging(); + this.contentsPager = this.contentsPager.decrementCount(); this.messageBus.publish(new ContentDeleted(content.id)); }, error => { @@ -157,12 +152,6 @@ export class ContentsPageComponent extends AppComponentBase implements OnDestroy this.languageSelected = language; } - private reset() { - this.loadFields(); - - this.currentPage = 0; - } - private loadFields() { this.contentFields = this.schema.fields.filter(x => x.properties.isListField); @@ -173,43 +162,26 @@ export class ContentsPageComponent extends AppComponentBase implements OnDestroy private load() { this.appName() - .switchMap(app => this.contentsService.getContents(app, this.schema.name, this.pageSize, this.currentPage * this.pageSize, this.currentQuery)) + .switchMap(app => this.contentsService.getContents(app, this.schema.name, this.contentsPager.pageSize, this.contentsPager.skip, this.contentsQuery)) .subscribe(dtos => { this.contentItems = ImmutableArray.of(dtos.items); - this.contentTotal = dtos.total; - this.updatePaging(); + this.contentsPager = this.contentsPager.setCount(dtos.total); }, error => { this.notifyError(error); }); } public goNext() { - if (this.canGoNext) { - this.currentPage++; + this.contentsPager = this.contentsPager.goNext(); - this.updatePaging(); - this.load(); - } + this.load(); } public goPrev() { - if (this.canGoPrev) { - this.currentPage--; + this.contentsPager = this.contentsPager.goPrev(); - this.updatePaging(); - this.load(); - } - } - - private updatePaging() { - const totalPages = Math.ceil(this.contentTotal / this.pageSize); - - this.itemFirst = this.currentPage * this.pageSize + 1; - this.itemLast = Math.min(this.contentTotal, (this.currentPage + 1) * this.pageSize); - - this.canGoNext = this.currentPage < totalPages - 1; - this.canGoPrev = this.currentPage > 0; + this.load(); } private updateContents(id: string, p: boolean | undefined, data: any, version: string) { diff --git a/src/Squidex/app/features/schemas/pages/schema/schema-page.component.scss b/src/Squidex/app/features/schemas/pages/schema/schema-page.component.scss index fb7019eed..ea9ebaf7b 100644 --- a/src/Squidex/app/features/schemas/pages/schema/schema-page.component.scss +++ b/src/Squidex/app/features/schemas/pages/schema/schema-page.component.scss @@ -13,6 +13,11 @@ } } +.btn-sm, +.btn-group-sm { + margin-top: .25rem; +} + .schema { &-edit { color: $color-border-dark; diff --git a/src/Squidex/app/features/settings/pages/clients/client.component.html b/src/Squidex/app/features/settings/pages/clients/client.component.html index 0fc70eca7..d4ab14dbf 100644 --- a/src/Squidex/app/features/settings/pages/clients/client.component.html +++ b/src/Squidex/app/features/settings/pages/clients/client.component.html @@ -39,7 +39,7 @@
Access tokens expire after 30 days
- diff --git a/src/Squidex/app/framework/angular/copy.directive.ts b/src/Squidex/app/framework/angular/copy.directive.ts index 6cef6031c..0c56035e0 100644 --- a/src/Squidex/app/framework/angular/copy.directive.ts +++ b/src/Squidex/app/framework/angular/copy.directive.ts @@ -7,6 +7,8 @@ import { Directive, HostListener, Input } from '@angular/core'; +import { Notification, NotificationService } from './../services/notification.service'; + @Directive({ selector: '[sqxCopy]' }) @@ -14,6 +16,11 @@ export class CopyDirective { @Input('sqxCopy') public inputElement: any; + constructor( + private readonly notifications: NotificationService + ) { + } + @HostListener('click') public onClick() { if (this.inputElement) { @@ -35,6 +42,8 @@ export class CopyDirective { try { document.execCommand('copy'); + + this.notifications.notify(Notification.info('Value has been added to your clipboard.')); } catch (e) { console.log('Copy failed'); } diff --git a/src/Squidex/app/framework/declarations.ts b/src/Squidex/app/framework/declarations.ts index 262053dbb..d8137fa51 100644 --- a/src/Squidex/app/framework/declarations.ts +++ b/src/Squidex/app/framework/declarations.ts @@ -49,5 +49,6 @@ export * from './utils/duration'; export * from './utils/immutable-array'; export * from './utils/math-helper'; export * from './utils/modal-view'; +export * from './utils/pager'; export * from './utils/string-helper'; export * from './utils/version'; \ No newline at end of file diff --git a/src/Squidex/app/framework/services/notification.service.ts b/src/Squidex/app/framework/services/notification.service.ts index c1a4a67bf..d659c73f4 100644 --- a/src/Squidex/app/framework/services/notification.service.ts +++ b/src/Squidex/app/framework/services/notification.service.ts @@ -16,7 +16,7 @@ export class Notification { constructor( public readonly message: string, public readonly messageType: string, - public readonly displayTime: number = 10000 + public readonly displayTime: number = 5000 ) { } diff --git a/src/Squidex/app/framework/utils/pager.ts b/src/Squidex/app/framework/utils/pager.ts new file mode 100644 index 000000000..b000fa493 --- /dev/null +++ b/src/Squidex/app/framework/utils/pager.ts @@ -0,0 +1,64 @@ +/* + * Squidex Headless CMS + * + * @license + * Copyright (c) Sebastian Stehle. All rights reserved + */ + +export class Pager { + public canGoNext = false; + public canGoPrev = false; + + public itemFirst = 0; + public itemLast = 0; + + public skip = 0; + + constructor( + public readonly numberOfItems: number, + public readonly page = 0, + public readonly pageSize = 10 + ) { + const totalPages = Math.ceil(numberOfItems / this.pageSize); + + this.itemFirst = page * this.pageSize + 1; + this.itemLast = Math.min(numberOfItems, (page + 1) * this.pageSize); + + this.canGoNext = page < totalPages - 1; + this.canGoPrev = page > 0; + + this.skip = page * pageSize; + } + + public goNext(): Pager { + if (!this.canGoNext) { + return this; + } + + return new Pager(this.numberOfItems, this.page + 1, this.pageSize); + } + + public goPrev(): Pager { + if (!this.canGoPrev) { + return this; + } + + return new Pager(this.numberOfItems, this.page - 1, this.pageSize); + } + + public reset(): Pager { + return new Pager(0, 0, this.pageSize); + } + + public setCount(numberOfItems: number): Pager { + return new Pager(numberOfItems, this.page, this.pageSize); + } + + public incrementCount(): Pager { + return new Pager(this.numberOfItems + 1, this.page, this.pageSize); + } + + public decrementCount(): Pager { + return new Pager(this.numberOfItems - 1, this.page, this.pageSize); + } +} \ No newline at end of file diff --git a/src/Squidex/app/shared/components/language-selector.component.ts b/src/Squidex/app/shared/components/language-selector.component.ts index af60a5a82..e6d2c3b1b 100644 --- a/src/Squidex/app/shared/components/language-selector.component.ts +++ b/src/Squidex/app/shared/components/language-selector.component.ts @@ -5,7 +5,7 @@ * Copyright (c) Sebastian Stehle. All rights reserved */ -import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; +import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core'; import { fadeAnimation, ModalView } from 'framework'; @@ -19,7 +19,7 @@ export interface Language { iso2Code: string; englishName: string; isMasterLangu fadeAnimation ] }) -export class LanguageSelectorComponent implements OnInit { +export class LanguageSelectorComponent implements OnChanges, OnInit { public dropdown = new ModalView(false, true); @Input() @@ -42,8 +42,16 @@ export class LanguageSelectorComponent implements OnInit { return this.languages && this.languages.length > 3; } + public ngOnChanges() { + this.update(); + } + public ngOnInit() { - if (this.languages && this.languages.length > 0 && !this.selectedLanguage) { + this.update(); + } + + private update() { + if (this.languages && this.languages.length > 0 && (!this.selectedLanguage || this.languages.indexOf(this.selectedLanguage) < 0)) { const selectedLanguage = this.languages.find(l => l.isMasterLanguage) || this.languages[0]; diff --git a/src/Squidex/app/shell/pages/internal/internal-area.component.scss b/src/Squidex/app/shell/pages/internal/internal-area.component.scss index ae07fbdd9..24c06aa80 100644 --- a/src/Squidex/app/shell/pages/internal/internal-area.component.scss +++ b/src/Squidex/app/shell/pages/internal/internal-area.component.scss @@ -40,4 +40,8 @@ &-error { background: $color-theme-error; } + + &-info { + background: $color-theme-blue; + } } \ No newline at end of file