Browse Source

Archive feature and bugfixes.

pull/107/head
Sebastian Stehle 9 years ago
parent
commit
0fcb6b139d
  1. 2
      src/Squidex/Controllers/Api/Schemas/SchemasController.cs
  2. 11
      src/Squidex/app/features/content/pages/content/content-page.component.html
  3. 10
      src/Squidex/app/features/content/pages/content/content-page.component.ts
  4. 18
      src/Squidex/app/features/content/pages/contents/contents-page.component.html
  5. 78
      src/Squidex/app/features/content/pages/contents/contents-page.component.ts
  6. 2
      src/Squidex/app/features/content/pages/contents/search-form.component.html
  7. 3
      src/Squidex/app/features/content/pages/contents/search-form.component.ts
  8. 2
      src/Squidex/app/features/content/pages/messages.ts
  9. 12
      src/Squidex/app/features/content/shared/content-item.component.html
  10. 6
      src/Squidex/app/features/content/shared/content-item.component.ts
  11. 4
      src/Squidex/app/features/content/shared/references-editor.component.ts
  12. 2
      src/Squidex/app/shared/services/contents.service.ts

2
src/Squidex/Controllers/Api/Schemas/SchemasController.cs

@ -125,7 +125,7 @@ namespace Squidex.Controllers.Api.Schemas
var context = await CommandBus.PublishAsync(command); var context = await CommandBus.PublishAsync(command);
var result = context.Result<EntityCreatedResult<Guid>>(); var result = context.Result<EntityCreatedResult<Guid>>();
var response = new EntityCreatedDto { Id = command.Name, Version = result.Version }; var response = new EntityCreatedDto { Id = command.SchemaId.ToString(), Version = result.Version };
return CreatedAtAction(nameof(GetSchema), new { name = request.Name }, response); return CreatedAtAction(nameof(GetSchema), new { name = request.Name }, response);
} }

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

@ -4,7 +4,7 @@
<sqx-panel panelWidth="53rem"> <sqx-panel panelWidth="53rem">
<div class="panel-header"> <div class="panel-header">
<div class="panel-title-row"> <div class="panel-title-row">
<div class="float-right"> <div class="float-right" *ngIf="!content || !content.isArchived">
<span *ngIf="isNewMode"> <span *ngIf="isNewMode">
<button type="button" class="btn btn-secondary" (click)="saveAsDraft()" title="CTRL + S"> <button type="button" class="btn btn-secondary" (click)="saveAsDraft()" title="CTRL + S">
Save as Draft Save as Draft
@ -19,16 +19,19 @@
Save Save
</button> </button>
</span> </span>
</div>
<sqx-shortcut keys="ctrl+s" (trigger)="saveAndPublish()"></sqx-shortcut> <sqx-shortcut keys="ctrl+s" (trigger)="saveAndPublish()"></sqx-shortcut>
</div>
<h3 class="panel-title" *ngIf="isNewMode"> <h3 class="panel-title" *ngIf="isNewMode">
New Content New Content
</h3> </h3>
<h3 class="panel-title" *ngIf="!isNewMode"> <h3 class="panel-title" *ngIf="!isNewMode && !content.isArchived">
Edit Content Edit Content
</h3> </h3>
<h3 class="panel-title" *ngIf="!isNewMode && content.isArchived">
Show Content
</h3>
</div> </div>
<a class="panel-close" sqxParentLink> <a class="panel-close" sqxParentLink>

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

@ -12,7 +12,7 @@ import { Observable, Subscription } from 'rxjs';
import { import {
ContentCreated, ContentCreated,
ContentDeleted, ContentRemoved,
ContentUpdated, ContentUpdated,
ContentVersionSelected ContentVersionSelected
} from './../messages'; } from './../messages';
@ -40,10 +40,10 @@ import {
export class ContentPageComponent extends AppComponentBase implements CanComponentDeactivate, OnDestroy, OnInit { export class ContentPageComponent extends AppComponentBase implements CanComponentDeactivate, OnDestroy, OnInit {
private contentDeletedSubscription: Subscription; private contentDeletedSubscription: Subscription;
private contentVersionSelectedSubscription: Subscription; private contentVersionSelectedSubscription: Subscription;
private content: ContentDto;
public schema: SchemaDetailsDto; public schema: SchemaDetailsDto;
public content: ContentDto;
public contentFormSubmitted = false; public contentFormSubmitted = false;
public contentForm: FormGroup; public contentForm: FormGroup;
@ -78,7 +78,7 @@ export class ContentPageComponent extends AppComponentBase implements CanCompone
}); });
this.contentDeletedSubscription = this.contentDeletedSubscription =
this.messageBus.of(ContentDeleted) this.messageBus.of(ContentRemoved)
.subscribe(message => { .subscribe(message => {
if (this.content && message.content.id === this.content.id) { if (this.content && message.content.id === this.content.id) {
this.router.navigate(['../'], { relativeTo: this.route }); this.router.navigate(['../'], { relativeTo: this.route });
@ -232,6 +232,10 @@ export class ContentPageComponent extends AppComponentBase implements CanCompone
fieldForm.controls['iv'].setValue(fieldValue['iv']); fieldForm.controls['iv'].setValue(fieldValue['iv']);
} }
} }
if (this.content.isArchived) {
this.contentForm.disable();
}
} }
} }
} }

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

@ -21,7 +21,13 @@
</form> </form>
<div class="dropdown-menu" *sqxModalView="searchModal" closeAlways="true" [sqxModalTarget]="searchInput" position="right"> <div class="dropdown-menu" *sqxModalView="searchModal" closeAlways="true" [sqxModalTarget]="searchInput" position="right">
<sqx-search-form (queryChanged)="contentsFilter.setValue($event, { emitEvent: false })" [query]="contentsFilter.value"></sqx-search-form> <sqx-search-form
[canArchive]="!isReadOnly"
(queryChanged)="contentsFilter.setValue($event, { emitEvent: false })"
[query]="contentsFilter.value"
(archivedChanged)="updateArchive($event)"
[archived]="isArchive">
</sqx-search-form>
</div> </div>
<span *ngIf="!isReadOnly && languages.length > 1"> <span *ngIf="!isReadOnly && languages.length > 1">
@ -33,12 +39,16 @@
</button> </button>
</div> </div>
<h3 class="panel-title" *ngIf="!isReadOnly"> <h3 class="panel-title" *ngIf="!isReadOnly && !isArchive">
Contents Contents
</h3> </h3>
<h3 class="panel-title" *ngIf="isArchive">
Archive
</h3>
<h3 class="panel-title" *ngIf="isReadOnly"> <h3 class="panel-title" *ngIf="isReadOnly">
References Refs
</h3> </h3>
</div> </div>
@ -82,6 +92,8 @@
[schema]="schema" [schema]="schema"
(unpublishing)="unpublishContent(content)" (unpublishing)="unpublishContent(content)"
(publishing)="publishContent(content)" (publishing)="publishContent(content)"
(archiving)="archiveContent(content)"
(restoring)="restoreContent(content)"
(deleting)="deleteContent(content)"></tr> (deleting)="deleteContent(content)"></tr>
<tr class="spacer"></tr> <tr class="spacer"></tr>
</ng-template> </ng-template>

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

@ -12,7 +12,7 @@ import { Subscription } from 'rxjs';
import { import {
ContentCreated, ContentCreated,
ContentDeleted, ContentRemoved,
ContentUpdated ContentUpdated
} from './../messages'; } from './../messages';
@ -57,6 +57,7 @@ export class ContentsPageComponent extends AppComponentBase implements OnDestroy
public languageParameter: string; public languageParameter: string;
public isReadOnly = false; public isReadOnly = false;
public isArchive = false;
public columnWidth: number; public columnWidth: number;
@ -112,13 +113,6 @@ export class ContentsPageComponent extends AppComponentBase implements OnDestroy
return { content, schemaId: this.schema.id }; return { content, schemaId: this.schema.id };
} }
public search() {
this.contentsQuery = this.contentsFilter.value;
this.contentsPager = new Pager(0);
this.load();
}
public publishContent(content: ContentDto) { public publishContent(content: ContentDto) {
this.appNameOnce() this.appNameOnce()
.switchMap(app => this.contentsService.publishContent(app, this.schema.name, content.id, content.version)) .switchMap(app => this.contentsService.publishContent(app, this.schema.name, content.id, content.version))
@ -139,14 +133,35 @@ export class ContentsPageComponent extends AppComponentBase implements OnDestroy
}); });
} }
public archiveContent(content: ContentDto) {
this.appNameOnce()
.switchMap(app => this.contentsService.archiveContent(app, this.schema.name, content.id, content.version))
.subscribe(() => {
content = content.archive(this.authService.user!.token);
this.removeContent(content);
}, error => {
this.notifyError(error);
});
}
public restoreContent(content: ContentDto) {
this.appNameOnce()
.switchMap(app => this.contentsService.restoreContent(app, this.schema.name, content.id, content.version))
.subscribe(() => {
content = content.restore(this.authService.user!.token);
this.removeContent(content);
}, error => {
this.notifyError(error);
});
}
public deleteContent(content: ContentDto) { public deleteContent(content: ContentDto) {
this.appNameOnce() this.appNameOnce()
.switchMap(app => this.contentsService.deleteContent(app, this.schema.name, content.id, content.version)) .switchMap(app => this.contentsService.deleteContent(app, this.schema.name, content.id, content.version))
.subscribe(() => { .subscribe(() => {
this.contentItems = this.contentItems.removeAll(x => x.id === content.id); this.removeContent(content);
this.contentsPager = this.contentsPager.decrementCount();
this.emitContentDeleted(content);
}, error => { }, error => {
this.notifyError(error); this.notifyError(error);
}); });
@ -154,7 +169,7 @@ export class ContentsPageComponent extends AppComponentBase implements OnDestroy
public load(showInfo = false) { public load(showInfo = false) {
this.appNameOnce() this.appNameOnce()
.switchMap(app => this.contentsService.getContents(app, this.schema.name, this.contentsPager.pageSize, this.contentsPager.skip, this.contentsQuery)) .switchMap(app => this.contentsService.getContents(app, this.schema.name, this.contentsPager.pageSize, this.contentsPager.skip, this.contentsQuery, null, this.isArchive))
.subscribe(dtos => { .subscribe(dtos => {
this.contentItems = ImmutableArray.of(dtos.items); this.contentItems = ImmutableArray.of(dtos.items);
this.contentsPager = this.contentsPager.setCount(dtos.total); this.contentsPager = this.contentsPager.setCount(dtos.total);
@ -167,8 +182,22 @@ export class ContentsPageComponent extends AppComponentBase implements OnDestroy
}); });
} }
public selectLanguage(language: AppLanguageDto) { public updateArchive(isArchive: boolean) {
this.languageSelected = language; this.contentsQuery = this.contentsFilter.value;
this.contentsPager = new Pager(0);
this.isArchive = isArchive;
this.searchModal.hide();
this.load();
}
public search() {
this.contentsQuery = this.contentsFilter.value;
this.contentsPager = new Pager(0);
this.load();
} }
public goNext() { public goNext() {
@ -183,8 +212,12 @@ export class ContentsPageComponent extends AppComponentBase implements OnDestroy
this.load(); this.load();
} }
private emitContentDeleted(content: ContentDto) { public selectLanguage(language: AppLanguageDto) {
this.messageBus.emit(new ContentDeleted(content)); this.languageSelected = language;
}
private emitContentRemoved(content: ContentDto) {
this.messageBus.emit(new ContentRemoved(content));
} }
private resetContents() { private resetContents() {
@ -196,6 +229,13 @@ export class ContentsPageComponent extends AppComponentBase implements OnDestroy
this.loadFields(); this.loadFields();
} }
private removeContent(content: ContentDto) {
this.contentItems = this.contentItems.removeAll(x => x.id === content.id);
this.contentsPager = this.contentsPager.decrementCount();
this.emitContentRemoved(content);
}
private loadFields() { private loadFields() {
this.contentFields = this.schema.fields.filter(x => x.properties.isListField); this.contentFields = this.schema.fields.filter(x => x.properties.isListField);
@ -203,6 +243,10 @@ export class ContentsPageComponent extends AppComponentBase implements OnDestroy
this.contentFields = [this.schema.fields[0]]; this.contentFields = [this.schema.fields[0]];
} }
if (this.contentFields.length === 0) {
this.contentFields = [<any>{}];
}
if (this.contentFields.length > 0) { if (this.contentFields.length > 0) {
this.columnWidth = 100 / this.contentFields.length; this.columnWidth = 100 / this.contentFields.length;
} else { } else {

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

@ -25,7 +25,7 @@
</div> </div>
</div> </div>
<div class="form-check"> <div class="form-check" *ngIf="canArchive">
<label class="form-check-label"> <label class="form-check-label">
<input class="form-check-input" type="checkbox" [ngModel]="archived" (ngModelChange)="archivedChanged.emit($event)" /> Archived items <input class="form-check-input" type="checkbox" [ngModel]="archived" (ngModelChange)="archivedChanged.emit($event)" /> Archived items
</label> </label>

3
src/Squidex/app/features/content/pages/contents/search-form.component.ts

@ -28,6 +28,9 @@ export class SearchFormComponent implements OnChanges {
@Output() @Output()
public archivedChanged = new EventEmitter<boolean>(); public archivedChanged = new EventEmitter<boolean>();
@Input()
public canArchive = true;
public searchForm = public searchForm =
this.formBuilder.group({ this.formBuilder.group({
odataOrderBy: '', odataOrderBy: '',

2
src/Squidex/app/features/content/pages/messages.ts

@ -21,7 +21,7 @@ export class ContentUpdated {
} }
} }
export class ContentDeleted { export class ContentRemoved {
constructor( constructor(
public readonly content: ContentDto public readonly content: ContentDto
) { ) {

12
src/Squidex/app/features/content/shared/content-item.component.html

@ -17,13 +17,19 @@
<i class="icon-dots"></i> <i class="icon-dots"></i>
</button> </button>
<div class="dropdown-menu" *sqxModalView="dropdown" closeAlways="true" [sqxModalTarget]="optionsButton" position="right" [@fade]> <div class="dropdown-menu" *sqxModalView="dropdown" closeAlways="true" [sqxModalTarget]="optionsButton" position="right" [@fade]>
<a class="dropdown-item" (click)="publishing.emit(); $event.stopPropagation()" *ngIf="!content.isPublished"> <a class="dropdown-item" (click)="publishing.emit(); $event.stopPropagation()" *ngIf="!content.isPublished && !content.isArchived">
Publish Publish
</a> </a>
<a class="dropdown-item" (click)="unpublishing.emit(); $event.stopPropagation()" *ngIf="content.isPublished"> <a class="dropdown-item" (click)="unpublishing.emit(); $event.stopPropagation()" *ngIf="content.isPublished && !content.isArchived">
Unpublish Unpublish
</a> </a>
<a class="dropdown-item dropdown-item-delete" <a class="dropdown-item" (click)="archiving.emit(); $event.stopPropagation()" *ngIf="!content.isArchived">
Archive
</a>
<a class="dropdown-item" (click)="restoring.emit(); $event.stopPropagation()" *ngIf="content.isArchived">
Restore
</a>
<a class="dropdown-item dropdown-item-delete" *ngIf="content.isArchived"
(sqxConfirmClick)="deleting.emit()" (sqxConfirmClick)="deleting.emit()"
confirmTitle="Delete content" confirmTitle="Delete content"
confirmText="Do you really want to delete the content?"> confirmText="Do you really want to delete the content?">

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

@ -35,6 +35,12 @@ export class ContentItemComponent extends AppComponentBase implements OnInit, On
@Output() @Output()
public unpublishing = new EventEmitter<ContentDto>(); public unpublishing = new EventEmitter<ContentDto>();
@Output()
public archiving = new EventEmitter<ContentDto>();
@Output()
public restoring = new EventEmitter<ContentDto>();
@Output() @Output()
public deleting = new EventEmitter<ContentDto>(); public deleting = new EventEmitter<ContentDto>();

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

@ -148,6 +148,10 @@ export class ReferencesEditorComponent extends AppComponentBase implements Contr
this.contentFields = [this.schema.fields[0]]; this.contentFields = [this.schema.fields[0]];
} }
if (this.contentFields.length === 0) {
this.contentFields = [<any>{}];
}
if (this.contentFields.length > 0) { if (this.contentFields.length > 0) {
this.columnWidth = 100 / this.contentFields.length; this.columnWidth = 100 / this.contentFields.length;
} else { } else {

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

@ -160,7 +160,7 @@ export class ContentsService {
return new ContentDto( return new ContentDto(
item.id, item.id,
item.isPublished, item.isPublished,
item.isDeleted === true, item.isArchived === true,
item.createdBy, item.createdBy,
item.lastModifiedBy, item.lastModifiedBy,
DateTime.parseISO_UTC(item.created), DateTime.parseISO_UTC(item.created),

Loading…
Cancel
Save