Skip to content

Commit

Permalink
feat(ux): Add custom UX improvements
Browse files Browse the repository at this point in the history
* volume validation and tooltip handling
* correct missing key in status of notebook
* default workspace volume

Co-authored-by: Skye Turriff <turriff.skye@gmail.com>
Co-authored-by: saffaalvi <alvi118@uwindsor.ca>
Co-authored-by: Wendy Gaultier <wvgaultier@gmail.com>
  • Loading branch information
4 people committed Mar 9, 2022
1 parent 813f13a commit e1afc90
Show file tree
Hide file tree
Showing 12 changed files with 53 additions and 43 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,8 @@
"prepareDeleteVolume": "Preparing to delete the Volume...",
"unattached": "Unattached",
"toolTipDeleting": "Deleting",
"tooltipDeleteVolume": "Delete Volume '{{name}}'",
"tooltipDeleteVolumeName": "Delete Volume '{{name}}'",
"tooltipDeleteVolume": "Delete Volume",
"usedBy": "Used By",
"lblNone": "(none)"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@
"prepareDeleteVolume": "Préparation de la suppression du volume...",
"unattached": "Libre",
"toolTipDeleting": "En supression",
"tooltipDeleteVolumeName": "Supprimer le volume '{{name}}'",
"tooltipDeleteVolume": "Supprimer le volume",
"usedBy": "Utilisé par",
"lblNone": "(aucun)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,27 @@
<mat-spinner
*ngSwitchCase="STATUS_TYPE.WAITING"
diameter="24"
matTooltip="{{ config?.getTooltip(row).key | translate }}"
matTooltip="{{ config?.getTooltip(row).Key | translate }}"
matTooltipClass="custom-tooltip"
></mat-spinner>

<mat-spinner
*ngSwitchCase="STATUS_TYPE.TERMINATING"
diameter="24"
matTooltip="{{ config?.getTooltip(row).key | translate }}"
matTooltip="{{ config?.getTooltip(row).Key | translate }}"
matTooltipClass="custom-tooltip"
></mat-spinner>

<lib-icon
*ngSwitchCase="STATUS_TYPE.STOPPED"
matTooltip="{{ config?.getTooltip(row).key | translate }}"
matTooltip="{{ config?.getTooltip(row).Key | translate }}"
icon="custom:stoppedResource"
></lib-icon>

<mat-icon
*ngSwitchDefault
[ngClass]="config?.getCssClasses(row)"
matTooltip="{{ config?.getTooltip(row).key | translate }}"
matTooltip="{{ config?.getTooltip(row).Key | translate }}"
matTooltipClass="custom-tooltip"
>
{{ config?.getIcon(row) }}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
[pvcs]="pvcs"
[ephemeral]="false"
[defaultStorageClass]="defaultStorageClass"
[sizes]="['4Gi', '8Gi', '16Gi', '32Gi', '64Gi', '128Gi', '256Gi', '512Gi']"
[sizes]="['4', '8', '16', '32', '64', '128', '256', '512']"
>
</app-volume>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
<mat-checkbox formControlName="noWorkspace">
{{ 'jupyter.formWorkspaceVolume.ckbNoPersistent' | translate }}
</mat-checkbox>

<app-volume
[volume]="parentForm.get('workspace')"
[notebookName]="parentForm.value.name"
[pvcs]="pvcs"
[ephemeral]="parentForm.value.noWorkspace"
[namespace]="parentForm.value.namespace"
[defaultStorageClass]="defaultStorageClass"
[sizes]="['4Gi', '8Gi', '16Gi', '32Gi']"
[sizes]="['4', '8', '16', '32']"
>
</app-volume>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { Volume } from 'src/app/types';
import { updateNonDirtyControl, NamespaceService } from 'kubeflow';
import { ErrorStateMatcher } from '@angular/material/core';
import { JWABackendService } from "src/app/services/backend.service";
import { TranslateService } from "@ngx-translate/core";

@Component({
selector: 'app-volume',
Expand Down Expand Up @@ -116,6 +117,7 @@ export class VolumeComponent implements OnInit, OnDestroy {

// ----- Component Functions -----
constructor(
private translate: TranslateService,
private backend: JWABackendService,
private ns: NamespaceService) {}

Expand All @@ -140,7 +142,7 @@ export class VolumeComponent implements OnInit, OnDestroy {
this.volume.get('name').valueChanges.subscribe((name: string) => {
// Update the fields if the volume is an existing one
this.volume.get('name').setValue(name, { emitEvent: false });
this.updateVolInputFields();
this.updateVolInputFields();
}),
);
// Get the list of mounted volumes of the existing Notebooks in the selected Namespace
Expand Down Expand Up @@ -201,13 +203,13 @@ export class VolumeComponent implements OnInit, OnDestroy {
const volumeName = this.volume.get("name");

if (volumeName.hasError("required")) {
return `The volume name can't be empty`;
return this.translate.instant("jupyter.volume.errorNameRequired");
}
if (volumeName.hasError("pattern")) {
return `The volume name can only contain lowercase alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character`;
return this.translate.instant("jupyter.volume.errorNamePattern");
}
if (volumeName.hasError("isMounted")) {
return "The volume is already mounted to another notebook and cannot be currently selected";
return this.translate.instant("jupyter.volume.errorMountedVolume");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ export const defaultVolumeConfig = {
export function getDeleteVolumeDialogConfig(name: string): DialogConfig {
return { // TODO key + param
title: {
key: 'jupyter.volumeTable.tooltipDeleteVolume',
key: 'jupyter.volumeTable.tooltipDeleteVolumeName',
params: { name: name }
},
message: 'jupyter.volumeTable.deleteDialogMessage',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,11 @@ export class IndexDefaultComponent implements OnInit, OnDestroy {
}
},
err => {
if (!isEqual(this.rawCostData, err)) {
this.rawCostData = err;
if (!isEqual(this.rawCostData, err)) {
this.rawCostData = err;

this.processedCostData = this.processIncomingCostData(err);
this.poller.reset();
}
this.poller.reset();
}
});
}),
);
Expand Down Expand Up @@ -339,16 +338,16 @@ export class IndexDefaultComponent implements OnInit, OnDestroy {
element.status.message = "bound";
element.status.phase = STATUS_TYPE.MOUNTED;
element.status.key = {
key: "jupyter.volumeTable.attached",
params: null,
Key: "jupyter.volumeTable.attached",
Params: null,
};
} else {
element.status = {} as Status;
element.status.message = "unbound";
element.status.phase = STATUS_TYPE.UNMOUNTED;
element.status.key = {
key: "jupyter.volumeTable.unattached",
params: null,
Key: "jupyter.volumeTable.unattached",
Params: null,
};
}
});
Expand Down
4 changes: 2 additions & 2 deletions frontend/jupyter/src/app/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -279,8 +279,8 @@ export interface Status {
state: string;
message: string;
key: {
key: string;
params?: string[];
Key: string;
Params?: string[];
}
}
export interface AggregateCostObject {
Expand Down
8 changes: 6 additions & 2 deletions frontend/jupyter/src/assets/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,10 @@
"errorMountedVolume": "The volume is already mounted to another notebook and cannot be currently selected",
"sizeInGi": "Size in Gi",
"mode": "Mode",
"mountPoint": "Mount Point"
"mountPoint": "Mount Point",
"errorNameRequired": "The volume name can't be empty",
"errorNamePattern": "The volume name can only contain lowercase alphanumeric characters, '-' or '.', and must start and end with an alphanumeric character"

},
"resourceForm": {
"msgDefaultStorageClass": "No default Storage Class is set. Can't create new Disks for the new Notebook. Please use an Existing Disk."
Expand Down Expand Up @@ -123,7 +126,8 @@
"prepareDeleteVolume": "Preparing to delete the Volume...",
"unattached": "Unattached",
"toolTipDeleting": "Deleting",
"tooltipDeleteVolume": "Delete Volume '{{name}}'",
"tooltipDeleteVolumeName": "Delete Volume '{{name}}'",
"tooltipDeleteVolume": "Delete Volume",
"usedBy": "Used By",
"lblNone": "(none)"
},
Expand Down
5 changes: 4 additions & 1 deletion frontend/jupyter/src/assets/i18n/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@
"errorMountedVolume": "Le volume est déjà monté sur un autre bloc-notes et ne peut être sélectionné actuellement",
"sizeInGi": "Taille en Gi",
"mode": "Mode",
"mountPoint": "Point de montage"
"mountPoint": "Point de montage",
"errorNameRequired": "Le nom du volume ne peut pas être vide",
"errorNamePattern": "Le nom du volume ne peut contenir que des caractères alphanumériques en minuscule, '-' ou '.', et doit commencer et se terminer par un caractères alphanumériques"
},
"resourceForm": {
"msgDefaultStorageClass": "Aucun stockage par default n'est définie. Impossible de créer un nouveau disque pour le nouveau bloc-notes. Veuillez utiliser un disque existant."
Expand Down Expand Up @@ -123,6 +125,7 @@
"prepareDeleteVolume": "Préparation de la suppression du volume...",
"unattached": "Libre",
"toolTipDeleting": "En supression",
"tooltipDeleteVolumeName": "Supprimer le volume '{{name}}'",
"tooltipDeleteVolume": "Supprimer le volume",
"usedBy": "Utilisé par",
"lblNone": "(aucun)"
Expand Down
32 changes: 16 additions & 16 deletions notebooks.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,8 +121,8 @@ type notebookPhase string

// KeyType is the type of key
type KeyType struct {
key string
params []string
Key string
Params []string
}
// status represents the status of a notebook.
type status struct {
Expand Down Expand Up @@ -167,8 +167,8 @@ func processStatus(notebook *kubeflowv1.Notebook, events []*corev1.Event) status
Phase: NotebookPhaseTerminating,
Key:
KeyType{
key: "jupyter.backend.status.notebookDeleting",
params: []string{},
Key: "jupyter.backend.status.notebookDeleting",
Params: []string{},
},
}
}
Expand All @@ -180,8 +180,8 @@ func processStatus(notebook *kubeflowv1.Notebook, events []*corev1.Event) status
Message: "No pods are currently running for this Notebook Server.",
Phase: NotebookPhaseStopped,
Key: KeyType{
key: "jupyter.backend.status.noPodsRunning",
params: []string{},
Key: "jupyter.backend.status.noPodsRunning",
Params: []string{},
},
}
}
Expand All @@ -190,8 +190,8 @@ func processStatus(notebook *kubeflowv1.Notebook, events []*corev1.Event) status
Message: "Notebook Server is stopping.",
Phase: NotebookPhaseTerminating,
Key: KeyType{
key: "jupyter.backend.status.notebookStopping",
params: []string{},
Key: "jupyter.backend.status.notebookStopping",
Params: []string{},
},
}
}
Expand All @@ -204,8 +204,8 @@ func processStatus(notebook *kubeflowv1.Notebook, events []*corev1.Event) status
Message: "Running",
Phase: NotebookPhaseReady,
Key: KeyType{
key: "jupyter.backend.status.running",
params: []string{},
Key: "jupyter.backend.status.running",
Params: []string{},
},
}
}
Expand All @@ -215,8 +215,8 @@ func processStatus(notebook *kubeflowv1.Notebook, events []*corev1.Event) status
Message: state.Waiting.Reason,
Phase: NotebookPhaseWaiting,
Key: KeyType{
key: "jupyter.backend.status.waitingStatus",
params: []string{},
Key: "jupyter.backend.status.waitingStatus",
Params: []string{},
},
}
}
Expand All @@ -228,8 +228,8 @@ func processStatus(notebook *kubeflowv1.Notebook, events []*corev1.Event) status
Message: event.Reason,
Phase: NotebookPhaseWarning,
Key: KeyType{
key: "jupyter.backend.status.errorEvent",
params: []string{},
Key: "jupyter.backend.status.errorEvent",
Params: []string{},
},
}
}
Expand All @@ -239,8 +239,8 @@ func processStatus(notebook *kubeflowv1.Notebook, events []*corev1.Event) status
Message: "Scheduling the Pod",
Phase: NotebookPhaseWaiting,
Key: KeyType{
key: "jupyter.backend.status.schedulingPod",
params: []string{},
Key: "jupyter.backend.status.schedulingPod",
Params: []string{},
},
}
}
Expand Down

0 comments on commit e1afc90

Please sign in to comment.