mirror of https://github.com/Squidex/squidex.git
14 changed files with 356 additions and 92 deletions
@ -0,0 +1,40 @@ |
|||||
|
<div dnd-droppable class="droppable category" [allowDrop]="allowDrop" (onDropSuccess)="changeCategory($event.dragData)"> |
||||
|
<div class="drop-indicator"></div> |
||||
|
|
||||
|
<div class="header clearfix"> |
||||
|
<a class="btn btn-sm btn-link" (click)="toggle()"> |
||||
|
<i [class.icon-caret-right]="isOpen" [class.icon-caret-down]="!isOpen"></i> |
||||
|
</a> |
||||
|
|
||||
|
<h3>{{displayName}} ({{schemasForCategory.length}})</h3> |
||||
|
|
||||
|
|
||||
|
<a class="btn btn-sm btn-link float-right" *ngIf="schemasForCategory.length === 0 && !isReadonly" (click)="removing.emit()"> |
||||
|
<i class="icon-bin"></i> |
||||
|
</a> |
||||
|
</div> |
||||
|
|
||||
|
<ul class="nav nav-panel nav-dark nav-dark-bordered flex-column" *ngIf="isOpen" @fade> |
||||
|
<li class="nav-item" *ngFor="let schema of schemasFiltered; trackBy: trackBySchema" dnd-draggable [dragEnabled]="!isReadonly" [dragData]="schema"> |
||||
|
<a class="nav-link" [routerLink]="[schema.name]" routerLinkActive="active"> |
||||
|
<div class="row" *ngIf="!isReadonly"> |
||||
|
<div class="col col-4"> |
||||
|
<span class="schema-name schema-name-accent">{{schema.displayName}}</span> |
||||
|
</div> |
||||
|
<div class="col col-4"> |
||||
|
<span class="schema-user"> |
||||
|
<i class="icon-user"></i> {{schema.lastModifiedBy | sqxUserNameRef}} |
||||
|
</span> |
||||
|
</div> |
||||
|
<div class="col col-4 schema-modified"> |
||||
|
<small class="item-modified">{{schema.lastModified | sqxFromNow}}</small> |
||||
|
|
||||
|
<span class="item-published" [class.unpublished]="!schema.isPublished"></span> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<span class="schema-name" *ngIf="isReadonly">{{schema.displayName}}</span> |
||||
|
</a> |
||||
|
</li> |
||||
|
</ul> |
||||
|
</div> |
||||
@ -0,0 +1,85 @@ |
|||||
|
@import '_mixins'; |
||||
|
@import '_vars'; |
||||
|
|
||||
|
$drag-margin: -8px; |
||||
|
|
||||
|
h3 { |
||||
|
display: inline-block; |
||||
|
} |
||||
|
|
||||
|
.btn { |
||||
|
width: 2rem; |
||||
|
} |
||||
|
|
||||
|
.category { |
||||
|
margin-bottom: 1rem; |
||||
|
} |
||||
|
|
||||
|
.dnd-drag-start { |
||||
|
border: 0; |
||||
|
} |
||||
|
|
||||
|
.droppable { |
||||
|
& { |
||||
|
position: relative; |
||||
|
} |
||||
|
|
||||
|
&.dnd-drag-over, |
||||
|
&.dnd-drag-enter { |
||||
|
& { |
||||
|
border: 0; |
||||
|
} |
||||
|
|
||||
|
.drop-indicator { |
||||
|
display: block; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.drop-indicator { |
||||
|
@include absolute($drag-margin, $drag-margin, $drag-margin, $drag-margin); |
||||
|
border: 2px dashed $color-dark-black; |
||||
|
background: none; |
||||
|
display: none; |
||||
|
pointer-events: none; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
.header { |
||||
|
margin-left: -1rem; |
||||
|
} |
||||
|
|
||||
|
.nav-link { |
||||
|
padding-top: .75rem; |
||||
|
padding-bottom: .75rem; |
||||
|
} |
||||
|
|
||||
|
.schema { |
||||
|
&-name { |
||||
|
@include truncate; |
||||
|
} |
||||
|
|
||||
|
&-name-accent { |
||||
|
color: $color-dark-foreground; |
||||
|
} |
||||
|
|
||||
|
&-modified { |
||||
|
text-align: right; |
||||
|
width: auto; |
||||
|
white-space: nowrap; |
||||
|
padding-left: 0; |
||||
|
} |
||||
|
|
||||
|
&-user { |
||||
|
@include border-radius(1px); |
||||
|
@include truncate; |
||||
|
display: inline-block; |
||||
|
background: $color-dark2-control; |
||||
|
padding: .1rem .25rem; |
||||
|
font-size: .8rem; |
||||
|
font-weight: normal; |
||||
|
margin-left: 10px; |
||||
|
margin-bottom: 2px; |
||||
|
max-width: 100%; |
||||
|
vertical-align: middle; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,99 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. |
||||
|
*/ |
||||
|
|
||||
|
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core'; |
||||
|
|
||||
|
import { |
||||
|
fadeAnimation, |
||||
|
ImmutableArray, |
||||
|
LocalStoreService, |
||||
|
SchemaDetailsDto, |
||||
|
SchemaDto, |
||||
|
SchemasState, |
||||
|
Types |
||||
|
} from '@app/shared/internal'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'sqx-schema-category', |
||||
|
styleUrls: ['./schema-category.component.scss'], |
||||
|
templateUrl: './schema-category.component.html', |
||||
|
animations: [ |
||||
|
fadeAnimation |
||||
|
] |
||||
|
}) |
||||
|
export class SchemaCategoryComponent implements OnInit, OnChanges { |
||||
|
@Output() |
||||
|
public removing = new EventEmitter(); |
||||
|
|
||||
|
@Input() |
||||
|
public name: string; |
||||
|
|
||||
|
@Input() |
||||
|
public isReadonly: boolean; |
||||
|
|
||||
|
@Input() |
||||
|
public schemasFilter: string; |
||||
|
|
||||
|
@Input() |
||||
|
public schemas: ImmutableArray<SchemaDto>; |
||||
|
|
||||
|
public displayName: string; |
||||
|
|
||||
|
public schemasFiltered: ImmutableArray<SchemaDto>; |
||||
|
public schemasForCategory: ImmutableArray<SchemaDto>; |
||||
|
|
||||
|
public isOpen = true; |
||||
|
|
||||
|
public allowDrop = (schema: any) => { |
||||
|
return (Types.is(schema, SchemaDto) || Types.is(schema, SchemaDetailsDto)) && !this.isSameCategory(schema); |
||||
|
} |
||||
|
|
||||
|
constructor( |
||||
|
private readonly localStore: LocalStoreService, |
||||
|
private readonly schemasState: SchemasState |
||||
|
) { |
||||
|
} |
||||
|
|
||||
|
public ngOnInit() { |
||||
|
this.isOpen = this.localStore.get(`schema-category.${name}`) !== 'false'; |
||||
|
} |
||||
|
|
||||
|
public toggle() { |
||||
|
this.isOpen = !this.isOpen; |
||||
|
|
||||
|
this.localStore.set(`schema-category.${name}`, this.isOpen + ''); |
||||
|
} |
||||
|
|
||||
|
public ngOnChanges(changes: SimpleChanges): void { |
||||
|
if (changes['schemas'] || changes['schemasFilter']) { |
||||
|
const query = this.schemasFilter; |
||||
|
|
||||
|
this.schemasForCategory = this.schemas.filter(x => this.isSameCategory(x)); |
||||
|
this.schemasFiltered = this.schemasForCategory.filter(x => !query || x.name.indexOf(query) >= 0); |
||||
|
} |
||||
|
|
||||
|
if (changes['name']) { |
||||
|
if (!this.name || this.name.length === 0) { |
||||
|
this.displayName = 'All Schemas'; |
||||
|
} else { |
||||
|
this.displayName = this.name; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private isSameCategory(schema: SchemaDto): boolean { |
||||
|
return (!this.name && !schema.category) || schema.category === this.name; |
||||
|
} |
||||
|
|
||||
|
public changeCategory(schema: SchemaDto) { |
||||
|
this.schemasState.changeCategory(schema, this.name).onErrorResumeNext().subscribe(); |
||||
|
} |
||||
|
|
||||
|
public trackBySchema(index: number, schema: SchemaDto) { |
||||
|
return schema.id; |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue