mirror of https://github.com/Squidex/squidex.git
9 changed files with 218 additions and 115 deletions
@ -0,0 +1,55 @@ |
|||||
|
<ng-container *ngIf="config"> |
||||
|
<button type="button" class="btn settings-button" (click)="dropdownModal.toggle()" #buttonSettings> |
||||
|
<i class="icon-settings"></i> |
||||
|
</button> |
||||
|
|
||||
|
<ng-container *sqxModal="dropdownModal"> |
||||
|
<div class="dropdown-menu" [sqxAnchoredTo]="buttonSettings" @fade position="bottom-right"> |
||||
|
<div class="dropdown-item" *ngFor="let item of configDefaults"> |
||||
|
<div class="form-check"> |
||||
|
<input class="form-check-input" type="checkbox" id="field_{{item.type}}" |
||||
|
[ngModel]="isSelected(item)" |
||||
|
(ngModelChange)="addOrRemove(item, $event)" /> |
||||
|
|
||||
|
<label class="form-check-label" for="field_{{item.type}}"> |
||||
|
{{item.name}} |
||||
|
</label> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
<div class="dropdown-divider"></div> |
||||
|
|
||||
|
<a class="dropdown-item" (click)="startExpertMode()">Expert Mode</a> |
||||
|
<a class="dropdown-item" (click)="saveConfig()">Save</a> |
||||
|
|
||||
|
<div class="dropdown-divider"></div> |
||||
|
|
||||
|
<a class="dropdown-item dropdown-item-delete" (beforeClick)="dropdownModal.hide()" |
||||
|
(sqxConfirmClick)="resetConfig()" |
||||
|
confirmTitle="Reset config" |
||||
|
confirmText="Do you really want to reset the dashboard to the default?"> |
||||
|
Reset |
||||
|
</a> |
||||
|
</div> |
||||
|
</ng-container> |
||||
|
|
||||
|
|
||||
|
<ng-container *sqxModal="expertDialog"> |
||||
|
<sqx-modal-dialog (close)="expertDialog.hide()" fullHeight="true" size="lg"> |
||||
|
<ng-container title> |
||||
|
Edit Config |
||||
|
</ng-container> |
||||
|
|
||||
|
<ng-container content> |
||||
|
<div class="json-editor"> |
||||
|
<sqx-json-editor [noBorder]="true" [(ngModel)]="expertConfig"></sqx-json-editor> |
||||
|
</div> |
||||
|
</ng-container> |
||||
|
|
||||
|
<ng-container footer> |
||||
|
<button type="button" class="btn btn-secondary" (click)="expertDialog.hide()">Cancel</button> |
||||
|
<button type="button" class="btn btn-primary" (click)="completeExpertMode()">Save</button> |
||||
|
</ng-container> |
||||
|
</sqx-modal-dialog> |
||||
|
</ng-container> |
||||
|
</ng-container> |
||||
@ -0,0 +1,5 @@ |
|||||
|
.json-editor ::ng-deep { |
||||
|
.editor { |
||||
|
@include absolute(0, 0, 0, 0); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,125 @@ |
|||||
|
/* |
||||
|
* Squidex Headless CMS |
||||
|
* |
||||
|
* @license |
||||
|
* Copyright (c) Squidex UG (haftungsbeschränkt). All rights reserved. |
||||
|
*/ |
||||
|
|
||||
|
// tslint:disable: readonly-array
|
||||
|
|
||||
|
import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from '@angular/core'; |
||||
|
import { AppDto, AppsState, AuthService, DialogModel, DialogService, fadeAnimation, ModalModel, Types, UIState } from '@app/shared'; |
||||
|
import { GridsterItem } from 'angular-gridster2'; |
||||
|
import { take } from 'rxjs/operators'; |
||||
|
|
||||
|
@Component({ |
||||
|
selector: 'sqx-dashboard-config', |
||||
|
styleUrls: ['./dashboard-config.component.scss'], |
||||
|
templateUrl: './dashboard-config.component.html', |
||||
|
animations: [ |
||||
|
fadeAnimation |
||||
|
] |
||||
|
}) |
||||
|
export class DashboardConfigComponent implements OnChanges { |
||||
|
@Input() |
||||
|
public app: AppDto[]; |
||||
|
|
||||
|
@Input() |
||||
|
public config: GridsterItem[]; |
||||
|
|
||||
|
@Output() |
||||
|
public configChange = new EventEmitter<GridsterItem[]>(); |
||||
|
|
||||
|
public configDefaults = DEFAULT_CONFIG; |
||||
|
|
||||
|
public expertDialog = new DialogModel(); |
||||
|
public expertConfig: GridsterItem[]; |
||||
|
|
||||
|
public dropdownModal = new ModalModel(); |
||||
|
|
||||
|
constructor( |
||||
|
public readonly appsState: AppsState, |
||||
|
public readonly authState: AuthService, |
||||
|
private readonly dialogs: DialogService, |
||||
|
private readonly uiState: UIState |
||||
|
) { |
||||
|
} |
||||
|
|
||||
|
public ngOnChanges(changes: SimpleChanges) { |
||||
|
if (changes['app']) { |
||||
|
this.uiState.getUser('dashboard.grid', DEFAULT_CONFIG).pipe(take(1)) |
||||
|
.subscribe(dto => { |
||||
|
this.setConfig(dto); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
private setConfig(config: any) { |
||||
|
if (!Types.isArrayOfObject(config)) { |
||||
|
config = DEFAULT_CONFIG; |
||||
|
} |
||||
|
|
||||
|
this.configChange.emit(Types.clone(config)); |
||||
|
} |
||||
|
|
||||
|
public startExpertMode() { |
||||
|
this.dropdownModal.hide(); |
||||
|
|
||||
|
this.expertConfig = Types.clone(this.config); |
||||
|
this.expertDialog.show(); |
||||
|
} |
||||
|
|
||||
|
public completeExpertMode() { |
||||
|
this.setConfig(this.expertConfig); |
||||
|
|
||||
|
this.expertConfig = null!; |
||||
|
this.expertDialog.hide(); |
||||
|
|
||||
|
this.saveConfig(); |
||||
|
} |
||||
|
|
||||
|
public resetConfig() { |
||||
|
this.setConfig(Types.clone(DEFAULT_CONFIG)); |
||||
|
|
||||
|
this.saveConfig(); |
||||
|
} |
||||
|
|
||||
|
public saveConfig() { |
||||
|
this.uiState.set('dashboard.grid', this.config, true); |
||||
|
|
||||
|
this.dialogs.notifyInfo('Configuration saved.'); |
||||
|
} |
||||
|
|
||||
|
public addOrRemove(item: GridsterItem) { |
||||
|
const current = this.config.find(x => x.type === item.type); |
||||
|
|
||||
|
if (current) { |
||||
|
this.config.splice(this.config.indexOf(current), 1); |
||||
|
} else { |
||||
|
this.config.push(Types.clone(item)); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public isSelected(item: GridsterItem) { |
||||
|
return this.config.find(x => x.type === item.type); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
const DEFAULT_CONFIG: GridsterItem[] = [ |
||||
|
{ cols: 1, rows: 1, x: 0, y: 0, type: 'schemas', name: 'Schema' }, |
||||
|
{ cols: 1, rows: 1, x: 1, y: 0, type: 'api', name: 'API Documentation' }, |
||||
|
{ cols: 1, rows: 1, x: 2, y: 0, type: 'support', name: 'Support' }, |
||||
|
{ cols: 1, rows: 1, x: 3, y: 0, type: 'github', name: 'Github' }, |
||||
|
|
||||
|
{ cols: 2, rows: 1, x: 0, y: 1, type: 'api-calls', name: 'API Calls Chart' }, |
||||
|
{ cols: 2, rows: 1, x: 2, y: 1, type: 'api-performance', name: 'API Performance Chart' }, |
||||
|
|
||||
|
{ cols: 1, rows: 1, x: 0, y: 2, type: 'api-calls-summary', name: 'API Calls Summary' }, |
||||
|
{ cols: 2, rows: 1, x: 1, y: 2, type: 'asset-uploads-count', name: 'Asset Uploads Count Chart' }, |
||||
|
{ cols: 1, rows: 1, x: 2, y: 2, type: 'asset-uploads-size-summary', name: 'Asset Uploads Size Chart' }, |
||||
|
|
||||
|
{ cols: 2, rows: 1, x: 0, y: 3, type: 'asset-uploads-size', name: 'Asset Total Storage Size' }, |
||||
|
{ cols: 2, rows: 1, x: 2, y: 3, type: 'api-traffic', name: 'API Traffic Chart' }, |
||||
|
|
||||
|
{ cols: 2, rows: 1, x: 0, y: 4, type: 'history', name: 'History' } |
||||
|
]; |
||||
Loading…
Reference in new issue