mirror of
https://github.com/farcasclaudiu/LanBackup.git
synced 2026-06-22 07:01:08 +03:00
missing component
This commit is contained in:
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,252 @@
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<span>
|
||||
Backup configurations
|
||||
</span>
|
||||
<div class="pull-right mypointerlink">
|
||||
<a (click)="doRefresh()" class="nounderline">
|
||||
<i class="fa fa-refresh fa-fw" [ngClass]="{ 'fa-spin': isloading }" aria-hidden="true"></i> Refresh
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="panel-body">
|
||||
|
||||
|
||||
<div>
|
||||
|
||||
|
||||
<!-- modal trigger button -->
|
||||
<button type="button" class="btn btn btn-success pull-right" data-toggle="modal" data-target="#myModal" *ngIf="isAdmin()" (click)="doNew()">
|
||||
<i class="fa fa-plus" aria-hidden="true"></i> New Configuration
|
||||
</button>
|
||||
<!-- Modal EDIT -->
|
||||
<div>
|
||||
<app-modal #modalEdit id="modalEdit">
|
||||
<div class="app-modal-header">
|
||||
<button type="button" class="close" (click)="modalEdit.hide()">×</button>
|
||||
<h4 class="modal-title">{{EditTitle}}</h4>
|
||||
</div>
|
||||
<div class="app-modal-body">
|
||||
<form>
|
||||
|
||||
|
||||
<fieldset>
|
||||
|
||||
<div class="container-fluid">
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="control-group">
|
||||
<!-- Client IP -->
|
||||
<label class="control-label" for="clientIP">Computer IP</label>
|
||||
<div class="controls">
|
||||
<input type="text" id="clientIP" name="clientIP" placeholder="computer ip address" class="input-xlarge validate" [(ngModel)]="editItem.clientIP">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="control-group">
|
||||
<!-- Src Folder -->
|
||||
<label class="control-label" for="srcFolder">Source Folder</label>
|
||||
<div class="controls">
|
||||
<input type="text" id="srcFolder" name="srcFolder" placeholder="source folder path" class="input-xlarge validate" [(ngModel)]="editItem.srcFolder">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6" class="control-group">
|
||||
<!-- Dest Folder -->
|
||||
<label class="control-label" for="destLanFolder">Destination Folder</label>
|
||||
<div class="controls">
|
||||
<input type="text" id="destLanFolder" name="destLanFolder" placeholder="destination lan folder path" class="input-xlarge validate" [(ngModel)]="editItem.destLanFolder">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="control-group">
|
||||
<!-- Src User -->
|
||||
<label class="control-label" for="srcUser">Source user</label>
|
||||
<div class="controls">
|
||||
<input type="text" id="srcUser" name="srcUser" placeholder="source user (john@computer)" class="input-xlarge validate" [(ngModel)]="editItem.srcUser">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6" class="control-group">
|
||||
<!-- Dest User -->
|
||||
<label class="control-label" for="destUser">Destination user</label>
|
||||
<div class="controls">
|
||||
<input type="text" id="destUser" name="destUser" placeholder="destination user (mary@server)" class="input-xlarge validate" [(ngModel)]="editItem.destUser">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-6">
|
||||
<div class="control-group">
|
||||
<!-- Src Pass -->
|
||||
<label class="control-label" for="srcPass">Source password</label>
|
||||
<div class="controls">
|
||||
<input type="password" id="srcPass" name="srcPass" placeholder="source pass (*****)" class="input-xlarge validate" [(ngModel)]="editItem.srcPass">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-md-6" class="control-group">
|
||||
<!-- Dest User -->
|
||||
<label class="control-label" for="destPass">Destination password</label>
|
||||
<div class="controls">
|
||||
<input type="password" id="destPass" name="destPass" placeholder="destination pass (*****)" class="input-xlarge validate" [(ngModel)]="editItem.destPass">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-md-12 control-group">
|
||||
<!-- CRONTAB -->
|
||||
<label class="control-label" for="crontab">Crontab shedule expression</label>
|
||||
<div class="controls">
|
||||
<input type="text" id="crontab" name="crontab" placeholder="crontab expression" class="input-xlarge validate" [(ngModel)]="editItem.crontab">
|
||||
</div>
|
||||
<div class="controls">
|
||||
<p>to create expressions please lick <a href="http://www.cronmaker.com/" target="_blank">here</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<h1></h1>
|
||||
<span>{{errorMsg}}</span>
|
||||
<h1></h1>
|
||||
</fieldset>
|
||||
|
||||
|
||||
|
||||
</form>
|
||||
</div>
|
||||
<div class="app-modal-footer">
|
||||
<button type="button" class="btn btn-default pull-left" (click)="modalEdit.hide()">Close</button>
|
||||
<button type="button" class="btn btn-success" (click)="doSave()">Save</button>
|
||||
</div>
|
||||
</app-modal>
|
||||
</div>
|
||||
|
||||
<!-- end Modal -->
|
||||
<!-- Modal DELETE -->
|
||||
<div>
|
||||
<app-modal #modalDelete id="modalDelete">
|
||||
<div class="app-modal-header">
|
||||
<button type="button" class="close" (click)="modalDelete.hide()">×</button>
|
||||
<h4 class="modal-title">Delete confirmation</h4>
|
||||
</div>
|
||||
<div class="app-modal-body">
|
||||
<div>
|
||||
|
||||
<p>
|
||||
Confim removal of {{editItem.clientIP}} from {{editItem.srcFolder}} to {{editItem.destLanFolder}}?
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="app-modal-footer">
|
||||
<button type="button" class="btn btn-default pull-left" (click)="modalDelete.hide()">Close</button>
|
||||
<button type="button" class="btn btn-danger" (click)="doDeleteConfirm()">Confirm</button>
|
||||
</div>
|
||||
</app-modal>
|
||||
</div>
|
||||
<!-- end Modal -->
|
||||
|
||||
|
||||
|
||||
<div class="tabledesc">
|
||||
Here are all scheduled backups. <br />
|
||||
Only "Admin" users can create, update, enable, disable and delete these. <br />
|
||||
If you need to perform these actions and you can't, please contact your system administrator <a href="mailto:{{adminEmail}}">here</a>.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<div class="table-responsive tableminim well">
|
||||
<table class="table table-hover table-fixed table-condensed table-striped anyLoadingTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>ID</th>
|
||||
<th>Computer IP</th>
|
||||
<th>Source</th>
|
||||
<th>Destination</th>
|
||||
<th>Details</th>
|
||||
<th class="text-center">Logs</th>
|
||||
<th class="text-center">Active</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
|
||||
<tr *ngFor="let backup of list.recs | paginate: { id: 'pagedList', itemsPerPage: pageSize, currentPage: currentPage, totalItems: totalPages }">
|
||||
<td>{{backup.id}}</td>
|
||||
<td>{{backup.clientIP}}</td>
|
||||
<td>{{backup.srcFolder}}</td>
|
||||
<td>{{backup.destLanFolder}}</td>
|
||||
<td>{{backup.crontab}}</td>
|
||||
<td>
|
||||
<div class="text-center">
|
||||
<button type="button" class="btn btn-xs btn-default" (click)="seeLogs(backup)">
|
||||
<i class="fa fa-list-alt" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="text-center switchAdjust">
|
||||
<ngSwitch [(ngModel)]="backup.isActive" (change)="toggleActive(backup)" [disabled]="!isAdmin()" size="small" class=""></ngSwitch>
|
||||
<!--<input type="checkbox" [ngModel]="backup.isActive" (change)="toggleActive(backup)" checked data-toggle="toggle" data-size="mini" data-onstyle="info" [disabled]="!isAdmin()">-->
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="text-center">
|
||||
<button type="button" class="btn btn-default btn-xs" (click)="doEdit(backup)" [disabled]="!isAdmin()">
|
||||
<i class="fa fa-pencil" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="text-center">
|
||||
<button type="button" class="btn btn-danger btn-xs" (click)="doDelete(backup)" [disabled]="!isAdmin()">
|
||||
<i class="fa fa-trash" aria-hidden="true"></i>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="spinnercontainer row" [ngClass]="{ 'hidden': !isloading }">
|
||||
<div class="myspinnerback">
|
||||
<div class="myspinner">
|
||||
<i class="fa fa-refresh fa-3x fa-fw fa-spin text-primary" aria-hidden="true"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
<!--pagination-->
|
||||
<div class="panel-footer table-footer">
|
||||
<div class="has-text-centered">
|
||||
<pagination-controls (pageChange)="getPage($event)" id="pagedList" previousLabel="«" nextLabel="»"></pagination-controls>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@@ -0,0 +1,241 @@
|
||||
import { Component, OnInit, Input, ViewChild } from '@angular/core';
|
||||
import { BackupConfiguration } from '../../model/BackupConfiguration';
|
||||
import { SaveResult } from '../../model/SaveResult';
|
||||
import { PaginatedList } from '../../model/PaginatedList';
|
||||
import { WebApiService } from '../../services/webapi.service';
|
||||
import { Observable } from 'rxjs/Observable';
|
||||
import { AuthenticationService } from '../../services/authentication.service';
|
||||
import { ModalComponent } from '../../shared/modal/modal.component';
|
||||
|
||||
import { LoggerService } from '../../services/logger.service';
|
||||
import { ToastNotification, ToastType } from '../../services/notifications.service';
|
||||
import { MessageService, Messages } from '../../services/message.service';
|
||||
|
||||
|
||||
import { GlobalRef } from '../../shared/global/global-ref';
|
||||
|
||||
|
||||
const EDIT_BACKUP_TITLE = "Edit backup configuration";
|
||||
const NEW_BACKUP_TITLE = "Create new backup configuration";
|
||||
|
||||
@Component({
|
||||
selector: 'backups',
|
||||
templateUrl: './backups.component.html',
|
||||
styleUrls: ['./backups.component.css'
|
||||
]
|
||||
})
|
||||
export class BackupsComponent implements OnInit {
|
||||
|
||||
@ViewChild('modalEdit')
|
||||
public readonly modalEdit: ModalComponent;
|
||||
|
||||
@ViewChild('modalDelete')
|
||||
public readonly modalDelete: ModalComponent;
|
||||
|
||||
public list: PaginatedList<BackupConfiguration> = new PaginatedList<BackupConfiguration>(null);
|
||||
|
||||
public EditTitle = NEW_BACKUP_TITLE;
|
||||
public editItem: BackupConfiguration = new BackupConfiguration(null);
|
||||
private prevSaveItem: BackupConfiguration;
|
||||
|
||||
|
||||
currentPage: number = 1;
|
||||
pageSize: number = 5;
|
||||
totalPages: number;
|
||||
public isloading = false;
|
||||
issaving = true;
|
||||
isNew = false;
|
||||
adminEmail = '';
|
||||
|
||||
|
||||
constructor(
|
||||
private webApi: WebApiService,
|
||||
private _service: AuthenticationService,
|
||||
private messageService: MessageService,
|
||||
private log: LoggerService,
|
||||
private _global: GlobalRef
|
||||
) {
|
||||
this.adminEmail = _global.nativeGlobal.clientSettings.admin_email;
|
||||
}
|
||||
|
||||
|
||||
showToast(toast: ToastNotification) {
|
||||
this.messageService.broadcast(Messages.MESSAGE_NOTIFY, toast);
|
||||
}
|
||||
|
||||
|
||||
ngOnInit(): void {
|
||||
this.doRefresh();
|
||||
}
|
||||
|
||||
|
||||
seeLogs(item: BackupConfiguration) {
|
||||
//TODO - show schedule logs
|
||||
this.log.debug('see logs ' + item);
|
||||
}
|
||||
|
||||
isAdmin() {
|
||||
return this._service.checkIsAdmin();
|
||||
}
|
||||
|
||||
doDelete(item: BackupConfiguration) {
|
||||
if (this.isAdmin()) {
|
||||
//
|
||||
this.editItem = item;
|
||||
this.log.debug('do delete ' + item);
|
||||
this.modalDelete.show();
|
||||
}
|
||||
}
|
||||
|
||||
doDeleteConfirm() {
|
||||
//remove from webApi
|
||||
this.issaving = true;
|
||||
this.webApi.deleteBackup(this.editItem)
|
||||
.subscribe(
|
||||
(data) => {
|
||||
//update list
|
||||
this.updateListLocal(this.editItem, true);
|
||||
this.modalDelete.hide();
|
||||
this.showToast({ title: "Delete success", body: "Backup configuration was deleted", type: ToastType.success });
|
||||
this.getPage(this.currentPage);
|
||||
this.issaving = false;
|
||||
},
|
||||
err => {
|
||||
this.issaving = false;
|
||||
this.showToast({ title: "Delete error", body: err, type: ToastType.error });
|
||||
this.log.error(err);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
doNew() {
|
||||
if (this.isAdmin()) {
|
||||
this.EditTitle = NEW_BACKUP_TITLE;
|
||||
this.editItem = new BackupConfiguration(null);
|
||||
this.isNew = true;
|
||||
this.modalEdit.show();
|
||||
}
|
||||
}
|
||||
|
||||
doEdit(item: BackupConfiguration) {
|
||||
if (this.isAdmin()) {
|
||||
//
|
||||
this.EditTitle = EDIT_BACKUP_TITLE;
|
||||
this.prevSaveItem = this.getPrevItem(item.id);
|
||||
this.editItem = jQuery.extend(true, {}, item);//create deep copy of original edited item
|
||||
this.isNew = false;
|
||||
this.log.debug('do edit ' + JSON.stringify(item));
|
||||
this.modalEdit.show();
|
||||
}
|
||||
}
|
||||
|
||||
toggleActive(item: BackupConfiguration) {
|
||||
if (this.isAdmin()) {
|
||||
//
|
||||
this.issaving = true;
|
||||
this.prevSaveItem = this.getPrevItem(item.id);
|
||||
item.isActive = !item.isActive;
|
||||
this.log.debug('do toggle active ' + item.isActive);
|
||||
var strAction = item.isActive ? "activated" : "disabled";
|
||||
//save into webapi
|
||||
this.callWebApiSave(item, false,
|
||||
"Update succes", `Backup configuration has been ${strAction}!`,
|
||||
"Update error", null
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
doSave() {
|
||||
// call API to save
|
||||
this.issaving = true;
|
||||
this.log.debug('saving');
|
||||
this.callWebApiSave(this.editItem, this.isNew,
|
||||
this.isNew ? "Create success" : "Edit success",
|
||||
this.isNew ? "The new backup configuration has been added!" : "The backup has been updated!",
|
||||
this.isNew ? "Create error" : "Edit error",
|
||||
() => {
|
||||
this.modalEdit.hide();
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
callWebApiSave(item: BackupConfiguration, isNew: boolean,
|
||||
titleSucces: string, msgSucces: string,
|
||||
titleErr: string, callback) {
|
||||
this.webApi.saveBackup(item, isNew)
|
||||
.subscribe(
|
||||
(data) => {
|
||||
//update list
|
||||
if (!isNew) {
|
||||
this.updateListLocal(data, false);
|
||||
}
|
||||
else {
|
||||
this.doRefresh();
|
||||
}
|
||||
if (callback) callback();
|
||||
this.showToast({ title: titleSucces, body: msgSucces, type: ToastType.success });
|
||||
this.issaving = false;
|
||||
},
|
||||
err => {
|
||||
this.issaving = false;
|
||||
this.updateListLocal(this.prevSaveItem, false);
|
||||
this.showToast({ title: titleErr, body: err, type: ToastType.error });
|
||||
this.log.error(err);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
updateListLocal(data: BackupConfiguration, todelete: boolean) {
|
||||
for (let ix = 0; ix < this.list.recs.length; ix++) {
|
||||
if (this.list.recs[ix].id == data.id) {
|
||||
if (todelete) {
|
||||
this.log.debug('local delete');
|
||||
this.list.recs.splice(ix, 1);
|
||||
}
|
||||
else {
|
||||
this.log.debug('local replace');
|
||||
this.list.recs.splice(ix, 1, data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getPrevItem(id: string) {
|
||||
for (let ix = 0; ix < this.list.recs.length; ix++) {
|
||||
if (this.list.recs[ix].id == id) {
|
||||
return this.list.recs[ix];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
doRefresh() {
|
||||
this.getPage(this.currentPage);
|
||||
}
|
||||
|
||||
getPage(page: number) {
|
||||
this.isloading = true;
|
||||
this.webApi.getBackupsPage(page, this.pageSize).subscribe(
|
||||
(data) => {
|
||||
|
||||
setTimeout(() => {
|
||||
this.list = data;
|
||||
this.currentPage = page
|
||||
this.totalPages = data.tp * this.pageSize;
|
||||
this.isloading = false;
|
||||
}, 300);//TODO - remove - induced delay
|
||||
|
||||
},
|
||||
err => {
|
||||
this.log.error(err);
|
||||
this.isloading = false;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user