mirror of https://github.com/Squidex/squidex.git
59 changed files with 775 additions and 304 deletions
@ -0,0 +1,35 @@ |
|||
/* |
|||
* Squidex Headless CMS |
|||
* |
|||
* @license |
|||
* Copyright (c) Sebastian Stehle. All rights reserved |
|||
*/ |
|||
|
|||
import { Directive, ElementRef, HostListener, OnInit, Renderer } from '@angular/core'; |
|||
|
|||
@Directive({ |
|||
selector: '[sqxSquare]' |
|||
}) |
|||
export class SquareDirective implements OnInit { |
|||
|
|||
constructor( |
|||
private readonly element: ElementRef, |
|||
private readonly renderer: Renderer |
|||
) { |
|||
} |
|||
|
|||
public ngOnInit() { |
|||
this.resize(); |
|||
} |
|||
|
|||
@HostListener('resize') |
|||
public onResize() { |
|||
this.resize(); |
|||
} |
|||
|
|||
private resize() { |
|||
const size = this.element.nativeElement.getBoundingClientRect(); |
|||
|
|||
this.renderer.setElementStyle(this.element.nativeElement, 'height', size.width + 'px'); |
|||
} |
|||
} |
|||
@ -1,54 +1,60 @@ |
|||
<div class="asset"> |
|||
<div class="card" (sqxFileDrop)="updateFile($event)"> |
|||
<div *ngIf="asset && progress == 0" [@fade]> |
|||
<div class="card-block"> |
|||
<div class="file-preview"> |
|||
<span class="file-type" *ngIf="fileType"> |
|||
{{fileType}} |
|||
</span> |
|||
<div class="card" (sqxFileDrop)="updateFile($event)" sqxSquare dnd-draggable [dragEnabled]="!!asset" [dragData]="asset"> |
|||
<div class="card-block"> |
|||
<div class="file-preview" *ngIf="asset && progress == 0" [@fade]> |
|||
<span class="file-type" *ngIf="fileType"> |
|||
{{fileType}} |
|||
</span> |
|||
|
|||
<div *ngIf="asset.isImage" class="file-image"> |
|||
<img [sqxImageSource]="previewUrl"> |
|||
</div> |
|||
<div *ngIf="!asset.isImage" class="file-icon-container"> |
|||
<img class="file-icon" [attr.src]="fileIcon"> |
|||
</div> |
|||
<div *ngIf="asset.isImage" class="file-image"> |
|||
<img [sqxImageSource]="previewUrl"> |
|||
</div> |
|||
<div *ngIf="!asset.isImage" class="file-icon-container"> |
|||
<img class="file-icon" [attr.src]="fileIcon"> |
|||
</div> |
|||
|
|||
<div class="file-overlay"> |
|||
<div class="file-overlay-background"></div> |
|||
<div class="file-overlay"> |
|||
<div class="file-overlay-background"></div> |
|||
|
|||
<a class="file-edit" (click)="renameDialog.show()"> |
|||
<i class="icon-pencil"></i> |
|||
</a> |
|||
<a class="file-download" [attr.href]="fileUrl" target="_blank"> |
|||
<i class="icon-download"></i> |
|||
</a> |
|||
<a class="file-edit" (click)="renameDialog.show()"> |
|||
<i class="icon-pencil"></i> |
|||
</a> |
|||
<a class="file-download" [attr.href]="fileUrl" target="_blank"> |
|||
<i class="icon-download"></i> |
|||
</a> |
|||
|
|||
<span *ngIf="!closeMode"> |
|||
<a class="file-delete" (click)="deleting.emit(asset)"> |
|||
<i class="icon-delete"></i> |
|||
</a> |
|||
</span> |
|||
<span *ngIf="closeMode"> |
|||
<a class="file-delete" (click)="closing.emit(asset)"> |
|||
<i class="icon-close"></i> |
|||
</a> |
|||
</span> |
|||
|
|||
<span class="file-overlay-type" *ngIf="fileType"> |
|||
{{fileType}} |
|||
</span> |
|||
<span class="file-user"> |
|||
<i class="icon-user"></i> {{userName(asset.lastModifiedBy, true) | async}} |
|||
</span> |
|||
<span class="file-modified"> |
|||
{{asset.lastModified | fromNow}} |
|||
</span> |
|||
|
|||
</div> |
|||
<span class="file-overlay-type" *ngIf="fileType"> |
|||
{{fileType}} |
|||
</span> |
|||
<span class="file-user"> |
|||
<i class="icon-user"></i> {{asset.lastModifiedBy | userNameRef}} |
|||
</span> |
|||
<span class="file-modified"> |
|||
{{asset.lastModified | fromNow}} |
|||
</span> |
|||
</div> |
|||
</div> |
|||
<div class="card-footer"> |
|||
<div class="file-name" [attr.title]="fileName"> |
|||
{{fileName}} |
|||
</div> |
|||
<div class="file-info"> |
|||
{{fileInfo}} |
|||
</div> |
|||
</div> |
|||
<div class="card-footer"> |
|||
<div class="file-name" [attr.title]="fileName"> |
|||
{{fileName}} |
|||
</div> |
|||
<div class="file-info"> |
|||
{{fileInfo}} |
|||
</div> |
|||
</div> |
|||
|
|||
<div *ngIf="progress > 0"> |
|||
<sqx-progress-bar class="upload-progress" style="width: 120px; height: 120px" mode="Circle" [value]="progress"></sqx-progress-bar> |
|||
</div> |
|||
@ -1,3 +1,11 @@ |
|||
<div class="assets-container"> |
|||
|
|||
<div class="assets-container" (sqxFileDrop)="addFiles($event)" dnd-droppable (onDropSuccess)="onAssetDropped($event.dragData)"> |
|||
<div class="row"> |
|||
<sqx-asset class="col-4" *ngFor="let file of newAssets" [initFile]="file" |
|||
(failed)="onAssetFailed(file)" |
|||
(loaded)="onAssetLoaded(file, $event)"> |
|||
</sqx-asset> |
|||
<sqx-asset class="col-4" *ngFor="let asset of oldAssets" [asset]="asset" [closeMode]="true" |
|||
(closing)="onAssetRemoving($event)"> |
|||
</sqx-asset> |
|||
</div> |
|||
</div> |
|||
@ -0,0 +1,159 @@ |
|||
/* |
|||
* Squidex Headless CMS |
|||
* |
|||
* @license |
|||
* Copyright (c) Sebastian Stehle. All rights reserved |
|||
*/ |
|||
|
|||
import { ChangeDetectorRef, OnDestroy, Pipe, PipeTransform } from '@angular/core'; |
|||
import { Observable, Subscription } from 'rxjs'; |
|||
|
|||
import { UsersProviderService } from './../declarations-base'; |
|||
|
|||
class UserAsyncPipe implements OnDestroy { |
|||
private lastUserId: string; |
|||
private lastValue: string; |
|||
private subscription: Subscription; |
|||
|
|||
constructor( |
|||
private readonly users: UsersProviderService, |
|||
private readonly changeDetector: ChangeDetectorRef |
|||
) { |
|||
} |
|||
|
|||
public ngOnDestroy() { |
|||
if (this.subscription) { |
|||
this.subscription.unsubscribe(); |
|||
} |
|||
} |
|||
|
|||
protected transformInternal(userId: string, transform: (users: UsersProviderService) => Observable<string>): string { |
|||
if (this.lastUserId !== userId) { |
|||
this.lastUserId = userId; |
|||
|
|||
if (this.subscription) { |
|||
this.subscription.unsubscribe(); |
|||
} |
|||
|
|||
this.subscription = transform(this.users).subscribe(value => { |
|||
this.lastValue = value; |
|||
|
|||
this.changeDetector.markForCheck(); |
|||
}); |
|||
} |
|||
|
|||
return this.lastValue; |
|||
} |
|||
} |
|||
|
|||
@Pipe({ |
|||
name: 'userName', |
|||
pure: false |
|||
}) |
|||
export class UserNamePipe extends UserAsyncPipe implements PipeTransform { |
|||
constructor(users: UsersProviderService, changeDetector: ChangeDetectorRef) { |
|||
super(users, changeDetector); |
|||
} |
|||
|
|||
public transform(userId: string, placeholder = 'Me'): string { |
|||
return super.transformInternal(userId, users => users.getUser(userId, placeholder).map(u => u.displayName)); |
|||
} |
|||
} |
|||
|
|||
@Pipe({ |
|||
name: 'userNameRef', |
|||
pure: false |
|||
}) |
|||
export class UserNameRefPipe extends UserAsyncPipe implements PipeTransform { |
|||
constructor(users: UsersProviderService, changeDetector: ChangeDetectorRef) { |
|||
super(users, changeDetector); |
|||
} |
|||
|
|||
public transform(userId: string, placeholder = 'Me'): string { |
|||
return super.transformInternal(userId, users => { |
|||
const parts = userId.split(':'); |
|||
|
|||
if (parts[0] === 'subject') { |
|||
return users.getUser(parts[1], placeholder).map(u => u.displayName); |
|||
} else { |
|||
if (parts[1].endsWith('client')) { |
|||
return Observable.of(parts[1]); |
|||
} else { |
|||
return Observable.of(`${parts[1]}-client`); |
|||
} |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
|
|||
@Pipe({ |
|||
name: 'userEmail', |
|||
pure: false |
|||
}) |
|||
export class UserEmailPipe extends UserAsyncPipe implements PipeTransform { |
|||
constructor(users: UsersProviderService, changeDetector: ChangeDetectorRef) { |
|||
super(users, changeDetector); |
|||
} |
|||
|
|||
public transform(userId: string): string { |
|||
return super.transformInternal(userId, users => users.getUser(userId).map(u => u.email)); |
|||
} |
|||
} |
|||
|
|||
@Pipe({ |
|||
name: 'userEmailRef', |
|||
pure: false |
|||
}) |
|||
export class UserEmailRefPipe extends UserAsyncPipe implements PipeTransform { |
|||
constructor(users: UsersProviderService, changeDetector: ChangeDetectorRef) { |
|||
super(users, changeDetector); |
|||
} |
|||
|
|||
public transform(userId: string): string { |
|||
return super.transformInternal(userId, users => { |
|||
const parts = userId.split(':'); |
|||
|
|||
if (parts[0] === 'subject') { |
|||
return users.getUser(parts[1]).map(u => u.email); |
|||
} else { |
|||
return null; |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
|
|||
@Pipe({ |
|||
name: 'userPicture', |
|||
pure: false |
|||
}) |
|||
export class UserPicturePipe extends UserAsyncPipe implements PipeTransform { |
|||
constructor(users: UsersProviderService, changeDetector: ChangeDetectorRef) { |
|||
super(users, changeDetector); |
|||
} |
|||
|
|||
public transform(userId: string): string { |
|||
return super.transformInternal(userId, users => users.getUser(userId).map(u => u.pictureUrl)); |
|||
} |
|||
} |
|||
|
|||
@Pipe({ |
|||
name: 'userPictureRef', |
|||
pure: false |
|||
}) |
|||
export class UserPictureRefPipe extends UserAsyncPipe implements PipeTransform { |
|||
constructor(users: UsersProviderService, changeDetector: ChangeDetectorRef) { |
|||
super(users, changeDetector); |
|||
} |
|||
|
|||
public transform(userId: string): string { |
|||
return super.transformInternal(userId, users => { |
|||
const parts = userId.split(':'); |
|||
|
|||
if (parts[0] === 'subject') { |
|||
return users.getUser(parts[1]).map(u => u.pictureUrl); |
|||
} else { |
|||
return Observable.of('/images/client.png'); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
/* |
|||
* Squidex Headless CMS |
|||
* |
|||
* @license |
|||
* Copyright (c) Sebastian Stehle. All rights reserved |
|||
*/ |
|||
|
|||
export * from './guards/app-must-exist.guard'; |
|||
export * from './guards/must-be-authenticated.guard'; |
|||
export * from './guards/must-be-not-authenticated.guard'; |
|||
export * from './guards/resolve-app-languages.guard'; |
|||
export * from './guards/resolve-content.guard'; |
|||
export * from './guards/resolve-published-schema.guard'; |
|||
export * from './guards/resolve-schema.guard'; |
|||
|
|||
export * from './services/app-contributors.service'; |
|||
export * from './services/app-clients.service'; |
|||
export * from './services/app-languages.service'; |
|||
export * from './services/apps-store.service'; |
|||
export * from './services/apps.service'; |
|||
export * from './services/assets.service'; |
|||
export * from './services/auth.service'; |
|||
export * from './services/contents.service'; |
|||
export * from './services/event-consumers.service'; |
|||
export * from './services/help.service'; |
|||
export * from './services/history.service'; |
|||
export * from './services/languages.service'; |
|||
export * from './services/schemas.service'; |
|||
export * from './services/users-provider.service'; |
|||
export * from './services/users.service'; |
|||
|
|||
export * from './utils/file-helper'; |
|||
export * from './utils/messages'; |
|||
|
|||
export * from 'framework'; |
|||
Loading…
Reference in new issue