diff --git a/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetsDto.cs b/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetsDto.cs index b7f9a3b05..c0870d583 100644 --- a/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetsDto.cs +++ b/src/Squidex/Areas/Api/Controllers/Assets/Models/AssetsDto.cs @@ -17,15 +17,15 @@ namespace Squidex.Areas.Api.Controllers.Assets.Models public sealed class AssetsDto : Resource { /// - /// The assets. + /// The total number of assets. /// - [Required] - public AssetDto[] Items { get; set; } + public long Total { get; set; } /// - /// The total number of assets. + /// The assets. /// - public long Total { get; set; } + [Required] + public AssetDto[] Items { get; set; } public string ToEtag() { diff --git a/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs b/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs index 079d9fdfc..547f56286 100644 --- a/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs +++ b/src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs @@ -120,9 +120,9 @@ namespace Squidex.Areas.Api.Controllers.Contents [ProducesResponseType(typeof(ContentsDto), 200)] [ApiPermission] [ApiCosts(1)] - public async Task GetAllContents(string app, [FromQuery] string ids, [FromQuery] string status = null) + public async Task GetAllContents(string app, [FromQuery] string ids, [FromQuery] string[] status = null) { - var context = Context().WithFrontendStatus(status); + var context = Context(); var result = await contentQuery.QueryAsync(context, Q.Empty.WithIds(ids).Ids); @@ -157,9 +157,9 @@ namespace Squidex.Areas.Api.Controllers.Contents [ProducesResponseType(typeof(ContentsDto), 200)] [ApiPermission] [ApiCosts(1)] - public async Task GetContents(string app, string name, [FromQuery] string ids = null, [FromQuery] string status = null) + public async Task GetContents(string app, string name, [FromQuery] string ids = null, [FromQuery] string[] status = null) { - var context = Context().WithFrontendStatus(status); + var context = Context(); var result = await contentQuery.QueryAsync(context, name, Q.Empty.WithIds(ids).WithODataQuery(Request.QueryString.ToString())); diff --git a/src/Squidex/Areas/Api/Controllers/Contents/Models/ContentsDto.cs b/src/Squidex/Areas/Api/Controllers/Contents/Models/ContentsDto.cs index a3a79ade2..f5029b78c 100644 --- a/src/Squidex/Areas/Api/Controllers/Contents/Models/ContentsDto.cs +++ b/src/Squidex/Areas/Api/Controllers/Contents/Models/ContentsDto.cs @@ -6,6 +6,7 @@ // ========================================================================== using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.Linq; using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Entities; @@ -26,8 +27,15 @@ namespace Squidex.Areas.Api.Controllers.Contents.Models /// /// The content items. /// + [Required] public ContentDto[] Items { get; set; } + /// + /// All available statuses. + /// + [Required] + public string[] Statuses { get; set; } + public string ToEtag() { return Items.ToManyEtag(Total); @@ -54,7 +62,8 @@ namespace Squidex.Areas.Api.Controllers.Contents.Models var result = new ContentsDto { Total = contents.Total, - Items = contents.Select(x => ContentDto.FromContent(x, context, controller, app, schema)).ToArray() + Items = contents.Select(x => ContentDto.FromContent(x, context, controller, app, schema)).ToArray(), + Statuses = new[] { "Published", "Draft", "Archived" } }; return result.CreateLinks(controller, app, schema); diff --git a/src/Squidex/Areas/Api/Controllers/Users/Models/UsersDto.cs b/src/Squidex/Areas/Api/Controllers/Users/Models/UsersDto.cs index f7f89cf41..c8a2937b1 100644 --- a/src/Squidex/Areas/Api/Controllers/Users/Models/UsersDto.cs +++ b/src/Squidex/Areas/Api/Controllers/Users/Models/UsersDto.cs @@ -6,6 +6,7 @@ // ========================================================================== using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; using System.Linq; using Squidex.Domain.Users; using Squidex.Shared; @@ -23,6 +24,7 @@ namespace Squidex.Areas.Api.Controllers.Users.Models /// /// The users. /// + [Required] public UserDto[] Items { get; set; } public static UsersDto FromResults(IEnumerable items, long total, ApiController controller) 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 e1bed115c..c848d5d5d 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 @@ -45,13 +45,10 @@ export class UserPageComponent extends ResourceOwner implements OnInit { this.user = selectedUser!; if (selectedUser) { - this.userForm.load(selectedUser); - this.isEditable = this.user.canUpdate; - if (!this.isEditable) { - this.userForm.form.disable(); - } + this.userForm.load(selectedUser); + this.userForm.setEnabled(this.isEditable); } })); } 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 39f263cd7..fd4afb1a6 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 @@ -182,7 +182,8 @@ export class ContentPageComponent extends ResourceOwner implements CanComponentD } private loadContent(data: any) { - this.contentForm.loadContent(data, this.content && !this.content.canUpdate); + this.contentForm.loadContent(data); + this.contentForm.setEnabled(!this.content || this.content.canUpdate); } public discardChanges() { @@ -219,13 +220,12 @@ export class ContentPageComponent extends ResourceOwner implements CanComponentD if (compare) { if (this.contentFormCompare === null) { this.contentFormCompare = new EditContentForm(this.schema, this.languages); - this.contentFormCompare.form.disable(); } - const isArchive = this.content && this.content.status === 'Archived'; + this.contentFormCompare.loadContent(dto.payload); + this.contentFormCompare.setEnabled(false); - this.contentFormCompare.loadContent(dto.payload, true); - this.contentForm.loadContent(this.content.dataDraft, isArchive); + this.loadContent(this.content.dataDraft); } else { if (this.contentFormCompare) { this.contentFormCompare = null; 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 d0af013bc..e23b7d5f6 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 @@ -21,7 +21,7 @@ [queries]="schemaQueries" (statusChange)="filterStatus($event)" [status]="contentsState.status | async" - [statuses]="statuses" + [statuses]="contentsState.statuses | async" expandable="true" enableArchive="true" enableShortcut="true"> 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 7e58e14f3..dff356794 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 @@ -11,9 +11,7 @@ import { onErrorResumeNext, switchMap, tap } from 'rxjs/operators'; import { AppLanguageDto, AppsState, - CONTENT_STATUSES, ContentDto, - ContentQueryStatus, ContentsState, FilterState, ImmutableArray, @@ -47,8 +45,6 @@ export class ContentsPageComponent extends ResourceOwner implements OnInit { public nextStatuses: string[] = []; - public statuses = CONTENT_STATUSES; - public language: AppLanguageDto; public languages: ImmutableArray; @@ -144,7 +140,7 @@ export class ContentsPageComponent extends ResourceOwner implements OnInit { .subscribe(); } - public filterStatus(status: ContentQueryStatus) { + public filterStatus(status: string[]) { this.contentsState.filterStatus(status); } diff --git a/src/Squidex/app/features/content/shared/contents-selector.component.html b/src/Squidex/app/features/content/shared/contents-selector.component.html index d8010ea54..e4c00bda7 100644 --- a/src/Squidex/app/features/content/shared/contents-selector.component.html +++ b/src/Squidex/app/features/content/shared/contents-selector.component.html @@ -15,7 +15,7 @@ [filter]="filter" (statusChange)="filterStatus($event)" [status]="contentsState.status | async" - [statuses]="statuses" + [statuses]="contentsState.statuses | async" (querySubmit)="search()" expandable="true"> diff --git a/src/Squidex/app/features/content/shared/contents-selector.component.ts b/src/Squidex/app/features/content/shared/contents-selector.component.ts index 3a7d11597..c27c6c1a8 100644 --- a/src/Squidex/app/features/content/shared/contents-selector.component.ts +++ b/src/Squidex/app/features/content/shared/contents-selector.component.ts @@ -8,9 +8,7 @@ import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { - CONTENT_STATUSES, ContentDto, - ContentQueryStatus, FilterState, LanguageDto, ManualContentsState, @@ -48,8 +46,6 @@ export class ContentsSelectorComponent implements OnInit { public filter = new FilterState(); - public statuses = CONTENT_STATUSES; - public selectedItems: { [id: string]: ContentDto; } = {}; public selectionCount = 0; @@ -74,7 +70,7 @@ export class ContentsSelectorComponent implements OnInit { this.contentsState.search(this.filter.apiFilter); } - public filterStatus(status: ContentQueryStatus) { + public filterStatus(status: string[]) { this.contentsState.filterStatus(status); } 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 8c88c9c8d..6c47ce087 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 @@ -79,11 +79,9 @@ export class RuleWizardComponent implements AfterViewInit, OnInit { } public ngAfterViewInit() { - if (!this.isEditable) { - this.actionForm.form.disable(); + this.actionForm.setEnabled(this.isEditable); - this.triggerForm.form.disable(); - } + this.triggerForm.setEnabled(this.isEditable); } public emitComplete() { diff --git a/src/Squidex/app/features/schemas/pages/schema/forms/field-form.component.ts b/src/Squidex/app/features/schemas/pages/schema/forms/field-form.component.ts index 0d7dd5509..6b8ca98b4 100644 --- a/src/Squidex/app/features/schemas/pages/schema/forms/field-form.component.ts +++ b/src/Squidex/app/features/schemas/pages/schema/forms/field-form.component.ts @@ -76,6 +76,8 @@ export class FieldFormComponent implements AfterViewInit { public ngAfterViewInit() { if (!this.isEditable) { this.editForm.disable(); + } else { + this.editForm.enable(); } } 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 2388ee42d..b25b815ae 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 @@ -40,10 +40,7 @@ export class SchemaEditFormComponent implements OnInit { this.isEditable = this.schema.canUpdate; this.editForm.load(this.schema.properties); - - if (!this.isEditable) { - this.editForm.form.disable(); - } + this.editForm.setEnabled(this.isEditable); } public emitComplete() { 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 2b6bab98a..9b5d7a2ec 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 @@ -42,10 +42,7 @@ export class SchemaScriptsFormComponent implements OnInit { this.isEditable = this.schema.canUpdateScripts; this.editForm.load(this.schema.scripts); - - if (!this.isEditable) { - this.editForm.form.disable(); - } + this.editForm.setEnabled(this.isEditable); } public emitComplete() { diff --git a/src/Squidex/app/features/settings/pages/languages/language.component.ts b/src/Squidex/app/features/settings/pages/languages/language.component.ts index c482b523b..8956b6a2a 100644 --- a/src/Squidex/app/features/settings/pages/languages/language.component.ts +++ b/src/Squidex/app/features/settings/pages/languages/language.component.ts @@ -98,10 +98,7 @@ export class LanguageComponent implements OnChanges { this.isEditable = this.language.canUpdate; this.editForm.load(this.language); - - if (!this.isEditable) { - this.editForm.form.disable(); - } + this.editForm.setEnabled(this.isEditable); this.otherLanguage = this.fallbackLanguagesNew.at(0); } diff --git a/src/Squidex/app/features/settings/pages/patterns/pattern.component.ts b/src/Squidex/app/features/settings/pages/patterns/pattern.component.ts index c517744cf..a4cd887b1 100644 --- a/src/Squidex/app/features/settings/pages/patterns/pattern.component.ts +++ b/src/Squidex/app/features/settings/pages/patterns/pattern.component.ts @@ -39,10 +39,7 @@ export class PatternComponent implements OnInit { this.isDeletable = this.pattern && this.pattern.canDelete; this.editForm.load(this.pattern); - - if (!this.isEditable) { - this.editForm.form.disable(); - } + this.editForm.setEnabled(this.isEditable); } public cancel() { diff --git a/src/Squidex/app/features/settings/pages/roles/role.component.ts b/src/Squidex/app/features/settings/pages/roles/role.component.ts index 4d77eb02d..67cbe9bbf 100644 --- a/src/Squidex/app/features/settings/pages/roles/role.component.ts +++ b/src/Squidex/app/features/settings/pages/roles/role.component.ts @@ -53,10 +53,7 @@ export class RoleComponent implements OnChanges { this.isEditable = this.role.canUpdate; this.editForm.load(this.role.permissions); - - if (!this.isEditable) { - this.editForm.form.disable(); - } + this.editForm.setEnabled(this.isEditable); } public toggleEditing() { diff --git a/src/Squidex/app/framework/state.ts b/src/Squidex/app/framework/state.ts index 97541026e..ae0269e4f 100644 --- a/src/Squidex/app/framework/state.ts +++ b/src/Squidex/app/framework/state.ts @@ -35,14 +35,22 @@ export class Form { ) { } - protected disable() { - this.form.disable(); + public setEnabled(isEnabled: boolean) { + if (isEnabled) { + this.enable(); + } else { + this.disable(); + } } protected enable() { this.form.enable(); } + protected disable() { + this.form.disable(); + } + protected setValue(value?: V) { if (value) { this.form.reset(this.transformLoad(value)); diff --git a/src/Squidex/app/shared/components/asset-dialog.component.html b/src/Squidex/app/shared/components/asset-dialog.component.html index 37b08bc02..10962b59b 100644 --- a/src/Squidex/app/shared/components/asset-dialog.component.html +++ b/src/Squidex/app/shared/components/asset-dialog.component.html @@ -38,7 +38,7 @@ Cancel - Save + Save \ No newline at end of file diff --git a/src/Squidex/app/shared/components/asset-dialog.component.ts b/src/Squidex/app/shared/components/asset-dialog.component.ts index b9e289cb0..463267626 100644 --- a/src/Squidex/app/shared/components/asset-dialog.component.ts +++ b/src/Squidex/app/shared/components/asset-dialog.component.ts @@ -35,7 +35,7 @@ export class AssetDialogComponent extends StatefulComponent implements OnInit { @Output() public complete = new EventEmitter(); - public isReadOnly = false; + public isEditable = false; public annotateForm = new AnnotateAssetForm(this.formBuilder); @@ -52,13 +52,10 @@ export class AssetDialogComponent extends StatefulComponent implements OnInit { } public ngOnInit() { - this.annotateForm.load(this.asset); - - this.isReadOnly = !this.asset.canUpdate; + this.isEditable = this.asset.canUpdate; - if (this.isReadOnly) { - this.annotateForm.form.disable(); - } + this.annotateForm.load(this.asset); + this.annotateForm.setEnabled(!this.isEditable); } public generateSlug() { @@ -74,7 +71,7 @@ export class AssetDialogComponent extends StatefulComponent implements OnInit { } public annotateAsset() { - if (this.isReadOnly) { + if (!this.isEditable) { return; } diff --git a/src/Squidex/app/shared/components/search-form.component.html b/src/Squidex/app/shared/components/search-form.component.html index 5347b37c8..756882347 100644 --- a/src/Squidex/app/shared/components/search-form.component.html +++ b/src/Squidex/app/shared/components/search-form.component.html @@ -69,14 +69,12 @@ - + 0"> - - - - {{statuses[key]}} - - + + diff --git a/src/Squidex/app/shared/components/search-form.component.ts b/src/Squidex/app/shared/components/search-form.component.ts index 27021e930..3865782e1 100644 --- a/src/Squidex/app/shared/components/search-form.component.ts +++ b/src/Squidex/app/shared/components/search-form.component.ts @@ -40,13 +40,13 @@ export class SearchFormComponent implements OnInit { public filter: FilterState; @Input() - public statuses: { [status: string]: string }; + public statuses: [] = []; @Input() - public status: string; + public status: string[]; @Output() - public statusChange = new EventEmitter(); + public statusChange = new EventEmitter<[]>(); @Input() public schemaName = ''; diff --git a/src/Squidex/app/shared/services/contents.service.spec.ts b/src/Squidex/app/shared/services/contents.service.spec.ts index 00b9224c3..4cbe177c5 100644 --- a/src/Squidex/app/shared/services/contents.service.spec.ts +++ b/src/Squidex/app/shared/services/contents.service.spec.ts @@ -47,11 +47,11 @@ describe('ContentsService', () => { let contents: ContentsDto; - contentsService.getContents('my-app', 'my-schema', 17, 13, undefined, undefined, 'Archived').subscribe(result => { + contentsService.getContents('my-app', 'my-schema', 17, 13, undefined, undefined, ['Draft', 'Published']).subscribe(result => { contents = result; }); - const req = httpMock.expectOne('http://service/p/api/content/my-app/my-schema?$top=17&$skip=13&status=Archived'); + const req = httpMock.expectOne('http://service/p/api/content/my-app/my-schema?$top=17&$skip=13&status=Draft&status=Published'); expect(req.request.method).toEqual('GET'); expect(req.request.headers.get('If-Match')).toBeNull(); @@ -61,11 +61,12 @@ describe('ContentsService', () => { items: [ contentResponse(12), contentResponse(13) - ] + ], + es: ['Draft', 'Published'] }); expect(contents!).toEqual( - new ContentsDto(10, [ + new ContentsDto(['Draft', 'Published'], 10, [ createContent(12), createContent(13) ])); @@ -76,7 +77,7 @@ describe('ContentsService', () => { contentsService.getContents('my-app', 'my-schema', 17, 13, 'my-query').subscribe(); - const req = httpMock.expectOne('http://service/p/api/content/my-app/my-schema?$search="my-query"&$top=17&$skip=13&status=PublishedDraft'); + const req = httpMock.expectOne('http://service/p/api/content/my-app/my-schema?$search="my-query"&$top=17&$skip=13'); expect(req.request.method).toEqual('GET'); expect(req.request.headers.get('If-Match')).toBeNull(); @@ -89,7 +90,7 @@ describe('ContentsService', () => { contentsService.getContents('my-app', 'my-schema', 17, 13, undefined, ['id1', 'id2']).subscribe(); - const req = httpMock.expectOne('http://service/p/api/content/my-app/my-schema?$top=17&$skip=13&ids=id1,id2&status=PublishedDraft'); + const req = httpMock.expectOne('http://service/p/api/content/my-app/my-schema?$top=17&$skip=13&ids=id1,id2'); expect(req.request.method).toEqual('GET'); expect(req.request.headers.get('If-Match')).toBeNull(); @@ -102,7 +103,7 @@ describe('ContentsService', () => { contentsService.getContents('my-app', 'my-schema', 17, 13, '$filter=my-filter').subscribe(); - const req = httpMock.expectOne('http://service/p/api/content/my-app/my-schema?$filter=my-filter&$top=17&$skip=13&status=PublishedDraft'); + const req = httpMock.expectOne('http://service/p/api/content/my-app/my-schema?$filter=my-filter&$top=17&$skip=13'); expect(req.request.method).toEqual('GET'); expect(req.request.headers.get('If-Match')).toBeNull(); diff --git a/src/Squidex/app/shared/services/contents.service.ts b/src/Squidex/app/shared/services/contents.service.ts index f2b594b7d..fae6b1927 100644 --- a/src/Squidex/app/shared/services/contents.service.ts +++ b/src/Squidex/app/shared/services/contents.service.ts @@ -35,6 +35,15 @@ export class ScheduleDto { } export class ContentsDto extends ResultSet { + constructor( + public readonly statuses: string[], + total: number, + items: ContentDto[], + links?: ResourceLinks + ) { + super(total, items, links); + } + public get canCreate() { return hasAnyLink(this._links, 'create'); } @@ -80,8 +89,6 @@ export class ContentDto { } } -export type ContentQueryStatus = 'Archived' | 'PublishedOnly' | 'PublishedDraft'; - @Injectable() export class ContentsService { constructor( @@ -91,7 +98,7 @@ export class ContentsService { ) { } - public getContents(appName: string, schemaName: string, take: number, skip: number, query?: string, ids?: string[], status: ContentQueryStatus = 'PublishedDraft'): Observable { + public getContents(appName: string, schemaName: string, take: number, skip: number, query?: string, ids?: string[], status?: string[]): Observable { const queryParts: string[] = []; if (query && query.length > 0) { @@ -117,18 +124,20 @@ export class ContentsService { } if (status) { - queryParts.push(`status=${status}`); + for (let s of status) { + queryParts.push(`status=${s}`); + } } const fullQuery = queryParts.join('&'); const url = this.apiUrl.buildUrl(`/api/content/${appName}/${schemaName}?${fullQuery}`); - return this.http.get<{ total: number, items: [] } & Resource>(url).pipe( - map(({ total, items, _links }) => { + return this.http.get<{ total: number, items: [], statuses: string[] } & Resource>(url).pipe( + map(({ total, items, statuses, _links }) => { const contents = items.map(x => parseContent(x)); - return new ContentsDto(total, contents, _links); + return new ContentsDto(statuses, total, contents, _links); }), pretifyError('Failed to load contents. Please reload.')); } diff --git a/src/Squidex/app/shared/state/contents.forms.ts b/src/Squidex/app/shared/state/contents.forms.ts index b5c1e1134..f74cc0d4d 100644 --- a/src/Squidex/app/shared/state/contents.forms.ts +++ b/src/Squidex/app/shared/state/contents.forms.ts @@ -408,7 +408,7 @@ export class EditContentForm extends Form { } } - public loadContent(value: any, disable: boolean) { + public loadContent(value: any) { for (let field of this.schema.fields) { if (field.isArray && field.nested.length > 0) { const fieldForm = this.form.get(field.name); @@ -445,12 +445,6 @@ export class EditContentForm extends Form { } super.load(value); - - if (disable) { - this.disable(); - } else { - this.enable(); - } } protected enable() { diff --git a/src/Squidex/app/shared/state/contents.state.ts b/src/Squidex/app/shared/state/contents.state.ts index a2e5b7589..5fbf38412 100644 --- a/src/Squidex/app/shared/state/contents.state.ts +++ b/src/Squidex/app/shared/state/contents.state.ts @@ -25,7 +25,7 @@ import { SchemaDto } from './../services/schemas.service'; import { AppsState } from './apps.state'; import { SchemasState } from './schemas.state'; -import { ContentDto, ContentQueryStatus, ContentsService } from './../services/contents.service'; +import { ContentDto, ContentsService } from './../services/contents.service'; interface Snapshot { // The current comments. @@ -40,8 +40,11 @@ interface Snapshot { // Indicates if the contents are loaded. isLoaded?: boolean; + // All statuses. + statuses?: string[]; + // Indicates which status is shown. - status: ContentQueryStatus; + status?: string[]; // The selected content. selectedContent?: ContentDto | null; @@ -56,12 +59,6 @@ interface Snapshot { _links?: ResourceLinks; } -export const CONTENT_STATUSES = { - 'PublishedDraft': 'Published and Drafts (Default)', - 'PublishedOnly': 'Published only', - 'Archived': 'Archived' -}; - function sameContent(lhs: ContentDto, rhs?: ContentDto): boolean { return lhs === rhs || (!!lhs && !!rhs && lhs.id === rhs.id && lhs.version === rhs.version); } @@ -87,14 +84,14 @@ export abstract class ContentsStateBase extends State { this.changes.pipe(map(x => !!x.isLoaded), distinctUntilChanged()); - public isArchive = - this.changes.pipe(map(x => x.status === 'Archived'), - distinctUntilChanged()); - public status = this.changes.pipe(map(x => x.status), distinctUntilChanged()); + public statuses = + this.changes.pipe(map(x => x.statuses), + distinctUntilChanged()); + public canCreateAny = this.changes.pipe(map(x => !!x.canCreate || !!x.canCreateAndPublish), distinctUntilChanged()); @@ -112,7 +109,7 @@ export abstract class ContentsStateBase extends State { private readonly contentsService: ContentsService, private readonly dialogs: DialogService ) { - super({ contents: ImmutableArray.of(), contentsPager: new Pager(0), status: 'PublishedDraft' }); + super({ contents: ImmutableArray.of(), contentsPager: new Pager(0) }); } public select(id: string | null): Observable { @@ -157,7 +154,7 @@ export abstract class ContentsStateBase extends State { this.snapshot.contentsPager.skip, this.snapshot.contentsQuery, undefined, this.snapshot.status).pipe( - tap(({ total, items, _links, canCreate, canCreateAndPublish }) => { + tap(({ total, items, _links, statuses, canCreate, canCreateAndPublish }) => { if (isReload) { this.dialogs.notifyInfo('Contents reloaded.'); } @@ -166,12 +163,29 @@ export abstract class ContentsStateBase extends State { const contents = ImmutableArray.of(items); const contentsPager = s.contentsPager.setCount(total); + statuses = s.statuses || statuses; + + const status = + s.statuses ? + s.status : + statuses; + let selectedContent = s.selectedContent; if (selectedContent) { selectedContent = contents.find(x => x.id === selectedContent!.id) || selectedContent; } - return { ...s, contents, contentsPager, selectedContent, isLoaded: true, _links, canCreate, canCreateAndPublish }; + return { ...s, + canCreate, + canCreateAndPublish, + contents, + contentsPager, + isLoaded: true, + selectedContent, + status, + statuses, + _links + }; }); })); } @@ -298,14 +312,14 @@ export abstract class ContentsStateBase extends State { } } - public filterStatus(status: ContentQueryStatus): Observable { - this.next(s => ({ ...s, contentsPager: new Pager(0), contentsQuery: undefined, status })); + public filterStatus(status: string[]): Observable { + this.next(s => ({ ...s, contentsPager: new Pager(0), status })); return this.loadInternal(); } - public search(query?: string): Observable { - this.next(s => ({ ...s, contentsPager: new Pager(0), contentsQuery: query })); + public search(contentsQuery?: string): Observable { + this.next(s => ({ ...s, contentsPager: new Pager(0), contentsQuery })); return this.loadInternal(); }