Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improvements for the UI #1471

Merged
merged 1 commit into from
Feb 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions static/skywire-manager-src/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Component } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import { MatDialog } from '@angular/material/dialog';
import { of, Subscription } from 'rxjs';
import { delay, flatMap } from 'rxjs/operators';
import { delay, mergeMap } from 'rxjs/operators';

import { StorageService } from './services/storage.service';
import { SnackbarService } from './services/snackbar.service';
Expand Down Expand Up @@ -111,7 +111,7 @@ export class AppComponent {
if (this.obtainPkSubscription) {
this.obtainPkSubscription.unsubscribe();
}
this.obtainPkSubscription = of(1).pipe(delay(delayMs), flatMap(() => this.apiService.get('about'))).subscribe(result => {
this.obtainPkSubscription = of(1).pipe(delay(delayMs), mergeMap(() => this.apiService.get('about'))).subscribe(result => {
if (result.public_key) {
this.finishStartup(result.public_key);
this.hypervisorPkObtained = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
matInput
>
</div>
<mat-error>
<span>{{ 'rewards-address-config.address-error' | translate }}</span>
</mat-error>
</mat-form-field>

<div class="text-container">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div class="wrapper highlight-internal-icon"
[matTooltip]="(!short ? 'labeled-element.tooltip' : 'labeled-element.tooltip-with-text') | translate:{ text: id }"
[matTooltipClass]="{ 'tooltip-word-break': true }"
(click)="$event.stopPropagation(); processClick();"
(click)="$event.stopPropagation(); $event.preventDefault(); processClick();"
>
<span class="label">
<!-- Label prefix. -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { ClipboardService } from 'src/app/services/clipboard.service';
import { SnackbarService } from 'src/app/services/snackbar.service';
import { EditLabelComponent } from '../edit-label/edit-label.component';
import GeneralUtils from 'src/app/utils/generalUtils';
import { Router } from '@angular/router';

/**
* Represents the parts of a label.
Expand Down Expand Up @@ -142,6 +143,7 @@ export class LabeledElementTextComponent implements OnDestroy {
private storageService: StorageService,
private clipboardService: ClipboardService,
private snackbarService: SnackbarService,
private router: Router,
) { }

ngOnDestroy() {
Expand All @@ -168,25 +170,35 @@ export class LabeledElementTextComponent implements OnDestroy {
});
}

options.push({
icon: 'settings',
label: 'labeled-element.go-to-settings',
});

// Show the options modal window.
SelectOptionComponent.openDialog(this.dialog, options, 'common.options').afterClosed().subscribe((selectedOption: number) => {
if (selectedOption === 1) {
// Copy the id.
if (this.clipboardService.copy(this.id)) {
this.snackbarService.showDone('copy.copied');
}
} else if (selectedOption === 3) {
// Ask for confirmation and remove the label.
const confirmationDialog = GeneralUtils.createConfirmationDialog(this.dialog, 'labeled-element.remove-label-confirmation');
} else if (selectedOption > 2) {
if (selectedOption === 3 && this.labelComponents.labelInfo) {
// Ask for confirmation and remove the label.
const confirmationDialog = GeneralUtils.createConfirmationDialog(this.dialog, 'labeled-element.remove-label-confirmation');

confirmationDialog.componentInstance.operationAccepted.subscribe(() => {
confirmationDialog.componentInstance.closeModal();
confirmationDialog.componentInstance.operationAccepted.subscribe(() => {
confirmationDialog.componentInstance.closeModal();

this.storageService.saveLabel(this.id, null, this.elementType);
this.snackbarService.showDone('edit-label.label-removed-warning');
this.storageService.saveLabel(this.id, null, this.elementType);
this.snackbarService.showDone('edit-label.label-removed-warning');

this.labelEdited.emit();
});
this.labelEdited.emit();
});
} else {
// Navigate to the settings page.
this.router.navigate(['/settings']);
}
} else {
// Params for the edit label modal window.
if (selectedOption === 2) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ app-lang-button {
position: fixed;
right: 10px;
top: 10px;
z-index: 10;
}

.main-container {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,24 @@
</div>
</div>
<mat-dialog-content #content>
<!-- Button for opening all the logs. -->
<a [href]="getLogsUrl()" target="_blank">
<app-button *ngIf="hasMoreLogMessages" class="full-logs-button" color="primary">
<div class="text-container">
{{ 'apps.log.view-all' | translate:{ totalLogs: totalLogs } }}
</div>
</app-button>
</a>

<!-- All entries. -->
<div *ngFor="let message of logMessages" class="app-log-message">
<span class="transparent">
{{ message.time }}
</span>
{{ message.msg }}
</div>

<!-- Msg if empty. -->
<div class="app-log-empty mt-3" *ngIf="!loading && (!logMessages || logMessages.length === 0)">
{{ 'apps.log.empty' | translate }}
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,16 @@
}
}
}

.full-logs-button {
::ng-deep button {
width: 100% !important;
display: block;
text-align: center;
margin-bottom: 15px;
}

.text-container {
width: 100%;
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Component, Inject, OnInit, OnDestroy, ViewChild, ElementRef } from '@angular/core';
import { MAT_DIALOG_DATA, MatDialogConfig, MatDialog, MatDialogRef } from '@angular/material/dialog';
import { Subscription, of } from 'rxjs';
import { delay, flatMap } from 'rxjs/operators';
import { delay, mergeMap } from 'rxjs/operators';

import { AppsService } from '../../../../../../services/apps.service';
import { Application } from '../../../../../../app.datatypes';
Expand All @@ -11,6 +11,7 @@ import { SnackbarService } from '../../../../../../services/snackbar.service';
import { AppConfig } from 'src/app/app.config';
import { OperationError } from 'src/app/utils/operation-error';
import { processServiceError } from 'src/app/utils/errors';
import { ApiService } from 'src/app/services/api.service';

/**
* Represents a log entry.
Expand Down Expand Up @@ -38,7 +39,13 @@ interface LogMessage {
export class LogComponent implements OnInit, OnDestroy {
@ViewChild('content') content: ElementRef;

// Logs entries shown on the UI.
logMessages: LogMessage[] = [];
// If not all logs entries ontained from the backend are being shown.
hasMoreLogMessages = false;
// How many log entries were obtained from the backend.
totalLogs = 0;

loading = false;
currentFilter: LogsFilter = {
text: 'apps.log.filter.7-days',
Expand Down Expand Up @@ -70,6 +77,7 @@ export class LogComponent implements OnInit, OnDestroy {
private appsService: AppsService,
private dialog: MatDialog,
private snackbarService: SnackbarService,
private apiService: ApiService,
) { }

ngOnInit() {
Expand All @@ -92,6 +100,11 @@ export class LogComponent implements OnInit, OnDestroy {
});
}

// Returns the URL to get the full logs from the backend.
getLogsUrl(): string {
return '/' + this.apiService.apiPrefix + this.appsService.getLogMessagesUrl(NodeComponent.getCurrentNodeKey(), this.data.name);
}

private loadData(delayMilliseconds: number) {
this.removeSubscription();

Expand All @@ -100,7 +113,7 @@ export class LogComponent implements OnInit, OnDestroy {
// Wait the delay.
delay(delayMilliseconds),
// Load the data. The node pk is obtained from the currently openned node page.
flatMap(() => this.appsService.getLogMessages(NodeComponent.getCurrentNodeKey(), this.data.name, this.currentFilter.days))
mergeMap(() => this.appsService.getLogMessages(NodeComponent.getCurrentNodeKey(), this.data.name, this.currentFilter.days))
).subscribe(
(log) => this.onLogsReceived(log),
(err: OperationError) => this.onLogsError(err)
Expand All @@ -119,22 +132,33 @@ export class LogComponent implements OnInit, OnDestroy {
this.shouldShowError = true;
this.snackbarService.closeCurrentIfTemporaryError();

let amount = 0;
this.hasMoreLogMessages = false;
this.totalLogs = logs.length;

// Separate the date from the actual log msg and add the entry to the array that will populate the UI.
logs.forEach(log => {
const dateStart = log.startsWith('[') ? 0 : -1;
const dateEnd = dateStart !== -1 ? log.indexOf(']') : -1;

if (dateStart !== -1 && dateEnd !== -1) {
this.logMessages.push({
time: log.substr(dateStart, dateEnd + 1),
msg: log.substr(dateEnd + 1),
});
// Limit how many entries to show.
if (amount < 5000) {
const dateStart = log.startsWith('[') ? 0 : -1;
const dateEnd = dateStart !== -1 ? log.indexOf(']') : -1;

if (dateStart !== -1 && dateEnd !== -1) {
this.logMessages.push({
time: log.substr(dateStart, dateEnd + 1),
msg: log.substr(dateEnd + 1),
});
} else {
this.logMessages.push({
time: '',
msg: log,
});
}
} else {
this.logMessages.push({
time: '',
msg: log,
});
this.hasMoreLogMessages = true;
}

amount += 1;
});

// Scroll to the bottom. Use a timer to wait for the UI to be updated.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
matInput
>
</div>
<mat-error>
<span>{{ 'rewards-address-config.address-error' | translate }}</span>
</mat-error>
</mat-form-field>
</form>
<app-button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
matInput
>
</div>
<mat-error>
<span>{{ 'router-config.min-hops-error' | translate }}</span>
</mat-error>
</mat-form-field>
</form>
<app-button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Component, OnInit, ViewChild, OnDestroy, ElementRef } from '@angular/co
import { UntypedFormBuilder, UntypedFormGroup, Validators } from '@angular/forms';
import { MatDialogRef, MatDialog, MatDialogConfig } from '@angular/material/dialog';
import { Subscription, of } from 'rxjs';
import { delay, flatMap } from 'rxjs/operators';
import { delay, mergeMap } from 'rxjs/operators';

import { TransportService } from '../../../../../../services/transport.service';
import { ButtonComponent } from '../../../../../layout/button/button.component';
Expand Down Expand Up @@ -224,7 +224,7 @@ export class CreateTransportComponent implements OnInit, OnDestroy {
// Wait the delay.
delay(delayMilliseconds),
// Load the data. The node pk is obtained from the currently openned node page.
flatMap(() => this.transportService.types(NodeComponent.getCurrentNodeKey()))
mergeMap(() => this.transportService.types(NodeComponent.getCurrentNodeKey()))
).subscribe(
types => {
// Sort the types and select dmsg as default, if posible.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Component, OnDestroy, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { MatDialog } from '@angular/material/dialog';
import { of, Subscription } from 'rxjs';
import { delay, flatMap } from 'rxjs/operators';
import { delay, mergeMap } from 'rxjs/operators';

import { TabButtonData, MenuOptionData } from '../../layout/top-bar/top-bar.component';
import { AuthService, AuthStates } from '../../../services/auth.service';
Expand Down Expand Up @@ -77,7 +77,7 @@ export class SettingsComponent implements OnInit, OnDestroy {
// Wait the delay.
delay(delayMilliseconds),
// Load the data. The node pk is obtained from the currently openned node page.
flatMap(() => this.authService.checkLogin())
mergeMap(() => this.authService.checkLogin())
).subscribe(
result => {
this.authChecked = true;
Expand Down
2 changes: 1 addition & 1 deletion static/skywire-manager-src/src/app/services/api.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class ApiService {
* with the dev server using the http protocol, because the dev server proxy uses it to
* route the request to the appropiate url.
*/
private readonly apiPrefix = !environment.production && location.protocol.indexOf('http:') !== -1 ?
public readonly apiPrefix = !environment.production && location.protocol.indexOf('http:') !== -1 ?
'http-api/' : 'api/';

/**
Expand Down
9 changes: 8 additions & 1 deletion static/skywire-manager-src/src/app/services/apps.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,14 @@ export class AppsService {
const since = days !== -1 ? Date.now() - (days * 86400000) : 0;
const sinceString = formatDate(since, 'yyyy-MM-ddTHH:mm:ssZZZZZ', 'en-US');

return this.apiService.get(`visors/${nodeKey}/apps/${encodeURIComponent(appName)}/logs?since=${sinceString}`
return this.apiService.get(this.getLogMessagesUrl(nodeKey, appName) + `?since=${sinceString}`
).pipe(map(response => response.logs));
}

/**
* Gets the partial URL for getting the logs of an app.
*/
getLogMessagesUrl(nodeKey: string, appName: string) {
return `visors/${nodeKey}/apps/${encodeURIComponent(appName)}/logs`;
}
}
4 changes: 2 additions & 2 deletions static/skywire-manager-src/src/app/services/node.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Injectable } from '@angular/core';
import { HttpErrorResponse } from '@angular/common/http';
import { Observable, Subscription, BehaviorSubject, of } from 'rxjs';
import { flatMap, map, delay, tap } from 'rxjs/operators';
import { map, delay, tap, mergeMap } from 'rxjs/operators';
import BigNumber from 'bignumber.js';

import { StorageService } from './storage.service';
Expand Down Expand Up @@ -324,7 +324,7 @@ export class NodeService {
tap(() => updatingSubject.next(true)),
delay(120),
// Load the data.
flatMap(() => operation))
mergeMap(() => operation))
.subscribe(result => {
updatingSubject.next(false);

Expand Down
4 changes: 4 additions & 0 deletions static/skywire-manager-src/src/assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
"labeled-element": {
"edit-label": "Edit label",
"remove-label": "Remove label",
"go-to-settings": "Go to settings",
"copy": "Copy",
"remove-label-confirmation": "Do you really want to remove the label?",
"unnamed-element": "Unnamed",
Expand Down Expand Up @@ -174,6 +175,7 @@
"info": "Here you can set to which Skycoin address you want the rewards to be sent. If you leave the address empty, the registration will be deleted and the visor will not receive rewards.",
"more-info-link": "(More info about the reward system)",
"address": "Address",
"address-error": "Please enter a valid Skycoin address.",
"save-config-button": "Save configuration",
"done": "Changes saved.",
"empty-warning": "The address in empty, so the registration will be deleted and no rewards will be received. Do you really want to continue?"
Expand All @@ -183,6 +185,7 @@
"title": "Router Configuration",
"info": "Here you can configure how many hops the connections must pass through other Skywire visors before reaching the final destination. NOTE: the changes will not affect the existing routes.",
"min-hops": "Min hops",
"min-hops-error": "Please enter a valid number.",
"save-config-button": "Save configuration",
"done": "Changes saved."
},
Expand Down Expand Up @@ -374,6 +377,7 @@
"title": "Log",
"empty": "There are no log messages for the selected time range.",
"filter-button": "Only showing logs generated since:",
"view-all": "View all {{ totalLogs }} entries",
"filter": {
"title": "Filter",
"filter": "Only show logs generated since",
Expand Down
Loading