Browse Source

Temp commit.

pull/364/head
Sebastian Stehle 7 years ago
parent
commit
5f5a01b6c0
  1. 10
      src/Squidex/Areas/Api/Controllers/Assets/Models/AssetsDto.cs
  2. 8
      src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs
  3. 11
      src/Squidex/Areas/Api/Controllers/Contents/Models/ContentsDto.cs
  4. 2
      src/Squidex/Areas/Api/Controllers/Users/Models/UsersDto.cs
  5. 7
      src/Squidex/app/features/administration/pages/users/user-page.component.ts
  6. 10
      src/Squidex/app/features/content/pages/content/content-page.component.ts
  7. 2
      src/Squidex/app/features/content/pages/contents/contents-page.component.html
  8. 6
      src/Squidex/app/features/content/pages/contents/contents-page.component.ts
  9. 2
      src/Squidex/app/features/content/shared/contents-selector.component.html
  10. 6
      src/Squidex/app/features/content/shared/contents-selector.component.ts
  11. 6
      src/Squidex/app/features/rules/pages/rules/rule-wizard.component.ts
  12. 2
      src/Squidex/app/features/schemas/pages/schema/forms/field-form.component.ts
  13. 5
      src/Squidex/app/features/schemas/pages/schema/schema-edit-form.component.ts
  14. 5
      src/Squidex/app/features/schemas/pages/schema/schema-scripts-form.component.ts
  15. 5
      src/Squidex/app/features/settings/pages/languages/language.component.ts
  16. 5
      src/Squidex/app/features/settings/pages/patterns/pattern.component.ts
  17. 5
      src/Squidex/app/features/settings/pages/roles/role.component.ts
  18. 12
      src/Squidex/app/framework/state.ts
  19. 2
      src/Squidex/app/shared/components/asset-dialog.component.html
  20. 13
      src/Squidex/app/shared/components/asset-dialog.component.ts
  21. 12
      src/Squidex/app/shared/components/search-form.component.html
  22. 6
      src/Squidex/app/shared/components/search-form.component.ts
  23. 15
      src/Squidex/app/shared/services/contents.service.spec.ts
  24. 23
      src/Squidex/app/shared/services/contents.service.ts
  25. 8
      src/Squidex/app/shared/state/contents.forms.ts
  26. 52
      src/Squidex/app/shared/state/contents.state.ts

10
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 public sealed class AssetsDto : Resource
{ {
/// <summary> /// <summary>
/// The assets. /// The total number of assets.
/// </summary> /// </summary>
[Required] public long Total { get; set; }
public AssetDto[] Items { get; set; }
/// <summary> /// <summary>
/// The total number of assets. /// The assets.
/// </summary> /// </summary>
public long Total { get; set; } [Required]
public AssetDto[] Items { get; set; }
public string ToEtag() public string ToEtag()
{ {

8
src/Squidex/Areas/Api/Controllers/Contents/ContentsController.cs

@ -120,9 +120,9 @@ namespace Squidex.Areas.Api.Controllers.Contents
[ProducesResponseType(typeof(ContentsDto), 200)] [ProducesResponseType(typeof(ContentsDto), 200)]
[ApiPermission] [ApiPermission]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> GetAllContents(string app, [FromQuery] string ids, [FromQuery] string status = null) public async Task<IActionResult> 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); 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)] [ProducesResponseType(typeof(ContentsDto), 200)]
[ApiPermission] [ApiPermission]
[ApiCosts(1)] [ApiCosts(1)]
public async Task<IActionResult> GetContents(string app, string name, [FromQuery] string ids = null, [FromQuery] string status = null) public async Task<IActionResult> 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())); var result = await contentQuery.QueryAsync(context, name, Q.Empty.WithIds(ids).WithODataQuery(Request.QueryString.ToString()));

11
src/Squidex/Areas/Api/Controllers/Contents/Models/ContentsDto.cs

@ -6,6 +6,7 @@
// ========================================================================== // ==========================================================================
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using Squidex.Domain.Apps.Core.Contents; using Squidex.Domain.Apps.Core.Contents;
using Squidex.Domain.Apps.Entities; using Squidex.Domain.Apps.Entities;
@ -26,8 +27,15 @@ namespace Squidex.Areas.Api.Controllers.Contents.Models
/// <summary> /// <summary>
/// The content items. /// The content items.
/// </summary> /// </summary>
[Required]
public ContentDto[] Items { get; set; } public ContentDto[] Items { get; set; }
/// <summary>
/// All available statuses.
/// </summary>
[Required]
public string[] Statuses { get; set; }
public string ToEtag() public string ToEtag()
{ {
return Items.ToManyEtag(Total); return Items.ToManyEtag(Total);
@ -54,7 +62,8 @@ namespace Squidex.Areas.Api.Controllers.Contents.Models
var result = new ContentsDto var result = new ContentsDto
{ {
Total = contents.Total, 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); return result.CreateLinks(controller, app, schema);

2
src/Squidex/Areas/Api/Controllers/Users/Models/UsersDto.cs

@ -6,6 +6,7 @@
// ========================================================================== // ==========================================================================
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq; using System.Linq;
using Squidex.Domain.Users; using Squidex.Domain.Users;
using Squidex.Shared; using Squidex.Shared;
@ -23,6 +24,7 @@ namespace Squidex.Areas.Api.Controllers.Users.Models
/// <summary> /// <summary>
/// The users. /// The users.
/// </summary> /// </summary>
[Required]
public UserDto[] Items { get; set; } public UserDto[] Items { get; set; }
public static UsersDto FromResults(IEnumerable<UserWithClaims> items, long total, ApiController controller) public static UsersDto FromResults(IEnumerable<UserWithClaims> items, long total, ApiController controller)

7
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!; this.user = selectedUser!;
if (selectedUser) { if (selectedUser) {
this.userForm.load(selectedUser);
this.isEditable = this.user.canUpdate; this.isEditable = this.user.canUpdate;
if (!this.isEditable) { this.userForm.load(selectedUser);
this.userForm.form.disable(); this.userForm.setEnabled(this.isEditable);
}
} }
})); }));
} }

10
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) { 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() { public discardChanges() {
@ -219,13 +220,12 @@ export class ContentPageComponent extends ResourceOwner implements CanComponentD
if (compare) { if (compare) {
if (this.contentFormCompare === null) { if (this.contentFormCompare === null) {
this.contentFormCompare = new EditContentForm(this.schema, this.languages); 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.loadContent(this.content.dataDraft);
this.contentForm.loadContent(this.content.dataDraft, isArchive);
} else { } else {
if (this.contentFormCompare) { if (this.contentFormCompare) {
this.contentFormCompare = null; this.contentFormCompare = null;

2
src/Squidex/app/features/content/pages/contents/contents-page.component.html

@ -21,7 +21,7 @@
[queries]="schemaQueries" [queries]="schemaQueries"
(statusChange)="filterStatus($event)" (statusChange)="filterStatus($event)"
[status]="contentsState.status | async" [status]="contentsState.status | async"
[statuses]="statuses" [statuses]="contentsState.statuses | async"
expandable="true" expandable="true"
enableArchive="true" enableArchive="true"
enableShortcut="true"> enableShortcut="true">

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

@ -11,9 +11,7 @@ import { onErrorResumeNext, switchMap, tap } from 'rxjs/operators';
import { import {
AppLanguageDto, AppLanguageDto,
AppsState, AppsState,
CONTENT_STATUSES,
ContentDto, ContentDto,
ContentQueryStatus,
ContentsState, ContentsState,
FilterState, FilterState,
ImmutableArray, ImmutableArray,
@ -47,8 +45,6 @@ export class ContentsPageComponent extends ResourceOwner implements OnInit {
public nextStatuses: string[] = []; public nextStatuses: string[] = [];
public statuses = CONTENT_STATUSES;
public language: AppLanguageDto; public language: AppLanguageDto;
public languages: ImmutableArray<AppLanguageDto>; public languages: ImmutableArray<AppLanguageDto>;
@ -144,7 +140,7 @@ export class ContentsPageComponent extends ResourceOwner implements OnInit {
.subscribe(); .subscribe();
} }
public filterStatus(status: ContentQueryStatus) { public filterStatus(status: string[]) {
this.contentsState.filterStatus(status); this.contentsState.filterStatus(status);
} }

2
src/Squidex/app/features/content/shared/contents-selector.component.html

@ -15,7 +15,7 @@
[filter]="filter" [filter]="filter"
(statusChange)="filterStatus($event)" (statusChange)="filterStatus($event)"
[status]="contentsState.status | async" [status]="contentsState.status | async"
[statuses]="statuses" [statuses]="contentsState.statuses | async"
(querySubmit)="search()" (querySubmit)="search()"
expandable="true"> expandable="true">
</sqx-search-form> </sqx-search-form>

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

@ -8,9 +8,7 @@
import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { import {
CONTENT_STATUSES,
ContentDto, ContentDto,
ContentQueryStatus,
FilterState, FilterState,
LanguageDto, LanguageDto,
ManualContentsState, ManualContentsState,
@ -48,8 +46,6 @@ export class ContentsSelectorComponent implements OnInit {
public filter = new FilterState(); public filter = new FilterState();
public statuses = CONTENT_STATUSES;
public selectedItems: { [id: string]: ContentDto; } = {}; public selectedItems: { [id: string]: ContentDto; } = {};
public selectionCount = 0; public selectionCount = 0;
@ -74,7 +70,7 @@ export class ContentsSelectorComponent implements OnInit {
this.contentsState.search(this.filter.apiFilter); this.contentsState.search(this.filter.apiFilter);
} }
public filterStatus(status: ContentQueryStatus) { public filterStatus(status: string[]) {
this.contentsState.filterStatus(status); this.contentsState.filterStatus(status);
} }

6
src/Squidex/app/features/rules/pages/rules/rule-wizard.component.ts

@ -79,11 +79,9 @@ export class RuleWizardComponent implements AfterViewInit, OnInit {
} }
public ngAfterViewInit() { public ngAfterViewInit() {
if (!this.isEditable) { this.actionForm.setEnabled(this.isEditable);
this.actionForm.form.disable();
this.triggerForm.form.disable(); this.triggerForm.setEnabled(this.isEditable);
}
} }
public emitComplete() { public emitComplete() {

2
src/Squidex/app/features/schemas/pages/schema/forms/field-form.component.ts

@ -76,6 +76,8 @@ export class FieldFormComponent implements AfterViewInit {
public ngAfterViewInit() { public ngAfterViewInit() {
if (!this.isEditable) { if (!this.isEditable) {
this.editForm.disable(); this.editForm.disable();
} else {
this.editForm.enable();
} }
} }

5
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.isEditable = this.schema.canUpdate;
this.editForm.load(this.schema.properties); this.editForm.load(this.schema.properties);
this.editForm.setEnabled(this.isEditable);
if (!this.isEditable) {
this.editForm.form.disable();
}
} }
public emitComplete() { public emitComplete() {

5
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.isEditable = this.schema.canUpdateScripts;
this.editForm.load(this.schema.scripts); this.editForm.load(this.schema.scripts);
this.editForm.setEnabled(this.isEditable);
if (!this.isEditable) {
this.editForm.form.disable();
}
} }
public emitComplete() { public emitComplete() {

5
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.isEditable = this.language.canUpdate;
this.editForm.load(this.language); this.editForm.load(this.language);
this.editForm.setEnabled(this.isEditable);
if (!this.isEditable) {
this.editForm.form.disable();
}
this.otherLanguage = this.fallbackLanguagesNew.at(0); this.otherLanguage = this.fallbackLanguagesNew.at(0);
} }

5
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.isDeletable = this.pattern && this.pattern.canDelete;
this.editForm.load(this.pattern); this.editForm.load(this.pattern);
this.editForm.setEnabled(this.isEditable);
if (!this.isEditable) {
this.editForm.form.disable();
}
} }
public cancel() { public cancel() {

5
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.isEditable = this.role.canUpdate;
this.editForm.load(this.role.permissions); this.editForm.load(this.role.permissions);
this.editForm.setEnabled(this.isEditable);
if (!this.isEditable) {
this.editForm.form.disable();
}
} }
public toggleEditing() { public toggleEditing() {

12
src/Squidex/app/framework/state.ts

@ -35,14 +35,22 @@ export class Form<T extends AbstractControl, V> {
) { ) {
} }
protected disable() { public setEnabled(isEnabled: boolean) {
this.form.disable(); if (isEnabled) {
this.enable();
} else {
this.disable();
}
} }
protected enable() { protected enable() {
this.form.enable(); this.form.enable();
} }
protected disable() {
this.form.disable();
}
protected setValue(value?: V) { protected setValue(value?: V) {
if (value) { if (value) {
this.form.reset(this.transformLoad(value)); this.form.reset(this.transformLoad(value));

2
src/Squidex/app/shared/components/asset-dialog.component.html

@ -38,7 +38,7 @@
<ng-container footer> <ng-container footer>
<button type="reset" class="float-left btn btn-secondary" (click)="emitCancel()">Cancel</button> <button type="reset" class="float-left btn btn-secondary" (click)="emitCancel()">Cancel</button>
<button type="submit" class="float-right btn btn-primary" *ngIf="!isReadOnly">Save</button> <button type="submit" class="float-right btn btn-primary" *ngIf="isEditable">Save</button>
</ng-container> </ng-container>
</sqx-modal-dialog> </sqx-modal-dialog>
</form> </form>

13
src/Squidex/app/shared/components/asset-dialog.component.ts

@ -35,7 +35,7 @@ export class AssetDialogComponent extends StatefulComponent implements OnInit {
@Output() @Output()
public complete = new EventEmitter<AssetDto>(); public complete = new EventEmitter<AssetDto>();
public isReadOnly = false; public isEditable = false;
public annotateForm = new AnnotateAssetForm(this.formBuilder); public annotateForm = new AnnotateAssetForm(this.formBuilder);
@ -52,13 +52,10 @@ export class AssetDialogComponent extends StatefulComponent implements OnInit {
} }
public ngOnInit() { public ngOnInit() {
this.annotateForm.load(this.asset); this.isEditable = this.asset.canUpdate;
this.isReadOnly = !this.asset.canUpdate;
if (this.isReadOnly) { this.annotateForm.load(this.asset);
this.annotateForm.form.disable(); this.annotateForm.setEnabled(!this.isEditable);
}
} }
public generateSlug() { public generateSlug() {
@ -74,7 +71,7 @@ export class AssetDialogComponent extends StatefulComponent implements OnInit {
} }
public annotateAsset() { public annotateAsset() {
if (this.isReadOnly) { if (!this.isEditable) {
return; return;
} }

12
src/Squidex/app/shared/components/search-form.component.html

@ -69,14 +69,12 @@
</div> </div>
</div> </div>
<div class="form-group row" *ngIf="statuses"> <div class="form-group row" *ngIf="statuses && statuses.length > 0">
<div class="col-10 offset-2"> <div class="col-10 offset-2">
<div class="form-check" *ngFor="let key of statuses | sqxKeys"> <sqx-checkbox-group [values]="statuses"
<input class="form-check-input" type="radio" name="status" id="status_{{key}}" [value]="key" [ngModel]="status" (ngModelChange)="statusChange.emit($event)" /> [ngModel]="status"
<label class="form-check-label" for="status_{{key}}"> (ngModelChange)="statusChange.emit($event)">
{{statuses[key]}} </sqx-checkbox-group>
</label>
</div>
</div> </div>
</div> </div>

6
src/Squidex/app/shared/components/search-form.component.ts

@ -40,13 +40,13 @@ export class SearchFormComponent implements OnInit {
public filter: FilterState; public filter: FilterState;
@Input() @Input()
public statuses: { [status: string]: string }; public statuses: [] = [];
@Input() @Input()
public status: string; public status: string[];
@Output() @Output()
public statusChange = new EventEmitter<string>(); public statusChange = new EventEmitter<[]>();
@Input() @Input()
public schemaName = ''; public schemaName = '';

15
src/Squidex/app/shared/services/contents.service.spec.ts

@ -47,11 +47,11 @@ describe('ContentsService', () => {
let contents: ContentsDto; 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; 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.method).toEqual('GET');
expect(req.request.headers.get('If-Match')).toBeNull(); expect(req.request.headers.get('If-Match')).toBeNull();
@ -61,11 +61,12 @@ describe('ContentsService', () => {
items: [ items: [
contentResponse(12), contentResponse(12),
contentResponse(13) contentResponse(13)
] ],
es: ['Draft', 'Published']
}); });
expect(contents!).toEqual( expect(contents!).toEqual(
new ContentsDto(10, [ new ContentsDto(['Draft', 'Published'], 10, [
createContent(12), createContent(12),
createContent(13) createContent(13)
])); ]));
@ -76,7 +77,7 @@ describe('ContentsService', () => {
contentsService.getContents('my-app', 'my-schema', 17, 13, 'my-query').subscribe(); 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.method).toEqual('GET');
expect(req.request.headers.get('If-Match')).toBeNull(); 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(); 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.method).toEqual('GET');
expect(req.request.headers.get('If-Match')).toBeNull(); 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(); 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.method).toEqual('GET');
expect(req.request.headers.get('If-Match')).toBeNull(); expect(req.request.headers.get('If-Match')).toBeNull();

23
src/Squidex/app/shared/services/contents.service.ts

@ -35,6 +35,15 @@ export class ScheduleDto {
} }
export class ContentsDto extends ResultSet<ContentDto> { export class ContentsDto extends ResultSet<ContentDto> {
constructor(
public readonly statuses: string[],
total: number,
items: ContentDto[],
links?: ResourceLinks
) {
super(total, items, links);
}
public get canCreate() { public get canCreate() {
return hasAnyLink(this._links, 'create'); return hasAnyLink(this._links, 'create');
} }
@ -80,8 +89,6 @@ export class ContentDto {
} }
} }
export type ContentQueryStatus = 'Archived' | 'PublishedOnly' | 'PublishedDraft';
@Injectable() @Injectable()
export class ContentsService { export class ContentsService {
constructor( 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<ContentsDto> { public getContents(appName: string, schemaName: string, take: number, skip: number, query?: string, ids?: string[], status?: string[]): Observable<ContentsDto> {
const queryParts: string[] = []; const queryParts: string[] = [];
if (query && query.length > 0) { if (query && query.length > 0) {
@ -117,18 +124,20 @@ export class ContentsService {
} }
if (status) { if (status) {
queryParts.push(`status=${status}`); for (let s of status) {
queryParts.push(`status=${s}`);
}
} }
const fullQuery = queryParts.join('&'); const fullQuery = queryParts.join('&');
const url = this.apiUrl.buildUrl(`/api/content/${appName}/${schemaName}?${fullQuery}`); const url = this.apiUrl.buildUrl(`/api/content/${appName}/${schemaName}?${fullQuery}`);
return this.http.get<{ total: number, items: [] } & Resource>(url).pipe( return this.http.get<{ total: number, items: [], statuses: string[] } & Resource>(url).pipe(
map(({ total, items, _links }) => { map(({ total, items, statuses, _links }) => {
const contents = items.map(x => parseContent(x)); 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.')); pretifyError('Failed to load contents. Please reload.'));
} }

8
src/Squidex/app/shared/state/contents.forms.ts

@ -408,7 +408,7 @@ export class EditContentForm extends Form<FormGroup, any> {
} }
} }
public loadContent(value: any, disable: boolean) { public loadContent(value: any) {
for (let field of this.schema.fields) { for (let field of this.schema.fields) {
if (field.isArray && field.nested.length > 0) { if (field.isArray && field.nested.length > 0) {
const fieldForm = <FormGroup>this.form.get(field.name); const fieldForm = <FormGroup>this.form.get(field.name);
@ -445,12 +445,6 @@ export class EditContentForm extends Form<FormGroup, any> {
} }
super.load(value); super.load(value);
if (disable) {
this.disable();
} else {
this.enable();
}
} }
protected enable() { protected enable() {

52
src/Squidex/app/shared/state/contents.state.ts

@ -25,7 +25,7 @@ import { SchemaDto } from './../services/schemas.service';
import { AppsState } from './apps.state'; import { AppsState } from './apps.state';
import { SchemasState } from './schemas.state'; import { SchemasState } from './schemas.state';
import { ContentDto, ContentQueryStatus, ContentsService } from './../services/contents.service'; import { ContentDto, ContentsService } from './../services/contents.service';
interface Snapshot { interface Snapshot {
// The current comments. // The current comments.
@ -40,8 +40,11 @@ interface Snapshot {
// Indicates if the contents are loaded. // Indicates if the contents are loaded.
isLoaded?: boolean; isLoaded?: boolean;
// All statuses.
statuses?: string[];
// Indicates which status is shown. // Indicates which status is shown.
status: ContentQueryStatus; status?: string[];
// The selected content. // The selected content.
selectedContent?: ContentDto | null; selectedContent?: ContentDto | null;
@ -56,12 +59,6 @@ interface Snapshot {
_links?: ResourceLinks; _links?: ResourceLinks;
} }
export const CONTENT_STATUSES = {
'PublishedDraft': 'Published and Drafts (Default)',
'PublishedOnly': 'Published only',
'Archived': 'Archived'
};
function sameContent(lhs: ContentDto, rhs?: ContentDto): boolean { function sameContent(lhs: ContentDto, rhs?: ContentDto): boolean {
return lhs === rhs || (!!lhs && !!rhs && lhs.id === rhs.id && lhs.version === rhs.version); return lhs === rhs || (!!lhs && !!rhs && lhs.id === rhs.id && lhs.version === rhs.version);
} }
@ -87,14 +84,14 @@ export abstract class ContentsStateBase extends State<Snapshot> {
this.changes.pipe(map(x => !!x.isLoaded), this.changes.pipe(map(x => !!x.isLoaded),
distinctUntilChanged()); distinctUntilChanged());
public isArchive =
this.changes.pipe(map(x => x.status === 'Archived'),
distinctUntilChanged());
public status = public status =
this.changes.pipe(map(x => x.status), this.changes.pipe(map(x => x.status),
distinctUntilChanged()); distinctUntilChanged());
public statuses =
this.changes.pipe(map(x => x.statuses),
distinctUntilChanged());
public canCreateAny = public canCreateAny =
this.changes.pipe(map(x => !!x.canCreate || !!x.canCreateAndPublish), this.changes.pipe(map(x => !!x.canCreate || !!x.canCreateAndPublish),
distinctUntilChanged()); distinctUntilChanged());
@ -112,7 +109,7 @@ export abstract class ContentsStateBase extends State<Snapshot> {
private readonly contentsService: ContentsService, private readonly contentsService: ContentsService,
private readonly dialogs: DialogService 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<ContentDto | null> { public select(id: string | null): Observable<ContentDto | null> {
@ -157,7 +154,7 @@ export abstract class ContentsStateBase extends State<Snapshot> {
this.snapshot.contentsPager.skip, this.snapshot.contentsPager.skip,
this.snapshot.contentsQuery, undefined, this.snapshot.contentsQuery, undefined,
this.snapshot.status).pipe( this.snapshot.status).pipe(
tap(({ total, items, _links, canCreate, canCreateAndPublish }) => { tap(({ total, items, _links, statuses, canCreate, canCreateAndPublish }) => {
if (isReload) { if (isReload) {
this.dialogs.notifyInfo('Contents reloaded.'); this.dialogs.notifyInfo('Contents reloaded.');
} }
@ -166,12 +163,29 @@ export abstract class ContentsStateBase extends State<Snapshot> {
const contents = ImmutableArray.of(items); const contents = ImmutableArray.of(items);
const contentsPager = s.contentsPager.setCount(total); const contentsPager = s.contentsPager.setCount(total);
statuses = s.statuses || statuses;
const status =
s.statuses ?
s.status :
statuses;
let selectedContent = s.selectedContent; let selectedContent = s.selectedContent;
if (selectedContent) { if (selectedContent) {
selectedContent = contents.find(x => x.id === selectedContent!.id) || 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<Snapshot> {
} }
} }
public filterStatus(status: ContentQueryStatus): Observable<any> { public filterStatus(status: string[]): Observable<any> {
this.next(s => ({ ...s, contentsPager: new Pager(0), contentsQuery: undefined, status })); this.next(s => ({ ...s, contentsPager: new Pager(0), status }));
return this.loadInternal(); return this.loadInternal();
} }
public search(query?: string): Observable<any> { public search(contentsQuery?: string): Observable<any> {
this.next(s => ({ ...s, contentsPager: new Pager(0), contentsQuery: query })); this.next(s => ({ ...s, contentsPager: new Pager(0), contentsQuery }));
return this.loadInternal(); return this.loadInternal();
} }

Loading…
Cancel
Save