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

Kf1.7 jupyter apis index frontend #235

Merged
merged 3 commits into from
May 30, 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
80 changes: 37 additions & 43 deletions frontend/jupyter/src/app/pages/index/index-default/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,87 +5,80 @@ import {
ActionIconValue,
ActionButtonValue,
MenuValue,
DialogConfig,
ComponentValue,
TableConfig,
TABLE_THEME,
DateTimeValue,
LinkValue,
LinkType,
} from 'kubeflow';
import { ServerTypeComponent } from './server-type/server-type.component';
import { quantityToScalar } from '@kubernetes/client-node/dist/util';
import { ProtBComponent } from './protb-icon/protb-icon.component';

// --- Configs for the Confirm Dialogs ---
export function getDeleteDialogConfig(name: string): DialogConfig {
return {
title: $localize`Are you sure you want to delete this notebook server? ${name}`,
message: $localize`Warning: Your data might be lost if the notebook server
is not backed by persistent storage`,
accept: $localize`DELETE`,
confirmColor: 'warn',
cancel: $localize`CANCEL`,
error: '',
applying: $localize`DELETING`,
width: '600px',
};
}

export function getStopDialogConfig(name: string): DialogConfig {
return {
title: $localize`Are you sure you want to stop this notebook server? ${name}`,
message: $localize`Warning: Your data might be lost if the notebook server
is not backed by persistent storage.`,
accept: $localize`STOP`,
confirmColor: 'primary',
cancel: $localize`CANCEL`,
error: '',
applying: $localize`STOPPING`,
width: '600px',
};
}

// --- Config for the Resource Table ---
export const defaultConfig: TableConfig = {
dynamicNamespaceColumn: true,
columns: [
{
matHeaderCellDef: $localize`Status`,
matColumnDef: 'status',
value: new StatusValue(),
sort: true,
},
{
matHeaderCellDef: $localize`Name`,
matColumnDef: 'name',
style: { width: '25%' },
value: new PropertyValue({
field: 'name',
tooltipField: 'name',
value: new LinkValue({
field: 'link',
popoverField: 'name',
truncate: true,
linkType: LinkType.Internal,
}),
sort: true,
},
{
matHeaderCellDef: '',
matColumnDef: 'prot-b',
value: new ComponentValue({
component: ProtBComponent,
}),
sort: true,
},
{
matHeaderCellDef: $localize`Type`,
matColumnDef: 'type',
value: new ComponentValue({
component: ServerTypeComponent,
}),
},
{
matHeaderCellDef: $localize`Age`,
sort: true,
sortingPreprocessorFn: element => element.serverType,
filteringPreprocessorFn: element => {
if (element.serverType === 'group-one') {
return 'rstudio';
} else if (element.serverType === 'group-two') {
return 'ubuntu';
} else if (element.serverType === 'group-three') {
return 'sas';
} else {
return 'jupyterlab';
}
},
},
{
matHeaderCellDef: $localize`Created at`,
matColumnDef: 'age',
style: { width: '12%' },
textAlignment: 'right',
value: new PropertyValue({ field: 'age', truncate: true }),
value: new DateTimeValue({ field: 'age' }),
sort: true,
},
{
matHeaderCellDef: $localize`Last activity`,
matColumnDef: 'last_activity',
textAlignment: 'right',
value: new DateTimeValue({ field: 'last_activity' }),
sort: true,
},
{
matHeaderCellDef: $localize`Image`,
Expand All @@ -97,6 +90,7 @@ export const defaultConfig: TableConfig = {
truncate: true,
style: { maxWidth: '300px' },
}),
sort: true,
},
{
matHeaderCellDef: $localize`GPUs`,
Expand All @@ -107,25 +101,25 @@ export const defaultConfig: TableConfig = {
field: 'gpus.count',
tooltipField: 'gpus.message',
}),
sort: true,
},
{
matHeaderCellDef: $localize`CPUs`,
matColumnDef: 'cpu',
style: { width: '8%' },
textAlignment: 'right',
value: new PropertyValue({ field: 'cpu' }),
sort: true,
sortingPreprocessorFn: quantityToScalar,
},
{
matHeaderCellDef: $localize`Memory`,
matColumnDef: 'memory',
style: { width: '8%' },
textAlignment: 'right',
value: new PropertyValue({ field: 'memory' }),
},
{
matHeaderCellDef: $localize`Volumes`,
matColumnDef: 'volumes',
value: new MenuValue({ field: 'volumes', itemsIcon: 'storage' }),
sort: true,
sortingPreprocessorFn: quantityToScalar,
},

{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
<div class="lib-content-wrapper">
<lib-title-actions-toolbar title="Notebooks" [buttons]="buttons" i18n-title>
<lib-namespace-select *ngIf="!env.production"></lib-namespace-select>
<lib-namespace-select
*ngIf="(ns.dashboardConnected$ | async) === dashboardDisconnectedState"
namespacesUrl="/api/namespaces"
></lib-namespace-select>
</lib-title-actions-toolbar>

<!--scrollable page content-->
<div class="page-padding lib-flex-grow">
<div class="page-padding lib-flex-grow lib-overflow-auto">
<lib-table
[config]="config"
[data]="processedData"
Expand All @@ -16,7 +19,7 @@
<lib-title-actions-toolbar title="Volumes" i18n-title>
</lib-title-actions-toolbar>
<!--scrollable page content-->
<div class="page-padding lib-flex-grow">
<div class="page-padding lib-flex-grow lib-overflow-auto">
<lib-table
[config]="volumeConfig"
[data]="processedVolumeData"
Expand All @@ -27,7 +30,7 @@

<lib-title-actions-toolbar title="Cost" i18n-title>
</lib-title-actions-toolbar>
<div class="page-padding lib-flex-grow">
<div class="page-padding lib-flex-grow lib-overflow-auto">
<p i18n>Approximate cost of notebook server resources - summed values may not match total due to rounding</p>
<div>
<div class="table-header-elem">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,42 @@
import { CommonModule } from '@angular/common';
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import {
BackendService,
ConfirmDialogService,
KubeflowModule,
NamespaceService,
PollerService,
SnackBarService,
} from 'kubeflow';
import { Observable, of } from 'rxjs';
import { JWABackendService } from 'src/app/services/backend.service';

import { IndexDefaultComponent } from './index-default.component';

const JWABackendServiceStub: Partial<JWABackendService> = {
getNotebooks: () => of(),
deleteNotebook: () => of(),
startNotebook: () => of(),
stopNotebook: () => of(),
};

const NamespaceServiceStub: Partial<NamespaceService> = {
getSelectedNamespace: () => of(),
getSelectedNamespace2: () => of(),
};

const SnackBarServiceStub: Partial<SnackBarService> = {
open: () => {},
close: () => {},
};

const MockBackendService: Partial<BackendService> = {
getNamespaces(): Observable<string[]> {
return of([]);
},
};

describe('IndexDefaultComponent', () => {
let component: IndexDefaultComponent;
let fixture: ComponentFixture<IndexDefaultComponent>;
Expand All @@ -10,6 +45,15 @@ describe('IndexDefaultComponent', () => {
waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [IndexDefaultComponent],
imports: [CommonModule, KubeflowModule, RouterTestingModule],
providers: [
{ provide: JWABackendService, useValue: JWABackendServiceStub },
{ provide: NamespaceService, useValue: NamespaceServiceStub },
{ provide: SnackBarService, useValue: SnackBarServiceStub },
{ provide: PollerService, useValue: {} },
{ provide: ConfirmDialogService, useValue: {} },
{ provide: BackendService, useValue: MockBackendService },
],
}).compileComponents();
}),
);
Expand Down
Loading