Unverified Commit 9cb520dc authored by Evgeny Stepanovych's avatar Evgeny Stepanovych Committed by GitHub
Browse files

Merge pull request #6323 from truenas/NAS-114413

NAS-114413 / None / NAS-114413: Porting angelfish changes
parents 5bcb0ad9 f563e1f2
base DOCS DOCS-3538 NAS-010101 NAS-110777 NAS-110800 NAS-111962-master NAS-112343 NAS-112995-22.12 NAS-113044 NAS-113464 NAS-113464-alt NAS-113511 NAS-113903-2 NAS-113904-2 NAS-114098 NAS-114179 NAS-114179-2 NAS-114389 NAS-114447 NAS-114448-bluefin NAS-114471 NAS-114549 NAS-114554 NAS-114607 NAS-114639 NAS-114659 NAS-114660 NAS-114751 NAS-114769 NAS-114806 NAS-114845 NAS-114846 NAS-114881 NAS-114915 NAS-114950 NAS-115146 NAS-115162 NAS-115254 NAS-115271 NAS-115339 NAS-115340 NAS-115357 NAS-115488 NAS-115546 NAS-115547 NAS-115593 NAS-115593-2 NAS-115593-3 NAS-115593-4 NAS-115593-5 NAS-115593-6 NAS-115593-7 NAS-115713-22-12 NAS-115759 NAS-115759-22.12 NAS-116151 NAS-116162 NAS-116334-1 NAS-116334-2 NAS-116393 NAS-116395 NAS-116397 NAS-116397-2 NAS-116397-3 NAS-116398 NAS-116405 NAS-116406 NAS-116410 NAS-116469 NAS-116715 NAS-116715-mobile NAS-116715-v2 NAS-116724 NAS-116915 NAS-116916 NAS-117017 NAS-117019 NAS-117028-22.12-BETA.2 NAS-117060 NAS-117098 NAS-117149-22.12 NAS-117216 NAS-117233 NAS-117239 NAS-117253 NAS-117278 NAS-117317 NAS-117323 NAS-117333 NAS-117401 NAS-117439 NAS-117475 NAS-117476 NAS-117481-test NAS-117520 NAS-117573-v2 NAS-117594 NAS-117628 NAS-117688-bluefin NAS-117700 NAS-117714 NAS-117718 NAS-117734 NAS-117768 NAS-117813 NAS-117823 NAS-117841-2 NAS-117846 NAS-117959 NAS-118036 NAS-118044 NAS-118113 NAS-118165 NAS-118303 NAS-118454-22.12 NAS-118505-22.12 NAS-118545 NAS-118548 NAS-119131 NAS-119140 NAS-119180-22.12.1 NAS-119431 NAS-119556-23.10 NAS-119615-22.12.1 NAS-119668 NAS-119695 NAS-119749-bluefin NAS-119750-22.12.1 NAS-119806 NAS-119812 NAS-119886-22.12.1 NAS-119996 NAS-119996-bluefin NAS-120045 NAS-120047 NAS-120057 NAS-120173-22.12.1 NAS-120181-22.12.1 NAS-120264-22.12.1 NAS-120274 NAS-120296-22.12.1 NAS-120326-22.12.1 NAS-120490_ NAS-120503 NAS-121006-22.12.2 NAS-121124 NAS-121128-22.12.2 NAS-121128-release-22.12.2 NAS-121136 NAS-121177 NAS-121218-22.12.3 NAS-121300 NAS-121316 NAS-121541 NAS-121542 NAS-121686 NAS-121721-22.12.3 NAS-121778 NAS-121827 NAS-121884-22.12.3 NAS-122267-22.12.4 NAS-122372 NAS-122601 NAS-122686 NAS-122706 NAS-122721 NAS-122751-23.10-BETA.1 NAS-122759 NAS-122781 NAS-122794-23.10 NAS-122855 NAS-122870-bluefin NAS-122969 NAS-122993-22.12.4 NAS-123055-22.12.4 NAS-123278 NAS-123295 NAS-123437 NAS-123478-22.12.4 NAS-123484 NAS-123492 NAS-123526-22.12.4 NAS-123651 NAS-123651-23.10-BETA.1 NAS-123666 NAS-123723 NAS-123723-cobia NAS-123762 NAS-123762-23.10 NAS-123778-23.10 NAS-123778-23.10-RC.1 NAS-123778-RC.1 NAS-123801 NAS-123810-23.10 NAS-123813-22.12.4 NAS-123836 NAS-123836-23.10-BETA.1 NAS-123836-24.04 NAS-123861 NAS-123911-23.10-BETA.1 NAS-123928-23.10 NAS-123931-22.12.4 NAS-123945 NAS-124044 NAS-124077 NAS-124131-23.10 NAS-124137 NAS-124183 NAS-124231 NAS-124232 NAS-124237-23.10 NAS-124325-23.10.0 NAS-124335 NAS-124354 NAS-124430 NAS-124454 NAS-124481-23.10.0 NAS-124481-23.10.1 NAS-124555-23.10.0 NAS-124555-23.10.1 NAS-124666 NAS-124707-23.10.0 NAS-124707-23.10.1 NAS-124716 NAS-124846-23.10.0 NAS-124846-23.10.1 NAS-124892 NAS-124895-23.10.1 NAS-124908 NAS-124951 NAS-124964 NAS-124999 NAS-125092 NAS-125213-23.10.1 NAS-125307 NAS-125532 NAS-125568 NAS-125607-validator NAS-125616-23.10.2 NAS-125654 NAS-125703-23.10.2 NAS-125728 NAS-125931 NAS-126699 NAS-126774-24.04-RC.1 NAS-126774-dragonfish NAS-126795 NAS-126795-test NAS-126795-test2 NAS-127001 NAS-127002-24.04-RC.1 NAS-127022 NAS-127041-24.04-BETA.1 NAS-127049-24.04-RC.1 NAS-127297-24.04-RC.1 NAS-127297-24.10 NAS-127369 NAS-127551 NAS-127551-alt NAS-127589-24.04.0 NAS-127593 NAS-127615-24.04.0 NAS-127660 NAS-127794 NAS-127829-24.10 NAS-127854-24.04.0 NAS-128030 NAS-128045 NAS-128071 NAS-128173 NAS-128209 NAS-128287 NAS-128289 TE-1553-dragonfish TE-1628 auto-129 back bugfix/NAS-117859-sidebar-menu-fix bugfix/NAS-117941-error-when-removing-pools-and-visit-datasets bugfix/NAS-118171-rsynk-task-local-path bugfix/NAS-118260-boot-env-keep-table-row bugfix/NAS-118282-search-input-fixes bugfix/NAS-118404-dataset-icon-role-double-toooltip bugfix/NAS-118414-warning-modal-icon bugfix/NAS-118415-tree-select-undefined bugfix/NAS-118454-acl-manager-after-dataset-creation-fix bugfix/NAS-118470-multiselext-styles-are-broken bugfix/NAS-118503-datasets-glitch-fix bugfix/NAS-118504-redirect-to-correct-dataset-after-permissions-submit bugfix/NAS-118510-redirect-url-fix-after-manual-change bugfix/NAS-118530-advanced-settings-box-duplicates bugfix/NAS-118541-progress-bar-oberflows bugfix/NAS-118557-replication-task-forbid-custom-retention-policy-cases bugfix/NAS-118600-smb-share-redirect bugfix/NAS-118601-remove-mixed-for-zfs-datasets cpu-pinning dataset-tree-tooltips developer/lyy feature/NAS-117754-font-rendering feature/NAS-117968-tooltips-to-status-icons-on-pools feature/NAS-118058-improve-dashboard-icons-sync-pool-and-storage feature/NAS-118147-html-refactoring feature/NAS-118269-improve-ui feature/NAS-118303 feature/NAS-118333-storage-dashboard-icons-update feature/NAS-118334-screentype-enum feature/NAS-118335-improve-spinners-look feature/NAS-118349-datasets-long-names feature/NAS-118360-handle-clipboard-api-not-available feature/NAS-118412-pool-processing-modal feature/NAS-118466-root-path-mnt feature/NAS-118543-user-password-field feauture/NAS-117474-datasets-table-header-sticky l10n_master llll master master-old metrics-enable patch-1 patch-235 rel-v0.0.1 release/22.12 release/22.12-BETA.1 release/22.12-BETA.2 release/22.12-RC.1 release/22.12.1 release/22.12.2 release/22.12.3 release/22.12.4 release/23.10-BETA.1 release/23.10-RC.1 release/23.10.0 release/23.10.1 release/23.10.1.1 release/23.10.1.2 release/23.10.1.3 release/23.10.2 release/24.04-BETA.1 release/24.04-RC.1 release/24.04.0 renediepenbroek/master revert-6783-NAS-116405 revert-7745-NAS-120274 stable/bluefin stable/cobia stable/dragonfish test-xxxyyy testing-refine-branchout-process testing-refine-branchout-process2 v0.0.2 TS-24.04-RC.1 TS-24.04-BETA.1 TS-23.10.2 TS-23.10.1.3 TS-23.10.1.2 TS-23.10.1.1 TS-23.10.1 TS-23.10.0.1 TS-23.10.0 TS-23.10-RC.1 TS-23.10-BETA.1 TS-22.12.4.2 TS-22.12.4.1 TS-22.12.4 TS-22.12.3.3 TS-22.12.3.2 TS-22.12.3.1 TS-22.12.3 TS-22.12.2 TS-22.12.1 TS-22.12.0 TS-22.12-RC.1 TS-22.12-BETA.2 TS-22.12-BETA.1 TS-22.12-ALPHA.1 TS-12.12.3 DN110M-CS-v2.0
No related merge requests found
Showing with 185 additions and 29 deletions
+185 -29
......@@ -720,6 +720,19 @@ export class EntityTableComponent<Row = any> implements OnInit, AfterViewInit, A
return res;
}
patchCurrentRows<T>(
rowSelector: (row: T) => boolean,
rowMutator: (row: T) => T,
): void {
this.currentRows = this.currentRows.map((row) => {
if (rowSelector(row)) {
return rowMutator(row) || row;
}
return row;
});
this.dataSourceStreamer$.next(this.currentRows);
}
isLeftStickyColumnNo(i: number): boolean {
return i === (this.currentColumns[0].prop === 'multiselect' ? 1 : 0);
}
......
<h1 mat-dialog-title>
<mat-icon class="information-icon">{{icon}}</mat-icon>
{{ title | translate }}
<span [innerHTML]="title | translate"></span>
</h1>
<div mat-dialog-content>
<div *ngIf="!isHtml" class="info-panel">
......
<mat-slide-toggle
color="primary"
[checked]="value"
[required]="required"
[disabled]="isDisabled"
(change)="onSlideToggleChanged($event)"
(blur)="onTouch()"
>
{{ label }}
<span *ngIf="required" class="required">*</span>
</mat-slide-toggle>
<tooltip *ngIf="tooltip" [header]="label" class="tooltip" [message]="tooltip"></tooltip>
<ix-errors [control]="controlDirective.control" [label]="label"></ix-errors>
:host {
display: block;
font-size: 12px;
margin-bottom: 19px;
margin-top: 12px;
mat-slide-toggle {
margin: 4px 4px 4px 0;
}
}
import {
ChangeDetectionStrategy, ChangeDetectorRef, Component, Input,
} from '@angular/core';
import {
ControlValueAccessor, NgControl,
} from '@angular/forms';
import { MatSlideToggleChange } from '@angular/material/slide-toggle';
import { UntilDestroy } from '@ngneat/until-destroy';
@UntilDestroy()
@Component({
selector: 'ix-slide-toggle',
styleUrls: ['./ix-slide-toggle.component.scss'],
templateUrl: './ix-slide-toggle.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class IxSlideToggleComponent implements ControlValueAccessor {
@Input() label: string;
@Input() hint: string;
@Input() tooltip: string;
@Input() required: boolean;
isDisabled = false;
value: boolean;
constructor(
public controlDirective: NgControl,
private cdr: ChangeDetectorRef,
) {
this.controlDirective.valueAccessor = this;
}
onChange: (value: boolean) => void = (): void => {};
onTouch: () => void = (): void => {};
writeValue(value: boolean): void {
this.value = value;
this.cdr.markForCheck();
}
registerOnChange(onChange: (value: boolean) => void): void {
this.onChange = onChange;
}
registerOnTouched(onTouched: () => void): void {
this.onTouch = onTouched;
}
setDisabledState?(isDisabled: boolean): void {
this.isDisabled = isDisabled;
this.cdr.markForCheck();
}
onSlideToggleChanged(event: MatSlideToggleChange): void {
this.value = event.checked;
this.onChange(event.checked);
}
}
import { BaseHarnessFilters, ComponentHarness, HarnessPredicate } from '@angular/cdk/testing';
import { MatSlideToggleHarness } from '@angular/material/slide-toggle/testing';
import { IxFormControlHarness } from 'app/pages/common/ix-forms/interfaces/ix-form-control-harness.interface';
export interface IxSlideToggleHarnessFilters extends BaseHarnessFilters {
label: string;
}
export class IxSlideToggleHarness extends ComponentHarness implements IxFormControlHarness {
static hostSelector = 'ix-slide-toggle';
static with(options: IxSlideToggleHarnessFilters): HarnessPredicate<IxSlideToggleHarness> {
return new HarnessPredicate(IxSlideToggleHarness, options)
.addOption('label', options.label,
(harness, label) => HarnessPredicate.stringMatches(harness.getLabelText(), label));
}
getMatSlideToggleHarness = this.locatorFor(MatSlideToggleHarness);
async getLabelText(): Promise<string> {
const label = await this.locatorFor('label')();
return label.text({ exclude: '.required' });
}
async getErrorText(): Promise<string> {
const label = await this.locatorForOptional('ix-errors')();
return label?.text() || '';
}
async getValue(): Promise<boolean> {
return (await this.getMatSlideToggleHarness()).isChecked();
}
async setValue(value: boolean): Promise<void> {
const matSlideToggleHarness = await this.getMatSlideToggleHarness();
if (value) {
return matSlideToggleHarness.check();
}
return matSlideToggleHarness.uncheck();
}
async isDisabled(): Promise<boolean> {
return (await this.getMatSlideToggleHarness()).isDisabled();
}
}
......@@ -35,6 +35,7 @@ export class LineChartComponent extends ViewComponent implements AfterViewInit,
get data(): ReportingData {
return this._data;
}
@Input() isReversed = false;
@Input() report: Report;
@Input() title: string;
@Input() timezone: string;
......@@ -87,15 +88,12 @@ export class LineChartComponent extends ViewComponent implements AfterViewInit,
// dygraph renderer
renderGraph(update?: boolean): void {
if (this.data.name == 'cpu') {
if (this.isReversed) {
this.data.legend = this.data.legend.reverse();
for (let i = 0; i < this.data.data.length; i++) {
const newRow = [];
while (this.data.data[i].length) {
newRow.push(this.data.data[i].pop());
}
this.data.data[i] = newRow;
}
this.data.data.forEach((row, i) => this.data.data[i] = row.slice().reverse());
this.data.aggregations.min = this.data.aggregations.min.slice().reverse();
this.data.aggregations.max = this.data.aggregations.max.slice().reverse();
this.data.aggregations.mean = this.data.aggregations.mean.slice().reverse();
}
const data = this.makeTimeAxis(this.data);
......
......@@ -81,6 +81,7 @@
[labelY]="report.vertical_label"
type="line"
[interactive]="false"
[isReversed]="isReversed"
></linechart>
</div>
......
......@@ -66,6 +66,7 @@ export class ReportComponent extends WidgetComponent implements AfterViewInit, O
@Input() identifier?: string;
// TODO: Make boolean
@Input() retroLogo?: string | number;
@Input() isReversed?: boolean;
@ViewChild(LineChartComponent, { static: false }) lineChart: LineChartComponent;
data: ReportingData;
......
......@@ -15,8 +15,13 @@
[retroLogo]="retroLogo"
[report]="activeReports[key]"
[identifier]="activeReports[key].identifiers[0]"
[isReversed]="isReportReversed(activeReports[key])"
></report>
<report
*ngIf="activeReports[key].identifiers.length == 0"
[report]="activeReports[key]"
[isReversed]="isReportReversed(activeReports[key])"
></report>
<report *ngIf="activeReports[key].identifiers.length == 0" [report]="activeReports[key]"></report>
</div>
<div class="bottom-spacer"></div>
</cdk-virtual-scroll-viewport>
......
......@@ -452,6 +452,10 @@ export class ReportsDashboardComponent implements OnInit, OnDestroy, /* HandleCh
});
}
isReportReversed(report: Report): boolean {
return report.name == 'cpu';
}
showConfigForm(): void {
const formComponent = this.modalService.openInSlideIn(ReportsConfigComponent);
formComponent.title = this.translate.instant('Reports Configuration');
......
......@@ -25,7 +25,7 @@
<div dynamicField [config]="diskField" [group]="diskFormGroup"></div>
</div>
</div>
<div *ngSwitch="VmDeviceType.Raw" fxFlex="100%" fxFlex.gt-xs="calc(100% - 16px)" class="form-line">
<div *ngSwitchCase="VmDeviceType.Raw" fxFlex="100%" fxFlex.gt-xs="calc(100% - 16px)" class="form-line">
<div *ngFor="let rawfileField of fieldSet.rawfileFieldConfig;">
<div dynamicField [config]="rawfileField" [group]="rawfileFormGroup"></div>
</div>
......
......@@ -26,10 +26,9 @@ import { EntityTableAction, EntityTableConfig } from 'app/modules/entity/entity-
import { EntityUtils } from 'app/modules/entity/utils';
import { VirtualMachineRow } from 'app/pages/vm/vm-list/virtual-machine-row.interface';
import {
WebSocketService, StorageService, AppLoaderService, DialogService, VmService, NetworkService, SystemGeneralService,
WebSocketService, StorageService, AppLoaderService, DialogService, VmService,
} from 'app/services';
import { ModalService } from 'app/services/modal.service';
import { PreferencesService } from 'app/services/preferences.service';
import { VmWizardComponent } from '../vm-wizard/vm-wizard.component';
@UntilDestroy()
......@@ -100,11 +99,7 @@ export class VmListComponent implements EntityTableConfig<VirtualMachineRow>, On
private http: HttpClient,
private modalService: ModalService,
private vmService: VmService,
private networkService: NetworkService,
private messageService: MessageService,
private prefService: PreferencesService,
private translate: TranslateService,
private systemGeneralService: SystemGeneralService,
) {
if (this.productType !== ProductType.Scale) {
// TODO: Check if it can be removed
......@@ -142,16 +137,21 @@ export class VmListComponent implements EntityTableConfig<VirtualMachineRow>, On
});
this.ws.subscribe('vm.query').pipe(untilDestroyed(this)).subscribe((event) => {
const changedRow = this.entityList.rows.find((o) => o.id === event.id);
if (event.fields.status.state === ServiceStatus.Running) {
changedRow.state = ServiceStatus.Running;
changedRow.status.state = event.fields.status.state;
changedRow.status.domain_state = event.fields.status.domain_state;
} else {
changedRow.state = ServiceStatus.Stopped;
changedRow.status.state = event.fields.status.state;
changedRow.status.domain_state = event.fields.status.domain_state;
}
entityList.patchCurrentRows(
(row: VirtualMachineRow) => row.id === event.id,
(changedRow) => {
if (event.fields.status.state === ServiceStatus.Running) {
changedRow.state = ServiceStatus.Running;
changedRow.status.state = event.fields.status.state;
changedRow.status.domain_state = event.fields.status.domain_state;
} else {
changedRow.state = ServiceStatus.Stopped;
changedRow.status.state = event.fields.status.state;
changedRow.status.domain_state = event.fields.status.domain_state;
}
return changedRow;
},
);
});
}
......@@ -277,7 +277,7 @@ export class VmListComponent implements EntityTableConfig<VirtualMachineRow>, On
}
doRowAction(row: VirtualMachineRow, method: ApiMethod, params: any[] = [row.id], updateTable = false): void {
if (method === 'vm.stop') {
if (method === this.wsMethods.stop) {
this.dialogRef = this.dialog.open(EntityJobComponent,
{ data: { title: this.translate.instant('Stopping {rowName}', { rowName: row.name }) } });
this.dialogRef.componentInstance.setCall(method, [params[0], params[1]]);
......@@ -557,7 +557,7 @@ export class VmListComponent implements EntityTableConfig<VirtualMachineRow>, On
{
id: 'SERIAL',
icon: 'keyboard_arrow_right',
label: this.translate.instant('Serial'),
label: this.translate.instant('Serial Shell'),
onClick: (vm: VirtualMachineRow) => {
this.router.navigate(new Array('').concat(['vm', 'serial', String(vm.id)]));
},
......
......@@ -3070,6 +3070,7 @@
"Serial Number": "",
"Serial Number:": "",
"Serial Port": "",
"Serial Shell": "",
"Serial Speed": "",
"Serial number for this disk.": "",
"Serial numbers of each disk being edited.": "",
......
......@@ -3070,6 +3070,7 @@
"Serial Number": "",
"Serial Number:": "",
"Serial Port": "",
"Serial Shell": "",
"Serial Speed": "",
"Serial number for this disk.": "",
"Serial numbers of each disk being edited.": "",
......
......@@ -3070,6 +3070,7 @@
"Serial Number": "",
"Serial Number:": "",
"Serial Port": "",
"Serial Shell": "",
"Serial Speed": "",
"Serial number for this disk.": "",
"Serial numbers of each disk being edited.": "",
......
......@@ -3070,6 +3070,7 @@
"Serial Number": "",
"Serial Number:": "",
"Serial Port": "",
"Serial Shell": "",
"Serial Speed": "",
"Serial number for this disk.": "",
"Serial numbers of each disk being edited.": "",
......
......@@ -3070,6 +3070,7 @@
"Serial Number": "",
"Serial Number:": "",
"Serial Port": "",
"Serial Shell": "",
"Serial Speed": "",
"Serial number for this disk.": "",
"Serial numbers of each disk being edited.": "",
......
......@@ -3070,6 +3070,7 @@
"Serial Number": "",
"Serial Number:": "",
"Serial Port": "",
"Serial Shell": "",
"Serial Speed": "",
"Serial number for this disk.": "",
"Serial numbers of each disk being edited.": "",
......
......@@ -3070,6 +3070,7 @@
"Serial Number": "",
"Serial Number:": "",
"Serial Port": "",
"Serial Shell": "",
"Serial Speed": "",
"Serial number for this disk.": "",
"Serial numbers of each disk being edited.": "",
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment