Commit e7e0aabc authored by Evgeny Stepanovych's avatar Evgeny Stepanovych
Browse files

NAS-111347 - Improving type safety

parent 0f0e53fa
base DOCS DOCS-3538 NAS-010101 NAS-100796 NAS-105865 NAS-108939 NAS-110078 NAS-110081 NAS-110488 NAS-110533 NAS-110571 NAS-110777 NAS-110800 NAS-111664 NAS-111872 NAS-111962-master NAS-111989 NAS-112060 NAS-112080 NAS-112189 NAS-112273 NAS-112282 NAS-112307 NAS-112309 NAS-112309-alt NAS-112334 NAS-112343 NAS-112371 NAS-112556 NAS-112556-akt NAS-112617 NAS-112629 NAS-112663 NAS-112710 NAS-112724 NAS-112739 NAS-112767 NAS-112767-alt2 NAS-112767-mocks NAS-112771 NAS-112795 NAS-112846 NAS-112908 NAS-112921 NAS-112945 NAS-112969 NAS-112976 NAS-112995-22.12 NAS-113044 NAS-113053 NAS-113219 NAS-113238 NAS-113257 NAS-113292 NAS-113293-reproduction NAS-113363-3 NAS-113370 NAS-113375 NAS-113377 NAS-113378 NAS-113464 NAS-113464-alt NAS-113474 NAS-113486 NAS-113490 NAS-113511 NAS-113590 NAS-113598 NAS-113651 NAS-113671 NAS-113675 NAS-113679 NAS-113695 NAS-113701 NAS-113706 NAS-113708 NAS-113709 NAS-113723-22.02-RC.2 NAS-113733 NAS-113734 NAS-113738-22.02 NAS-113760 NAS-113790 NAS-113817 NAS-113821 NAS-113837 NAS-113860 NAS-113867 NAS-113876 NAS-113903 NAS-113903-2 NAS-113904-2 NAS-113953 NAS-114032 NAS-114045 NAS-114058 NAS-114084 NAS-114087 NAS-114088 NAS-114098 NAS-114171 NAS-114173 NAS-114179 NAS-114179-2 NAS-114204 NAS-114214 NAS-114215 NAS-114241 NAS-114338 NAS-114347 NAS-114389 NAS-114410 NAS-114413-2 NAS-114420 NAS-114428 NAS-114447 NAS-114448 NAS-114448-bluefin NAS-114471 NAS-114546 NAS-114549 NAS-114554 NAS-114607 NAS-114622 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-115887-22.02.1 NAS-115942-22.02 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-116422 NAS-116450 NAS-116469 NAS-116609 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-117713-12 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-118465 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 q5sys-3838 rel-v0.0.1 release-test/22.02.3 release/21.08-BETA.1 release/21.08-BETA.2 release/22.02 release/22.02-RC.1 release/22.02-RC.2 release/22.02-test release/22.02.1 release/22.02.2 release/22.02.3 release/22.02.4 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/angelfish stable/bluefin stable/cobia stable/dragonfish t1356-scaleuitest test-xxxyyy testing-refine-branchout-process testing-refine-branchout-process2 truenas/21.08-stable 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-22.02.4 TS-22.02.3 TS-22.02.2.1 TS-22.02.2 TS-22.02.1 TS-22.02.0.1 TS-22.02.0 TS-22.2.0 TS-22.02.RELEASE.1 TS-22.02-RC.2 TS-22.02-RC.1 TS-22.02-RC.1-2 TS-22.02-RC.1-1 TS-21.08-BETA.2 TS-21.08-BETA.1 TS-12.12.3 DN110M-CS-v2.0
No related merge requests found
Showing with 96 additions and 81 deletions
+96 -81
......@@ -8,7 +8,7 @@ import { CoreService } from 'app/core/services/core-service/core.service';
import { ProductType } from 'app/enums/product-type.enum';
import { CoreEvent } from 'app/interfaces/events';
import { LocaleService } from 'app/services/locale.service';
import { RoutePartsService } from 'app/services/route-parts/route-parts.service';
import { RoutePartsService, RoutePart } from 'app/services/route-parts/route-parts.service';
@UntilDestroy()
@Component({
......@@ -20,7 +20,7 @@ export class BreadcrumbComponent implements OnInit {
@Input() product_type: ProductType;
copyrightYear = this.localeService.getCopyrightYearFromBuildTime();
routeParts: any[];
routeParts: (RoutePart & { disabled?: boolean })[];
isEnabled = true;
constructor(private router: Router,
private routePartsService: RoutePartsService,
......
......@@ -40,7 +40,7 @@
</div>
<navigation (stateChange)="changeState($event)" (menuToggled)="toggleMenu($event)" (menuClosed)="toggleMenu()"></navigation>
<navigation (menuToggled)="toggleMenu($event)" (menuClosed)="toggleMenu()"></navigation>
<div class="sidenav-copyright-txt" *ngIf="!isSidenavCollapsed">
<div class="hostname-label" *ngIf="hostname" matTooltip="Hostname: {{hostname}}">{{hostname}}</div>
<div>TrueNAS {{product_type}}®</div>
......
......@@ -12,6 +12,7 @@ import { LayoutService } from 'app/core/services/layout.service';
import { ProductType } from 'app/enums/product-type.enum';
import { CoreEvent } from 'app/interfaces/events';
import { SysInfoEvent } from 'app/interfaces/events/sys-info-event.interface';
import { SubMenuItem } from 'app/interfaces/menu-item.interface';
import { WebSocketService, SystemGeneralService } from 'app/services';
import { LanguageService } from 'app/services/language.service';
import { LocaleService } from 'app/services/locale.service';
......@@ -42,7 +43,7 @@ export class AdminLayoutComponent implements OnInit, AfterViewChecked {
isOpen = false;
notificPanelClosed = false;
menuName: string;
subs: any[];
subs: SubMenuItem[];
copyrightYear = this.localeService.getCopyrightYearFromBuildTime();
readonly ProductType = ProductType;
......@@ -248,14 +249,6 @@ export class AdminLayoutComponent implements OnInit, AfterViewChecked {
this.isSidenotOpen = false;
}
changeState($event: any): void {
if ($event.transfer) {
if (this.media.isActive('xs') || this.media.isActive('sm')) {
this.sideNave.close();
}
}
}
openModal(id: string): void {
this.modalService.open(id, {});
}
......@@ -265,7 +258,7 @@ export class AdminLayoutComponent implements OnInit, AfterViewChecked {
}
// For the slide-in menu
toggleMenu(menuInfo?: any): void {
toggleMenu(menuInfo?: [string, SubMenuItem[]]): void {
if (this.isOpen && !menuInfo || this.isOpen && menuInfo[0] === this.menuName) {
this.isOpen = false;
} else if (menuInfo) {
......
......@@ -8,6 +8,7 @@ import { filter } from 'rxjs/operators';
import { ViewControllerComponent } from 'app/core/components/view-controller/view-controller.component';
import { ProductType } from 'app/enums/product-type.enum';
import { SysInfoEvent } from 'app/interfaces/events/sys-info-event.interface';
import { MenuItem, SubMenuItem } from 'app/interfaces/menu-item.interface';
import { WebSocketService } from 'app/services';
import { NavigationService } from 'app/services/navigation/navigation.service';
......@@ -19,13 +20,12 @@ import { NavigationService } from 'app/services/navigation/navigation.service';
export class NavigationComponent extends ViewControllerComponent implements OnInit {
hasIconTypeMenuItem: boolean;
iconTypeMenuTitle: string;
menuItems: any[];
menuItems: MenuItem[];
menuList = document.getElementsByClassName('top-level');
isHighlighted: string;
@Output() stateChange: EventEmitter<any> = new EventEmitter();
@Output() menuToggled: EventEmitter<any> = new EventEmitter();
@Output() menuClosed: EventEmitter<any> = new EventEmitter();
@Output() menuToggled: EventEmitter<[string, SubMenuItem[]]> = new EventEmitter();
@Output() menuClosed: EventEmitter<void> = new EventEmitter();
constructor(
private navService: NavigationService, private router: Router, private ws: WebSocketService,
......@@ -78,7 +78,7 @@ export class NavigationComponent extends ViewControllerComponent implements OnIn
});
}
toggleMenu(state: any, sub: any): void {
toggleMenu(state: string, sub: SubMenuItem[]): void {
this.menuToggled.emit([state, sub]);
}
......
......@@ -18,6 +18,7 @@ export enum ServiceName {
Ups = 'ups',
WebDav = 'webdav',
Http = 'http',
Kubernetes = 'kubernetes',
}
export const serviceNames = new Map<ServiceName, string>([
......
......@@ -403,7 +403,7 @@ export type ApiDirectory = {
'iscsi.initiator.delete': { params: any; response: any };
'iscsi.target.query': { params: any; response: IscsiTarget[] };
'iscsi.extent.disk_choices': { params: void; response: Choices };
'iscsi.extent.query': { params: any; response: IscsiExtent[] };
'iscsi.extent.query': { params: QueryParams<IscsiExtent>; response: IscsiExtent[] };
'iscsi.extent.create': { params: any; response: any };
'iscsi.extent.update': { params: any; response: any };
'iscsi.extent.delete': { params: any; response: any };
......@@ -671,7 +671,7 @@ export type ApiDirectory = {
'systemdataset.update': { params: [{ [poolName: string]: string }]; response: any };
// Service
'service.started': { params: any; response: any };
'service.started': { params: [ServiceName]; response: boolean };
'service.query': { params: QueryParams<Service>; response: Service[] };
'service.update': { params: [number, Partial<Service>]; response: number };
'service.start': { params: [ServiceName]; response: boolean };
......
export interface MenuItem {
type: string; // Possible values: link/slideOut/icon/separator/extLink
name?: string; // Used as display text for item and title for separator type
state?: string; // Router state
icon?: string; // Item icon name
tooltip?: string; // Tooltip text
disabled?: boolean; // If true, item will not be appeared in sidenav.
sub?: SubMenuItem[]; // Dropdown items
}
export interface SubMenuItem {
name: string; // Display text
state: string; // Router state
disabled?: boolean; // If true, item will not be appeared in sidenav.
}
import { ApiKey } from 'app/interfaces/api-key.interface';
export type ApiKeysRow = ApiKey & { created_time: string };
......@@ -12,6 +12,7 @@ import { LocaleService } from 'app/services/locale.service';
import { ConfirmDialog } from '../common/confirm-dialog/confirm-dialog.component';
import { DialogFormConfiguration } from '../common/entity/entity-dialog/dialog-form-configuration.interface';
import { EntityUtils } from '../common/entity/utils';
import { ApiKeysRow } from './api-keys-row.interface';
@UntilDestroy()
@Component({
......@@ -27,7 +28,7 @@ export class ApiKeysComponent implements EntityTableConfig {
addCall: 'api_key.create' = 'api_key.create';
editCall: 'api_key.update' = 'api_key.update';
currItem: any;
currItem: ApiKeysRow;
entityList: EntityTableComponent;
columns = [
......@@ -106,11 +107,11 @@ export class ApiKeysComponent implements EntityTableConfig {
afterInit(entityList: EntityTableComponent): void {
this.entityList = entityList;
}
resourceTransformIncomingRestData(data: ApiKey[]): any[] {
resourceTransformIncomingRestData(data: ApiKey[]): ApiKeysRow[] {
return data.map((item) => {
return {
...item,
created_time: this.localeService.formatDateTime(item.created_at.$date as any),
created_time: this.localeService.formatDateTime(item.created_at.$date),
};
});
}
......@@ -119,7 +120,7 @@ export class ApiKeysComponent implements EntityTableConfig {
const that = entityDialogForm.parent;
if (that.currItem) {
that.ws.call(that.editCall, [that.currItem.id, entityDialogForm.formValue]).pipe(untilDestroyed(this)).subscribe(
(res: any) => {
(res) => {
entityDialogForm.dialogRef.close(true);
if (res.key) {
that.displayKey(res.key);
......@@ -132,7 +133,7 @@ export class ApiKeysComponent implements EntityTableConfig {
);
} else {
that.ws.call(that.addCall, [entityDialogForm.formValue]).pipe(untilDestroyed(this)).subscribe(
(res: any) => {
(res) => {
entityDialogForm.dialogRef.close(true);
that.displayKey(res.key);
that.entityList.getData();
......@@ -160,13 +161,13 @@ export class ApiKeysComponent implements EntityTableConfig {
};
}
getActions(): EntityTableAction[] {
getActions(): EntityTableAction<ApiKeysRow>[] {
return [{
name: helptext.action_edit,
id: 'edit',
icon: 'edit',
label: 'Edit',
onClick: (rowinner: any) => {
onClick: (rowinner: ApiKeysRow) => {
this.apikeysFormConf.title = helptext.formDialog.edit_title;
this.apikeysFormConf.saveButtonText = helptext.formDialog.edit_button;
this.apikeysFormConf.method_ws = this.editCall;
......@@ -178,7 +179,7 @@ export class ApiKeysComponent implements EntityTableConfig {
id: 'delete',
icon: 'delete',
label: 'Delete',
onClick: (rowinner: any) => {
onClick: (rowinner: ApiKeysRow) => {
this.entityList.doDelete(rowinner);
},
}] as EntityTableAction[];
......
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';
import { ServiceName } from 'app/enums/service-name.enum';
import { UpgradeSummary } from 'app/interfaces/application.interface';
import { Catalog, CatalogApp } from 'app/interfaces/catalog.interface';
import { ChartReleaseEvent } from 'app/interfaces/chart-release-event.interface';
......@@ -23,8 +24,8 @@ export class ApplicationsService {
return this.ws.call('kubernetes.config');
}
getKubernetesServiceStarted(): Observable<any> {
return this.ws.call('service.started', ['kubernetes']);
getKubernetesServiceStarted(): Observable<boolean> {
return this.ws.call('service.started', [ServiceName.Kubernetes]);
}
getAllCatalogItems(): Observable<Catalog[]> {
......
......@@ -797,12 +797,12 @@ export class EntityTableComponent<Row = any> implements OnInit, AfterViewInit, O
// this.modalService.open('slide-in-form', this.conf.addComponent);
}
doEdit(id: string): void {
doEdit(id: string | number): void {
if (this.conf.doEdit) {
this.conf.doEdit(id, this);
} else {
this.router.navigate(
new Array('/').concat(this.conf.route_edit).concat(id),
new Array('/').concat(this.conf.route_edit).concat(id as any),
);
}
}
......
......@@ -55,8 +55,8 @@ export interface EntityTableConfig<Row = any> {
getActions?: (row: Row) => EntityTableAction<Row>[];
getAddActions?: () => any[];
rowValue?: (row: unknown, attr: string) => unknown;
wsMultiDeleteParams?: (selected: any) => any;
updateMultiAction?: (selected: any) => any;
wsMultiDeleteParams?: (selected: Row[]) => any;
updateMultiAction?: (selected: Row[]) => any;
doAdd?: (id?: string | number, tableComponent?: EntityTableComponent) => void;
doEdit?: (id?: string | number, tableComponent?: EntityTableComponent) => void;
onCheckboxChange?: (row: Row) => void;
......
......@@ -3,9 +3,9 @@ import {
Component, ElementRef, Input, OnInit, ViewChild,
} from '@angular/core';
import { ServiceStatus } from 'app/enums/service-status.enum';
import { InputTableConf } from 'app/pages/common/entity/table/table.component';
import { AppTableConfig } from 'app/pages/common/entity/table/table.component';
export interface InputExpandableTableConf extends InputTableConf {
export interface InputExpandableTableConf extends AppTableConfig {
detailsHref?: string;
expandableTableComponent?: ExpandableTableComponent;
limitRows?: number;
......
......@@ -2,17 +2,16 @@ import {
Component, OnInit, Input, ViewChild, AfterViewInit, AfterViewChecked,
} from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { MatCellDef } from '@angular/material/table/cell';
import { JobState } from 'app/enums/job-state.enum';
import { WebSocketService } from 'app/services';
import { EmptyConfig, EmptyType } from '../entity-empty/entity-empty.component';
import { TableService } from './table.service';
export interface AppTableAction {
export interface AppTableAction<Row = any> {
name: string;
icon: string;
matTooltip?: string;
onClick: (element: MatCellDef) => void;
onClick: (row: Row) => void;
}
export interface AppTableHeaderAction {
......@@ -22,7 +21,7 @@ export interface AppTableHeaderAction {
export interface AppTableHeaderExtraAction extends AppTableHeaderAction {}
export interface InputTableConf {
export interface AppTableConfig {
title?: string;
titleHref?: string;
columns: any[];
......@@ -71,7 +70,7 @@ export interface InputTableConf {
export class TableComponent implements OnInit, AfterViewInit, AfterViewChecked {
@ViewChild('table') table: any;
_tableConf: InputTableConf;
_tableConf: AppTableConfig;
title = '';
titleHref: string;
dataSource: any[];
......@@ -94,11 +93,11 @@ export class TableComponent implements OnInit, AfterViewInit, AfterViewChecked {
private entityEmptyLarge = false;
private enableViewMore = false;
get tableConf(): InputTableConf {
get tableConf(): AppTableConfig {
return this._tableConf;
}
@Input('conf') set tableConf(conf: InputTableConf) {
@Input('conf') set tableConf(conf: AppTableConfig) {
if (!this._tableConf) {
this._tableConf = conf;
} else {
......
......@@ -2,8 +2,10 @@ import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { KeychainCredentialType } from 'app/enums/keychain-credential-type.enum';
import { CloudsyncCredential } from 'app/interfaces/cloudsync-credential.interface';
import { CloudsyncProvider } from 'app/interfaces/cloudsync-provider.interface';
import { AppTableAction } from 'app/pages/common/entity/table/table.component';
import { KeychainCredential } from 'app/interfaces/keychain-credential.interface';
import { AppTableAction, AppTableConfig } from 'app/pages/common/entity/table/table.component';
import {
WebSocketService, KeychainCredentialService, AppLoaderService,
DialogService, ReplicationService, StorageService, CloudCredentialService,
......@@ -21,7 +23,7 @@ import { SshKeypairsFormComponent } from './forms/ssh-keypairs-form.component';
providers: [KeychainCredentialService, ReplicationService, CloudCredentialService],
})
export class BackupCredentialsComponent implements OnInit {
cards: any;
cards: { name: string; tableConf: AppTableConfig }[];
// Components included in this dashboard
protected sshConnections: SshConnectionsFormComponent;
......@@ -56,7 +58,6 @@ export class BackupCredentialsComponent implements OnInit {
this.cards = [
{
name: 'cloudCredentials',
flex: 40,
tableConf: {
title: 'Cloud Credentials',
queryCall: 'cloudsync.credentials.query',
......@@ -71,14 +72,13 @@ export class BackupCredentialsComponent implements OnInit {
add() {
this.parent.modalService.open('slide-in-form', this.parent.cloudCredentials);
},
edit(row: any) {
edit(row: CloudsyncCredential) {
this.parent.modalService.open('slide-in-form', this.parent.cloudCredentials, row.id);
},
dataSourceHelper: this.cloudCredentialsDataSourceHelper.bind(this),
},
}, {
name: 'sshConnections',
flex: 30,
tableConf: {
title: 'SSH Connections',
queryCall: 'keychaincredential.query',
......@@ -93,13 +93,12 @@ export class BackupCredentialsComponent implements OnInit {
add() {
this.parent.modalService.open('slide-in-form', this.parent.sshConnections);
},
edit(row: any) {
edit(row: KeychainCredential) {
this.parent.modalService.open('slide-in-form', this.parent.sshConnections, row.id);
},
},
}, {
name: 'sshKeypairs',
flex: 30,
tableConf: {
title: 'SSH Keypairs',
queryCall: 'keychaincredential.query',
......@@ -115,7 +114,7 @@ export class BackupCredentialsComponent implements OnInit {
add() {
this.parent.modalService.open('slide-in-form', this.parent.sshKeypairs);
},
edit(row: any) {
edit(row: KeychainCredential) {
this.parent.modalService.open('slide-in-form', this.parent.sshKeypairs, row.id);
},
},
......@@ -123,7 +122,7 @@ export class BackupCredentialsComponent implements OnInit {
];
}
cloudCredentialsDataSourceHelper(res: any[]): any[] {
cloudCredentialsDataSourceHelper(res: CloudsyncCredential[]): CloudsyncCredential[] {
return res.map((item) => {
if (this.providers) {
const credentialProvider = this.providers.find((provider) => provider.name == item.provider);
......@@ -135,11 +134,11 @@ export class BackupCredentialsComponent implements OnInit {
});
}
sshConnectionsDataSourceHelper(res: any[]): any[] {
sshConnectionsDataSourceHelper(res: KeychainCredential[]): KeychainCredential[] {
return res.filter((item) => item.type === KeychainCredentialType.SshCredentials);
}
sshKeyPairsDataSourceHelper(res: any[]): any[] {
sshKeyPairsDataSourceHelper(res: KeychainCredential[]): KeychainCredential[] {
return res.filter((item) => item.type === KeychainCredentialType.SshKeyPair);
}
......
......@@ -5,19 +5,21 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import * as _ from 'lodash';
import { helptext_system_ca } from 'app/helptext/system/ca';
import { helptext_system_certificates } from 'app/helptext/system/certificates';
import { CertificateAuthority } from 'app/interfaces/certificate-authority.interface';
import { Certificate } from 'app/interfaces/certificate.interface';
import { Option } from 'app/interfaces/option.interface';
import { DialogFormConfiguration } from 'app/pages/common/entity/entity-dialog/dialog-form-configuration.interface';
import { EntityDialogComponent } from 'app/pages/common/entity/entity-dialog/entity-dialog.component';
import { FieldConfig } from 'app/pages/common/entity/entity-form/models/field-config.interface';
import { EntityFormService } from 'app/pages/common/entity/entity-form/services/entity-form.service';
import { AppTableAction } from 'app/pages/common/entity/table/table.component';
import { AppTableAction, AppTableConfig } from 'app/pages/common/entity/table/table.component';
import { EntityUtils } from 'app/pages/common/entity/utils';
import { AcmednsFormComponent } from 'app/pages/credentials/certificates-dash/forms/acmedns-form.component';
import {
SystemGeneralService, WebSocketService, AppLoaderService, DialogService, StorageService,
} from 'app/services';
import { ModalService } from 'app/services/modal.service';
import { T } from 'app/translate-marker';
import { AcmednsFormComponent } from './forms/acmedns-form.component';
import { CertificateAuthorityAddComponent } from './forms/ca-add.component';
import { CertificateAuthorityEditComponent } from './forms/ca-edit.component';
import { CertificateAcmeAddComponent } from './forms/certificate-acme-add.component';
......@@ -31,7 +33,7 @@ import { CertificateEditComponent } from './forms/certificate-edit.component';
providers: [EntityFormService],
})
export class CertificatesDashComponent implements OnInit {
cards: any;
cards: { name: string; tableConf: AppTableConfig }[];
protected certificateAddComponent: CertificateAddComponent;
protected certificateEditComponent: CertificateEditComponent;
......@@ -105,7 +107,7 @@ export class CertificatesDashComponent implements OnInit {
add() {
this.parent.modalService.open('slide-in-form', this.parent.certificateAddComponent);
},
edit(row: any) {
edit(row: Certificate) {
this.parent.modalService.open('slide-in-form', this.parent.certificateEditComponent, row.id);
},
},
......@@ -132,7 +134,7 @@ export class CertificatesDashComponent implements OnInit {
add() {
this.parent.modalService.open('slide-in-form', this.parent.certificateAddComponent, 'csr');
},
edit(row: any) {
edit(row: Certificate) {
this.parent.modalService.open('slide-in-form', this.parent.certificateEditComponent, row.id);
},
},
......@@ -161,10 +163,10 @@ export class CertificatesDashComponent implements OnInit {
add() {
this.parent.modalService.open('slide-in-form', this.parent.certificateAuthorityAddComponent);
},
edit(row: any) {
edit(row: CertificateAuthority) {
this.parent.modalService.open('slide-in-form', this.parent.certificateAuthorityEditComponent, row.id);
},
delete(row: any, table: any) {
delete(row: CertificateAuthority, table: any) {
if (row.signed_certificates > 0) {
(this.parent.dialogService as DialogService).confirm({
title: helptext_system_ca.delete_error.title,
......@@ -194,7 +196,7 @@ export class CertificatesDashComponent implements OnInit {
add() {
this.parent.modalService.open('slide-in-form', this.parent.acmeDNSComponent);
},
edit(row: any) {
edit(row: CertificateAuthority) {
this.parent.modalService.open('slide-in-form', this.parent.acmeDNSComponent, row.id);
},
},
......@@ -211,7 +213,7 @@ export class CertificatesDashComponent implements OnInit {
return res.filter((item) => item.certificate !== null);
}
csrDataSourceHelper(res: any[]): any[] {
csrDataSourceHelper(res: Certificate[]): Certificate[] {
return res.filter((item) => item.CSR !== null);
}
......@@ -250,7 +252,7 @@ export class CertificatesDashComponent implements OnInit {
icon: 'save_alt',
name: 'download',
onClick: (rowinner: any) => {
onClick: (rowinner: Certificate) => {
const path = rowinner.CSR ? rowinner.csr_path : rowinner.certificate_path;
const fileName = rowinner.name + '.crt'; // what about for a csr?
this.ws.call('core.download', ['filesystem.get', [path], fileName]).pipe(untilDestroyed(this)).subscribe(
......@@ -294,13 +296,13 @@ export class CertificatesDashComponent implements OnInit {
return this.downloadActions;
}
csrActions(): AppTableAction[] {
csrActions(): AppTableAction<Certificate>[] {
const csrRowActions = [...this.downloadActions];
const acmeAction = {
icon: 'build',
name: 'create_ACME',
matTooltip: T('Create ACME Certificate'),
onClick: (rowinner: any) => {
onClick: (rowinner: Certificate) => {
this.modalService.open('slide-in-form', this.acmeAddComponent, rowinner.id);
event.stopPropagation();
},
......@@ -309,13 +311,13 @@ export class CertificatesDashComponent implements OnInit {
return csrRowActions;
}
caActions(): AppTableAction[] {
caActions(): AppTableAction<CertificateAuthority>[] {
const caRowActions = [...this.downloadActions];
const acmeAction = {
icon: 'beenhere',
name: 'sign_CSR',
matTooltip: helptext_system_ca.list.action_sign,
onClick: (rowinner: any) => {
onClick: (rowinner: CertificateAuthority) => {
this.dialogService.dialogForm(this.signCSRFormConf);
this.caId = rowinner.id;
event.stopPropagation();
......@@ -325,7 +327,7 @@ export class CertificatesDashComponent implements OnInit {
return caRowActions;
}
openForm(component: any, id: any): void {
openForm(component: CertificateAcmeAddComponent, id: any): void {
setTimeout(() => {
this.modalService.open('slide-in-form', component, id);
}, 200);
......
......@@ -3,6 +3,7 @@ import { FormGroup, Validators } from '@angular/forms';
import { MatDialog } from '@angular/material/dialog';
import { Router, ActivatedRoute } from '@angular/router';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { TreeNode } from 'angular-tree-component';
import * as filesize from 'filesize';
import * as _ from 'lodash';
import { Observable } from 'rxjs';
......@@ -465,7 +466,7 @@ export class CloudsyncFormComponent implements FormConfiguration {
return this.ws.call('cloudsync.list_buckets', [credential.id]);
}
getChildren(node: any): Promise<Promise<any>> {
getChildren(node: TreeNode): Promise<Promise<any>> {
const credential = this.formGroup.controls['credentials'].value;
let bucket = this.formGroup.controls['bucket'].value;
if (this.bucket_field.disabled) {
......@@ -490,7 +491,7 @@ export class CloudsyncFormComponent implements FormConfiguration {
}
}
getBucketFolders(credential: string, bucket: string, node: any): Promise<any> {
getBucketFolders(credential: string, bucket: string, node: TreeNode): Promise<any> {
const formValue = this.entityForm.formGroup.value;
const children: any[] = [];
const data = {
......@@ -606,8 +607,8 @@ export class CloudsyncFormComponent implements FormConfiguration {
this.bucket_input_field = this.fieldSets.config('bucket_input');
this.setDisabled('bucket', true, true);
this.setDisabled('bucket_input', true, true);
this.cloudcredentialService.getCloudsyncCredentials().then((credentials: any) => {
credentials.forEach((item: any) => {
this.cloudcredentialService.getCloudsyncCredentials().then((credentials) => {
credentials.forEach((item) => {
this.credentials.options.push({ label: item.name + ' (' + item.provider + ')', value: item.id });
this.credentials_list.push(item);
});
......@@ -654,7 +655,7 @@ export class CloudsyncFormComponent implements FormConfiguration {
}
});
this.formGroup.get('path_source').valueChanges.pipe(untilDestroyed(this)).subscribe((values: any) => {
this.formGroup.get('path_source').valueChanges.pipe(untilDestroyed(this)).subscribe((values: string | string[]) => {
if (!values) {
return;
}
......
......@@ -29,7 +29,7 @@ import { DialogFormConfiguration } from 'app/pages/common/entity/entity-dialog/d
import { EntityDialogComponent } from 'app/pages/common/entity/entity-dialog/entity-dialog.component';
import { EntityFormService } from 'app/pages/common/entity/entity-form/services/entity-form.service';
import { EntityJobComponent } from 'app/pages/common/entity/entity-job/entity-job.component';
import { AppTableAction, InputTableConf } from 'app/pages/common/entity/table/table.component';
import { AppTableAction, AppTableConfig } from 'app/pages/common/entity/table/table.component';
import { EntityUtils } from 'app/pages/common/entity/utils';
import { CloudsyncFormComponent } from 'app/pages/data-protection/cloudsync/cloudsync-form/cloudsync-form.component';
import { ReplicationFormComponent } from 'app/pages/data-protection/replication/replication-form/replication-form.component';
......@@ -55,7 +55,7 @@ import { T } from 'app/translate-marker';
export interface TaskCard {
name: string;
tableConf: InputTableConf;
tableConf: AppTableConfig;
}
enum TaskCardId {
......
......@@ -368,7 +368,7 @@ export class ActiveDirectoryComponent implements FormConfiguration {
_.find(this.fieldConfig, { name: 'bindpw' })['required'] = res;
});
entityEdit.formGroup.controls['kerberos_principal'].valueChanges.pipe(untilDestroyed(this)).subscribe((res: any) => {
entityEdit.formGroup.controls['kerberos_principal'].valueChanges.pipe(untilDestroyed(this)).subscribe((res: string) => {
if (res) {
entityEdit.setDisabled('bindname', true);
entityEdit.setDisabled('bindpw', true);
......
......@@ -6,7 +6,7 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import helptext from 'app/helptext/directory-service/dashboard';
import idmapHelptext from 'app/helptext/directory-service/idmap';
import { EmptyType } from 'app/pages/common/entity/entity-empty/entity-empty.component';
import { InputTableConf } from 'app/pages/common/entity/table/table.component';
import { AppTableConfig } from 'app/pages/common/entity/table/table.component';
import { ActiveDirectoryComponent } from 'app/pages/directory-service/active-directory/active-directory.component';
import { KerberosKeytabsFormComponent } from 'app/pages/directory-service/kerberos-keytabs/kerberos-keytabs-form.component';
import { KerberosRealmsFormComponent } from 'app/pages/directory-service/kerberos-realms/kerberos-realms-form.component';
......@@ -51,7 +51,7 @@ export class DirectoryServicesComponent implements OnInit {
message: T('To configure sysctls, click the "Add" button.'),
};
idmapTableConf: InputTableConf = {
idmapTableConf: AppTableConfig = {
title: helptext.idmap.title,
titleHref: '/directoryservice/idmap',
queryCall: 'idmap.query',
......@@ -80,7 +80,7 @@ export class DirectoryServicesComponent implements OnInit {
},
};
kerberosRealmsTableConf: InputTableConf = {
kerberosRealmsTableConf: AppTableConfig = {
title: helptext.kerberosRealms.title,
titleHref: '/directoryservice/kerberosrealms',
queryCall: 'kerberos.realm.query',
......@@ -105,7 +105,7 @@ export class DirectoryServicesComponent implements OnInit {
},
};
kerberosKeytabTableConf: InputTableConf = {
kerberosKeytabTableConf: AppTableConfig = {
title: helptext.kerberosKeytab.title,
titleHref: '/directoryservice/kerberoskeytabs',
queryCall: 'kerberos.keytab.query',
......
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