You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@texera.apache.org by gi...@apache.org on 2026/07/09 02:10:32 UTC
(texera) branch gh-readonly-queue/main/pr-6263-2b9c7afabb89474ce988358c797f8949e058f158 created (now 00572931bf)
This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a change to branch gh-readonly-queue/main/pr-6263-2b9c7afabb89474ce988358c797f8949e058f158
in repository https://gitbox.apache.org/repos/asf/texera.git
at 00572931bf fix(frontend): correct JVM memory slider spacing and tooltip formatting (#6263)
This branch includes the following new commits:
new 00572931bf fix(frontend): correct JVM memory slider spacing and tooltip formatting (#6263)
The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
(texera) 01/01: fix(frontend): correct JVM memory slider spacing and tooltip formatting (#6263)
Posted by gi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/main/pr-6263-2b9c7afabb89474ce988358c797f8949e058f158
in repository https://gitbox.apache.org/repos/asf/texera.git
commit 00572931bf6d5644833efc838b9efa6792c60135
Author: roshiiiiz <ro...@gmail.com>
AuthorDate: Thu Jul 9 07:08:26 2026 +0500
fix(frontend): correct JVM memory slider spacing and tooltip formatting (#6263)
<!--
Thanks for sending a pull request (PR)! Here are some tips for you:
1. If this is your first time, please read our contributor guidelines:
[Contributing to
Texera](https://github.com/apache/texera/blob/main/CONTRIBUTING.md)
2. Ensure you have added or run the appropriate tests for your PR
3. If the PR is work in progress, mark it a draft on GitHub.
4. Please write your PR title to summarize what this PR proposes, we
are following Conventional Commits style for PR titles as well.
5. Be sure to keep the PR description updated to reflect all changes.
-->
### What changes were proposed in this PR?
This PR fixes a UI rendering issue with the JVM Memory slider in the
computing unit creation modals. Because the slider steps are non-linear
(2, 4, 128, 256), the UI component was previously spacing them
proportionally, causing the tick marks to clump together awkwardly. This
PR ensures the steps are spaced evenly across the slider while correctly
displaying the actual Gigabyte sizes in the hover tooltip.
**Changes made:**
- Updated `computing-unit.util.ts` to map the JVM memory sizes to
sequential indices (0, 1, 2, 3...) to force perfect, even spacing across
the slider component.
- Added a `jvmMemoryTipFormatter` function in
`user-computing-unit.component.ts` and
`computing-unit-selection.component.ts` to dynamically translate the raw
slider index back into the literal memory string (e.g., "256G") for the
tooltip.
- Adjusted the `[nzMin]` and `[nzMax]` properties and bound the
`[nzTipFormatter]` in the corresponding `.html` templates for both the
Workspace and User Dashboard computing unit modals.
### Any related issues, documentation, discussions?
Issue##3375
### How was this PR tested?
Tested manually in a local development environment:
- Booted the local dashboard and backend via `docker-compose`.
- Opened the "Create Computing Unit" modal in both the User Dashboard
and the Workspace "Power Button" dropdown.
- Switched the Computing Unit type to "Kubernetes" to display the JVM
memory slider.
- Interacted with the slider and verified that the spacing is perfectly
distributed, and the black tooltip correctly displays the literal memory
size (2G, 4G, 128G, 256G) when hovering/clicking.
### Was this PR authored or co-authored using generative AI tooling?
Generated-by: Antigravity (DeepMind)
**Before:**
<img width="1600" height="786" alt="WhatsApp Image 2026-07-08 at 05 07
27"
src="https://github.com/user-attachments/assets/d73dcc23-5111-4301-9155-e4a90c1ead08"
/>
**After**
<img width="1918" height="942" alt="Issue 3375"
src="https://github.com/user-attachments/assets/3ace999b-87d1-4608-8d66-eb7a7f5e29b3"
/>
---------
Co-authored-by: probe <pr...@x>
---
.../computing-unit-create-modal.component.html | 5 ++--
.../computing-unit-create-modal.component.spec.ts | 18 +++++------
.../computing-unit-create-modal.component.ts | 35 ++++++++++++----------
.../src/app/common/util/computing-unit.util.ts | 23 +++++---------
4 files changed, 39 insertions(+), 42 deletions(-)
diff --git a/frontend/src/app/common/component/computing-unit-create-modal/computing-unit-create-modal.component.html b/frontend/src/app/common/component/computing-unit-create-modal/computing-unit-create-modal.component.html
index 462f506dbd..1ab9f0bd18 100644
--- a/frontend/src/app/common/component/computing-unit-create-modal/computing-unit-create-modal.component.html
+++ b/frontend/src/app/common/component/computing-unit-create-modal/computing-unit-create-modal.component.html
@@ -171,9 +171,10 @@
*ngIf="showJvmMemorySlider"
class="jvm-memory-slider"
[nzMarks]="jvmMemoryMarks"
- [nzMin]="jvmMemorySteps[0] || 2"
+ [nzMin]="0"
[nzMax]="jvmMemoryMax"
- [nzStep]="null"
+ [nzTipFormatter]="jvmMemoryTipFormatter"
+ [nzStep]="1"
[nzIncluded]="false"
[ngModel]="jvmMemorySliderValue"
(ngModelChange)="onJvmMemorySliderChange($event)">
diff --git a/frontend/src/app/common/component/computing-unit-create-modal/computing-unit-create-modal.component.spec.ts b/frontend/src/app/common/component/computing-unit-create-modal/computing-unit-create-modal.component.spec.ts
index 1b0782ca9a..dd4eaf0231 100644
--- a/frontend/src/app/common/component/computing-unit-create-modal/computing-unit-create-modal.component.spec.ts
+++ b/frontend/src/app/common/component/computing-unit-create-modal/computing-unit-create-modal.component.spec.ts
@@ -369,8 +369,8 @@ describe("ComputingUnitCreateModalComponent", () => {
component.onJvmMemorySliderChange(component.jvmMemoryMax - 1);
- expect(component.jvmMemorySteps).toContain(component.jvmMemorySliderValue);
- expect(component.selectedJvmMemorySize).toBe(`${component.jvmMemorySliderValue}G`);
+ expect(component.jvmMemorySteps).toContain(component.jvmMemorySteps[component.jvmMemorySliderValue]);
+ expect(component.selectedJvmMemorySize).toBe(`${component.jvmMemorySteps[component.jvmMemorySliderValue]}G`);
});
it("flags max JVM memory only when the slider is shown at its maximum", () => {
@@ -381,7 +381,7 @@ describe("ComputingUnitCreateModalComponent", () => {
component.onJvmMemorySliderChange(component.jvmMemoryMax);
expect(component.isMaxJvmMemorySelected()).toBe(true);
- component.onJvmMemorySliderChange(component.jvmMemorySteps[0]);
+ component.onJvmMemorySliderChange(0);
expect(component.isMaxJvmMemorySelected()).toBe(false);
});
@@ -389,12 +389,12 @@ describe("ComputingUnitCreateModalComponent", () => {
fixture.detectChanges();
component.selectedMemory = "8Gi";
component.onMemorySelectionChange();
- component.onJvmMemorySliderChange(4);
+ component.onJvmMemorySliderChange(1); // Index 1 for 4G in [2, 4, 6]
component.selectedMemory = "4096Mi";
component.onMemorySelectionChange();
- expect(component.jvmMemorySliderValue).toBe(4);
+ expect(component.jvmMemorySliderValue).toBe(1);
expect(component.selectedJvmMemorySize).toBe("4G");
});
@@ -402,7 +402,7 @@ describe("ComputingUnitCreateModalComponent", () => {
fixture.detectChanges();
component.selectedMemory = "8Gi";
component.onMemorySelectionChange();
- component.onJvmMemorySliderChange(4);
+ component.onJvmMemorySliderChange(1);
component.selectedMemory = "2";
component.onMemorySelectionChange();
@@ -584,7 +584,7 @@ describe("ComputingUnitCreateModalComponent", () => {
sliderNgModel.viewToModelUpdate(component.jvmMemoryMax);
tick();
expect(component.jvmMemorySliderValue).toBe(component.jvmMemoryMax);
- expect(component.selectedJvmMemorySize).toBe(`${component.jvmMemoryMax}G`);
+ expect(component.selectedJvmMemorySize).toBe(`${component.jvmMemorySteps[component.jvmMemoryMax]}G`);
clickSelectOption("type-selection", "Local");
expect(component.selectedComputingUnitType).toBe("local");
@@ -597,7 +597,7 @@ describe("ComputingUnitCreateModalComponent", () => {
expect(component.localComputingUnitUri).toBe("http://localhost:8085");
});
- it("falls back to a slider minimum of 2 when no JVM steps are configured", () => {
+ it("falls back to a slider minimum of 0 when no JVM steps are configured", () => {
mockComputingUnitService.getComputingUnitTypes.mockReturnValue(
of({ typeOptions: ["kubernetes"] as WorkflowComputingUnitType[] })
);
@@ -609,7 +609,7 @@ describe("ComputingUnitCreateModalComponent", () => {
const sliderEl = document.querySelector("nz-slider")!;
const slider = (getDebugNode(sliderEl) as DebugElement).componentInstance as { nzMin: number };
- expect(slider.nzMin).toBe(2);
+ expect(slider.nzMin).toBe(0);
});
it("wires the footer buttons to cancel and create", () => {
diff --git a/frontend/src/app/common/component/computing-unit-create-modal/computing-unit-create-modal.component.ts b/frontend/src/app/common/component/computing-unit-create-modal/computing-unit-create-modal.component.ts
index 5ae0ccbedd..5e34bfd470 100644
--- a/frontend/src/app/common/component/computing-unit-create-modal/computing-unit-create-modal.component.ts
+++ b/frontend/src/app/common/component/computing-unit-create-modal/computing-unit-create-modal.component.ts
@@ -38,7 +38,6 @@ import { DashboardWorkflowComputingUnit, WorkflowComputingUnitType } from "../..
import { extractErrorMessage } from "../../util/error";
import {
buildLocalComputingUnitUri,
- findNearestValidStep,
getJvmMemorySliderConfig,
isComputingUnitShmTooLarge,
parseResourceNumber,
@@ -111,6 +110,10 @@ export class ComputingUnitCreateModalComponent implements OnInit, OnChanges {
jvmMemorySteps: number[] = [1]; // Available steps in binary progression (1,2,4,8...)
showJvmMemorySlider: boolean = false; // Whether to show the slider
+ jvmMemoryTipFormatter = (index: number): string => {
+ return this.jvmMemorySteps && this.jvmMemorySteps[index] !== undefined ? `${this.jvmMemorySteps[index]}G` : "";
+ };
+
// cpu&memory limit options from backend
cpuOptions: string[] = [];
memoryOptions: string[] = [];
@@ -279,18 +282,24 @@ export class ComputingUnitCreateModalComponent implements OnInit, OnChanges {
this.resetJvmMemorySlider();
}
- onJvmMemorySliderChange(value: number): void {
+ onJvmMemorySliderChange(index: number): void {
// Ensure the value is one of the valid steps
- const validStep = findNearestValidStep(value, this.jvmMemorySteps);
- this.jvmMemorySliderValue = validStep;
- this.selectedJvmMemorySize = `${validStep}G`;
+ const validStep = this.jvmMemorySteps[index];
+ if (validStep !== undefined) {
+ this.jvmMemorySliderValue = index;
+ this.selectedJvmMemorySize = `${validStep}G`;
+ }
}
// Check if the maximum JVM memory value is selected
isMaxJvmMemorySelected(): boolean {
// Only show warning for larger memory sizes (>=4GB) where the slider is shown
// AND when the maximum value is selected
- return this.showJvmMemorySlider && this.jvmMemorySliderValue === this.jvmMemoryMax && this.jvmMemoryMax >= 4;
+ return (
+ this.showJvmMemorySlider &&
+ this.jvmMemorySliderValue === this.jvmMemoryMax &&
+ this.jvmMemorySteps[this.jvmMemoryMax] >= 4
+ );
}
// Completely reset the JVM memory slider based on the selected CU memory
@@ -308,7 +317,7 @@ export class ComputingUnitCreateModalComponent implements OnInit, OnChanges {
// Listen for memory selection changes
onMemorySelectionChange(): void {
// Store current JVM memory value for potential reuse
- const previousJvmMemory = this.jvmMemorySliderValue;
+ const previousJvmMemoryValue = this.jvmMemorySteps[this.jvmMemorySliderValue];
// Reset slider configuration based on the new memory selection
this.resetJvmMemorySlider();
@@ -320,14 +329,10 @@ export class ComputingUnitCreateModalComponent implements OnInit, OnChanges {
let cuMemoryInGb = memoryUnit === "Gi" ? memoryValue : memoryUnit === "Mi" ? Math.floor(memoryValue / 1024) : 1;
// Only try to preserve previous value for larger memory sizes where slider is shown
- if (
- cuMemoryInGb > 3 &&
- previousJvmMemory >= 2 &&
- previousJvmMemory <= this.jvmMemoryMax &&
- this.jvmMemorySteps.includes(previousJvmMemory)
- ) {
- this.jvmMemorySliderValue = previousJvmMemory;
- this.selectedJvmMemorySize = `${previousJvmMemory}G`;
+ if (cuMemoryInGb > 3 && previousJvmMemoryValue >= 2 && this.jvmMemorySteps.includes(previousJvmMemoryValue)) {
+ const index = this.jvmMemorySteps.indexOf(previousJvmMemoryValue);
+ this.jvmMemorySliderValue = index;
+ this.selectedJvmMemorySize = `${previousJvmMemoryValue}G`;
}
}
diff --git a/frontend/src/app/common/util/computing-unit.util.ts b/frontend/src/app/common/util/computing-unit.util.ts
index 65fe07b44c..aab9fec2a3 100644
--- a/frontend/src/app/common/util/computing-unit.util.ts
+++ b/frontend/src/app/common/util/computing-unit.util.ts
@@ -187,16 +187,6 @@ export function memoryPercentage(usage: string, limit: string): number {
return Math.min(percentage, 100);
}
-export function findNearestValidStep(value: number, jvmMemorySteps: number[]): number {
- if (jvmMemorySteps.length === 0) return 1;
- if (jvmMemorySteps.includes(value)) return value;
-
- // Find the closest step value
- return jvmMemorySteps.reduce((prev, curr) => {
- return Math.abs(curr - value) < Math.abs(prev - value) ? curr : prev;
- });
-}
-
export function validateName(trimmedName: string): string | null {
if (!trimmedName) return "Computing unit name cannot be empty";
if (trimmedName.length > 128) return "Computing unit name cannot exceed 128 characters";
@@ -285,8 +275,8 @@ function buildJvmMemorySteps(maxGb: number, start: number): number[] {
}
function buildJvmMemoryMarks(steps: number[]): Record<number, string> {
- return steps.reduce<Record<number, string>>((marks, step) => {
- marks[step] = `${step}G`;
+ return steps.reduce<Record<number, string>>((marks, step, index) => {
+ marks[index] = `${step}G`;
return marks;
}, {});
}
@@ -299,23 +289,24 @@ export function getJvmMemorySliderConfig(selectedMemory: string): JvmMemorySlide
const steps = buildJvmMemorySteps(cuMemoryInGb, 1);
return {
- jvmMemoryMax: cuMemoryInGb,
+ jvmMemoryMax: steps.length - 1,
showJvmMemorySlider: false,
jvmMemorySteps: steps,
jvmMemoryMarks: buildJvmMemoryMarks(steps),
- jvmMemorySliderValue: defaultValue,
+ jvmMemorySliderValue: steps.indexOf(defaultValue),
selectedJvmMemorySize: `${defaultValue}G`,
};
}
const steps = buildJvmMemorySteps(cuMemoryInGb, 2);
+ const defaultIndex = steps.indexOf(2);
return {
- jvmMemoryMax: cuMemoryInGb,
+ jvmMemoryMax: steps.length - 1,
showJvmMemorySlider: true,
jvmMemorySteps: steps,
jvmMemoryMarks: buildJvmMemoryMarks(steps),
- jvmMemorySliderValue: 2,
+ jvmMemorySliderValue: defaultIndex !== -1 ? defaultIndex : 0,
selectedJvmMemorySize: "2G",
};
}