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 00:36:37 UTC
(texera) branch main updated: feat(frontend): advanced settings for computing-unit creation (#6104)
This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/texera.git
The following commit(s) were added to refs/heads/main by this push:
new 6fc1fb76eb feat(frontend): advanced settings for computing-unit creation (#6104)
6fc1fb76eb is described below
commit 6fc1fb76eb542fffcaed48823ed53bff91555901
Author: Kunwoo (Chris) <14...@users.noreply.github.com>
AuthorDate: Wed Jul 8 20:24:51 2026 -0400
feat(frontend): advanced settings for computing-unit creation (#6104)
### What changes were proposed in this PR?
This PR improves the UI of creating a computing unit (CU) with an
"Advanced Settings" section to get a simplified default view.
The shared memory size and JVM memory size are too technical for most
users, so the create-CU modal now shows only the common fields (name /
RAM / CPU) by default and tucks those two options behind a collapsed
"Advanced Settings" panel:
- Collapsed by default, and collapses again every time the modal opens.
- If shared memory is set larger than total memory while the panel is
collapsed, a warning appears on the panel header so the invalid value is
not hidden.
- Implemented once in the shared `ComputingUnitCreateModalComponent`
(#6082), so both entry points (the dashboard Computing Units page and
the workspace power button) get the same behavior.
The feature was originally implemented on the downstream dknet-ai.org
deployment
([Texera/dknet-ai-public@30318e2d](https://github.com/Texera/dknet-ai-public/commit/30318e2da47aff5620997febdf2f92e54c92aad1)).
### Any related issues, documentation, discussions?
Closes #6102
### How was this PR tested?
https://github.com/user-attachments/assets/b7a5e4d3-b655-45bc-bf5c-f6ef1674af9c
### Was this PR authored or co-authored using generative AI tooling?
Generated-by: Claude Code
---------
Signed-off-by: Kunwoo (Chris) <14...@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <17...@users.noreply.github.com>
---
.../computing-unit-create-modal.component.html | 148 +++++++++++++--------
.../computing-unit-create-modal.component.scss | 141 +++++++++++++++++++-
.../computing-unit-create-modal.component.spec.ts | 135 ++++++++++++++++++-
.../computing-unit-create-modal.component.ts | 58 +++++++-
4 files changed, 417 insertions(+), 65 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 df5f725c9c..462f506dbd 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
@@ -93,65 +93,103 @@
</nz-select>
</div>
- <div class="select-unit shared-memory-group">
- <span>
- Adjust the Shared Memory Size
+ <!-- Advanced settings: progressive disclosure for the power-user knobs -->
+ <div class="advanced-settings">
+ <button
+ type="button"
+ class="advanced-settings-toggle"
+ [class.expanded]="showAdvancedSettings"
+ [attr.aria-expanded]="showAdvancedSettings"
+ (click)="toggleAdvancedSettings()">
<i
nz-icon
- nzType="info-circle"
- nz-tooltip
- [nzTooltipTitle]="
- 'Shared memory (/dev/shm) is used for inter-process communication. If you plan to run ML tasks (e.g., using PyTorch), consider increasing this size. Learn more: https://man7.org/linux/man-pages/man7/shm_overview.7.html'
- ">
- </i>
- </span>
- <div class="shm-input-row">
- <input
- nz-input
- type="number"
- min="0"
- [(ngModel)]="shmSizeValue"
- class="shm-size-input"
- placeholder="e.g. 512" />
- <nz-select
- class="shm-unit-select"
- [(ngModel)]="shmSizeUnit">
- <nz-option
- nzValue="Mi"
- nzLabel="Mi"></nz-option>
- <nz-option
- nzValue="Gi"
- nzLabel="Gi"></nz-option>
- </nz-select>
- </div>
- <div
- *ngIf="isShmTooLarge()"
- class="shm-warning">
- Shared memory cannot be greater than total memory.
- </div>
- </div>
+ nzType="right"
+ nzTheme="outline"
+ class="advanced-settings-chevron"></i>
+ <span class="advanced-settings-label">Advanced Settings</span>
+ <span
+ class="advanced-settings-hint"
+ [class.advanced-settings-hint--warning]="hasCollapsedWarning()">
+ <ng-container *ngIf="hasCollapsedWarning(); else advancedSettingsHint">
+ <i
+ nz-icon
+ nzType="exclamation-circle"
+ nzTheme="outline"></i>
+ {{ collapsedWarningText() }}
+ </ng-container>
+ <ng-template #advancedSettingsHint>Shared memory · JVM heap size</ng-template>
+ </span>
+ </button>
- <div class="select-unit name-field">
- <span>JVM Memory Size: {{selectedJvmMemorySize}}</span>
- <nz-slider
- *ngIf="showJvmMemorySlider"
- class="jvm-memory-slider"
- [nzMarks]="jvmMemoryMarks"
- [nzMin]="jvmMemorySteps[0] || 2"
- [nzMax]="jvmMemoryMax"
- [nzStep]="null"
- [nzIncluded]="false"
- [ngModel]="jvmMemorySliderValue"
- (ngModelChange)="onJvmMemorySliderChange($event)">
- </nz-slider>
<div
- *ngIf="isMaxJvmMemorySelected()"
- class="memory-warning">
- <nz-alert
- nzType="warning"
- nzMessage="Using maximum JVM memory may affect the performance of Python-based operators."
- nzShowIcon>
- </nz-alert>
+ class="advanced-settings-body"
+ [class.expanded]="showAdvancedSettings"
+ [attr.inert]="showAdvancedSettings ? null : ''">
+ <div class="advanced-settings-clip">
+ <div class="advanced-settings-inner">
+ <div class="select-unit shared-memory-group">
+ <span>
+ Adjust the Shared Memory Size
+ <i
+ nz-icon
+ nzType="info-circle"
+ nz-tooltip
+ [nzTooltipTitle]="
+ 'Shared memory (/dev/shm) is used for inter-process communication. If you plan to run ML tasks (e.g., using PyTorch), consider increasing this size. Learn more: https://man7.org/linux/man-pages/man7/shm_overview.7.html'
+ ">
+ </i>
+ </span>
+ <div class="shm-input-row">
+ <input
+ nz-input
+ type="number"
+ min="0"
+ [(ngModel)]="shmSizeValue"
+ class="shm-size-input"
+ placeholder="e.g. 512" />
+ <nz-select
+ class="shm-unit-select"
+ [(ngModel)]="shmSizeUnit">
+ <nz-option
+ nzValue="Mi"
+ nzLabel="Mi"></nz-option>
+ <nz-option
+ nzValue="Gi"
+ nzLabel="Gi"></nz-option>
+ </nz-select>
+ </div>
+ <div
+ *ngIf="isShmTooLarge()"
+ class="shm-warning">
+ Shared memory cannot be greater than total memory.
+ </div>
+ </div>
+
+ <div class="select-unit jvm-memory-group">
+ <span>JVM Memory Size: {{selectedJvmMemorySize}}</span>
+ <nz-slider
+ *ngIf="showJvmMemorySlider"
+ class="jvm-memory-slider"
+ [nzMarks]="jvmMemoryMarks"
+ [nzMin]="jvmMemorySteps[0] || 2"
+ [nzMax]="jvmMemoryMax"
+ [nzStep]="null"
+ [nzIncluded]="false"
+ [ngModel]="jvmMemorySliderValue"
+ (ngModelChange)="onJvmMemorySliderChange($event)">
+ </nz-slider>
+ <div
+ *ngIf="isMaxJvmMemorySelected()"
+ class="memory-warning">
+ <nz-alert
+ nzType="warning"
+ nzMessage="Using maximum JVM memory may affect the performance of Python-based operators."
+ nzShowIcon>
+ </nz-alert>
+ </div>
+ </div>
+ </div>
+ </div>
</div>
</div>
</ng-container>
diff --git a/frontend/src/app/common/component/computing-unit-create-modal/computing-unit-create-modal.component.scss b/frontend/src/app/common/component/computing-unit-create-modal/computing-unit-create-modal.component.scss
index ba2b25415b..d519455a90 100644
--- a/frontend/src/app/common/component/computing-unit-create-modal/computing-unit-create-modal.component.scss
+++ b/frontend/src/app/common/component/computing-unit-create-modal/computing-unit-create-modal.component.scss
@@ -23,11 +23,6 @@
width: 100%;
}
-.jvm-memory-slider {
- width: 100%;
- margin: 10px 0;
-}
-
.memory-warning {
margin-top: 10px;
font-size: 0.9em;
@@ -86,3 +81,139 @@
white-space: nowrap;
}
}
+
+// ── Advanced Settings progressive-disclosure panel ──────────────────────────
+// Collapsed by default; houses the shared-memory and JVM-heap knobs so the
+// common path (name / RAM / CPU) stays uncluttered.
+
+// The inner panel's padding, also reused for the slider's bottom margin.
+$advanced-panel-padding: 16px;
+
+.advanced-settings {
+ grid-column: span 2;
+ margin-top: 2px;
+ border-top: 1px solid #f0f0f0;
+ padding-top: 10px;
+}
+
+.advanced-settings-toggle {
+ display: flex;
+ align-items: center;
+ gap: 8px;
+ width: 100%;
+ padding: 7px 10px;
+ margin: 0;
+ background: transparent;
+ border: none;
+ border-radius: 6px;
+ color: #595959;
+ font-family: inherit;
+ cursor: pointer;
+ transition:
+ background-color 0.2s ease,
+ color 0.2s ease;
+
+ &:hover {
+ background-color: #f0f6ff;
+ color: #1890ff;
+ }
+
+ &:focus-visible {
+ outline: 2px solid rgba(24, 144, 255, 0.35);
+ outline-offset: 1px;
+ }
+}
+
+.advanced-settings-chevron {
+ font-size: 11px;
+ color: inherit;
+ transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1);
+
+ .advanced-settings-toggle.expanded & {
+ transform: rotate(90deg);
+ }
+}
+
+.advanced-settings-label {
+ font-size: 13px;
+ font-weight: 600;
+ letter-spacing: 0.01em;
+ color: inherit;
+}
+
+.advanced-settings-hint {
+ display: inline-flex;
+ align-items: center;
+ margin-left: auto;
+ font-size: 12px;
+ font-weight: 400;
+ color: #bfbfbf;
+ white-space: nowrap;
+ transition: color 0.2s ease;
+
+ .advanced-settings-toggle.expanded &,
+ .advanced-settings-toggle:hover & {
+ color: #69b1ff;
+ }
+}
+
+// Warning variant: promotes a hidden shared-memory error onto the collapsed
+// header. Stays amber even on hover, overriding the blue affordance above.
+.advanced-settings-hint--warning,
+.advanced-settings-toggle:hover .advanced-settings-hint--warning {
+ color: #faad14;
+ font-weight: 500;
+
+ i {
+ margin-right: 4px;
+ }
+}
+
+// Height animates via the 0fr→1fr grid-row trick so it eases open to the
+// content's natural height without a hard-coded max-height.
+.advanced-settings-body {
+ display: grid;
+ grid-template-rows: 0fr;
+ transition: grid-template-rows 0.28s cubic-bezier(0.4, 0, 0.2, 1);
+
+ &.expanded {
+ grid-template-rows: 1fr;
+ }
+}
+
+.advanced-settings-clip {
+ overflow: hidden;
+ min-height: 0;
+}
+
+.advanced-settings-inner {
+ display: flex;
+ flex-direction: column;
+ gap: 18px;
+ margin-top: 10px;
+ padding: $advanced-panel-padding;
+ border: 1px solid #eef0f2;
+ border-left: 2px solid #1890ff;
+ border-radius: 8px;
+ background: #fafbfc;
+ // Content drifts up + fades in slightly behind the height ease for depth.
+ opacity: 0;
+ transform: translateY(-4px);
+ transition:
+ opacity 0.26s ease 0.04s,
+ transform 0.26s ease 0.04s;
+
+ .advanced-settings-body.expanded & {
+ opacity: 1;
+ transform: translateY(0);
+ }
+
+ .jvm-memory-slider {
+ // align-self: stretch makes the horizontal margin the single source of
+ // truth for the inset. The bottom margin mirrors the panel padding so the
+ // slider's end labels (e.g. 2G / 16G) keep the same breathing room as
+ // every other edge of the box.
+ align-self: stretch;
+ margin: 6px 10px $advanced-panel-padding;
+ }
+}
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 027c62ee7a..1b0782ca9a 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
@@ -17,7 +17,7 @@
* under the License.
*/
-import { ApplicationRef, DebugElement, getDebugNode } from "@angular/core";
+import { ApplicationRef, DebugElement, getDebugNode, SimpleChange } from "@angular/core";
import { NgModel } from "@angular/forms";
import { CdkVirtualScrollViewport } from "@angular/cdk/scrolling";
import { ComponentFixture, TestBed } from "@angular/core/testing";
@@ -220,6 +220,94 @@ describe("ComputingUnitCreateModalComponent", () => {
expect(component.isShmTooLarge()).toBe(false);
});
+ it("toggles the advanced-settings panel", () => {
+ component.showAdvancedSettings = false;
+ component.toggleAdvancedSettings();
+ expect(component.showAdvancedSettings).toBe(true);
+ component.toggleAdvancedSettings();
+ expect(component.showAdvancedSettings).toBe(false);
+ });
+
+ it("re-collapses the advanced-settings panel each time the modal opens", () => {
+ component.showAdvancedSettings = true;
+ component.ngOnChanges({ visible: new SimpleChange(false, true, false) });
+ expect(component.showAdvancedSettings).toBe(false);
+
+ // Closing the modal must not touch the panel state.
+ component.showAdvancedSettings = true;
+ component.ngOnChanges({ visible: new SimpleChange(true, false, false) });
+ expect(component.showAdvancedSettings).toBe(true);
+ });
+
+ it("resets the advanced values each time the modal opens", () => {
+ fixture.detectChanges();
+ component.selectedMemory = "8Gi";
+ component.onMemorySelectionChange();
+ component.shmSizeValue = 4;
+ component.shmSizeUnit = "Gi";
+ component.onJvmMemorySliderChange(component.jvmMemoryMax);
+
+ component.ngOnChanges({ visible: new SimpleChange(false, true, false) });
+
+ const expected = getJvmMemorySliderConfig("8Gi");
+ expect(component.shmSizeValue).toBe(64);
+ expect(component.shmSizeUnit).toBe("Mi");
+ expect(component.jvmMemorySliderValue).toBe(expected.jvmMemorySliderValue);
+ expect(component.selectedJvmMemorySize).toBe(expected.selectedJvmMemorySize);
+
+ // Closing the modal must not touch the values.
+ component.shmSizeValue = 2;
+ component.shmSizeUnit = "Gi";
+ component.ngOnChanges({ visible: new SimpleChange(true, false, false) });
+ expect(component.shmSizeValue).toBe(2);
+ expect(component.shmSizeUnit).toBe("Gi");
+ });
+
+ it("surfaces the max-JVM warning on the collapsed header", () => {
+ vi.spyOn(component, "isShmTooLarge").mockReturnValue(false);
+ vi.spyOn(component, "isMaxJvmMemorySelected").mockReturnValue(true);
+
+ component.showAdvancedSettings = false;
+ expect(component.hasCollapsedWarning()).toBe(true);
+ expect(component.collapsedWarningText()).toBe("JVM memory at maximum");
+
+ // Expanded: the inline nz-alert is visible, so the header stays quiet.
+ component.showAdvancedSettings = true;
+ expect(component.hasCollapsedWarning()).toBe(false);
+ });
+
+ it("prefers the shm warning over the JVM warning when both apply", () => {
+ vi.spyOn(component, "isShmTooLarge").mockReturnValue(true);
+ vi.spyOn(component, "isMaxJvmMemorySelected").mockReturnValue(true);
+
+ component.selectedMemory = "4Gi";
+ component.showAdvancedSettings = false;
+ expect(component.collapsedWarningText()).toBe("Shared memory exceeds total");
+ });
+
+ it("flags a collapsed warning only when collapsed and shm exceeds memory", () => {
+ vi.spyOn(component, "isShmTooLarge").mockReturnValue(true);
+ component.selectedMemory = "4Gi";
+ component.showAdvancedSettings = false;
+ expect(component.hasCollapsedWarning()).toBe(true);
+ // Expanded: the inline warning is visible, so the header stays quiet.
+ component.showAdvancedSettings = true;
+ expect(component.hasCollapsedWarning()).toBe(false);
+ });
+
+ it("suppresses the shm warning until the memory options have loaded", () => {
+ vi.spyOn(component, "isShmTooLarge").mockReturnValue(true);
+ component.selectedMemory = "";
+ component.showAdvancedSettings = false;
+ expect(component.hasCollapsedWarning()).toBe(false);
+ });
+
+ it("does not flag a warning when shm fits within memory", () => {
+ vi.spyOn(component, "isShmTooLarge").mockReturnValue(false);
+ component.showAdvancedSettings = false;
+ expect(component.hasCollapsedWarning()).toBe(false);
+ });
+
it("initializes the local computing unit URI from the window location", () => {
fixture.detectChanges();
expect(component.localComputingUnitUri).toBe(buildLocalComputingUnitUri(window.location));
@@ -346,6 +434,17 @@ describe("ComputingUnitCreateModalComponent", () => {
expect(document.querySelector(".create-compute-unit-container")).toBeTruthy();
expect(document.querySelector(".unit-name-input")).toBeTruthy();
expect(document.querySelector(".gpu-selection")).toBeTruthy();
+
+ // Collapsed: the invalid shm value is announced on the panel header.
+ expect(document.querySelector(".advanced-settings-hint--warning")?.textContent).toContain(
+ "Shared memory exceeds total"
+ );
+
+ // Expand the panel so the advanced controls are actually user-visible
+ // before asserting on them.
+ (document.querySelector(".advanced-settings-toggle") as HTMLButtonElement).click();
+ fixture.detectChanges();
+
expect(document.querySelector(".shm-warning")?.textContent).toContain(
"Shared memory cannot be greater than total memory."
);
@@ -354,6 +453,35 @@ describe("ComputingUnitCreateModalComponent", () => {
expect(document.querySelector(".unit-uri-input")).toBeNull();
});
+ it("expands and collapses the advanced panel when the toggle button is clicked", () => {
+ mockComputingUnitService.getComputingUnitTypes.mockReturnValue(
+ of({ typeOptions: ["kubernetes"] as WorkflowComputingUnitType[] })
+ );
+ mockComputingUnitService.getComputingUnitLimitOptions.mockReturnValue(
+ of({ cpuLimitOptions: ["1"], memoryLimitOptions: ["1Gi"], gpuLimitOptions: ["0"] })
+ );
+ fixture.detectChanges();
+ component.visible = true;
+ fixture.detectChanges();
+
+ const toggle = document.querySelector(".advanced-settings-toggle") as HTMLButtonElement;
+ const body = document.querySelector(".advanced-settings-body") as HTMLElement;
+ expect(toggle.getAttribute("aria-expanded")).toBe("false");
+ expect(body.classList.contains("expanded")).toBe(false);
+
+ toggle.click();
+ fixture.detectChanges();
+ expect(component.showAdvancedSettings).toBe(true);
+ expect(toggle.getAttribute("aria-expanded")).toBe("true");
+ expect(body.classList.contains("expanded")).toBe(true);
+
+ toggle.click();
+ fixture.detectChanges();
+ expect(component.showAdvancedSettings).toBe(false);
+ expect(toggle.getAttribute("aria-expanded")).toBe("false");
+ expect(body.classList.contains("expanded")).toBe(false);
+ });
+
it("renders the minimal kubernetes form without GPU select, warnings, or slider", () => {
mockComputingUnitService.getComputingUnitTypes.mockReturnValue(
of({ typeOptions: ["kubernetes"] as WorkflowComputingUnitType[] })
@@ -429,6 +557,11 @@ describe("ComputingUnitCreateModalComponent", () => {
setInputValue(".unit-name-input", "Typed Name");
expect(component.newComputingUnitName).toBe("Typed Name");
+ // Expand the advanced panel first: the shm input and JVM slider sit in
+ // the collapsed (inert) body, which a real user cannot interact with.
+ (document.querySelector(".advanced-settings-toggle") as HTMLButtonElement).click();
+ tick();
+
setInputValue(".shm-size-input", "128");
expect(component.shmSizeValue).toBe(128);
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 930bde396b..5ae0ccbedd 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
@@ -17,7 +17,7 @@
* under the License.
*/
-import { Component, EventEmitter, Input, OnInit, Output } from "@angular/core";
+import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from "@angular/core";
import { NgFor, NgIf, TitleCasePipe } from "@angular/common";
import { FormsModule } from "@angular/forms";
import { UntilDestroy, untilDestroyed } from "@ngneat/until-destroy";
@@ -46,6 +46,10 @@ import {
unitTypeMessageTemplate,
} from "../../util/computing-unit.util";
+// Defaults for the advanced-settings values, restored every time the modal opens.
+const DEFAULT_SHM_SIZE_VALUE = 64;
+const DEFAULT_SHM_SIZE_UNIT: "Mi" | "Gi" = "Mi";
+
/**
* The "create computing unit" modal shared by the workspace power button and
* the dashboard Computing Units page. Owns the whole form (type, name,
@@ -79,11 +83,15 @@ import {
TitleCasePipe,
],
})
-export class ComputingUnitCreateModalComponent implements OnInit {
+export class ComputingUnitCreateModalComponent implements OnInit, OnChanges {
@Input() visible = false;
@Output() visibleChange = new EventEmitter<boolean>();
@Output() unitCreated = new EventEmitter<DashboardWorkflowComputingUnit>();
+ // Advanced settings disclosure — collapsed by default, houses the
+ // shared-memory and JVM-heap knobs most users never touch.
+ showAdvancedSettings = false;
+
newComputingUnitName: string = "";
selectedMemory: string = "";
selectedCpu: string = "";
@@ -91,8 +99,8 @@ export class ComputingUnitCreateModalComponent implements OnInit {
selectedJvmMemorySize: string = "1G"; // Initial JVM memory size
selectedComputingUnitType?: WorkflowComputingUnitType; // Selected computing unit type
selectedShmSize: string = "64Mi"; // Shared memory size
- shmSizeValue: number = 64; // default to 64
- shmSizeUnit: "Mi" | "Gi" = "Mi"; // default unit
+ shmSizeValue: number = DEFAULT_SHM_SIZE_VALUE;
+ shmSizeUnit: "Mi" | "Gi" = DEFAULT_SHM_SIZE_UNIT;
availableComputingUnitTypes: WorkflowComputingUnitType[] = [];
localComputingUnitUri: string = ""; // URI for local computing unit
@@ -157,6 +165,48 @@ export class ComputingUnitCreateModalComponent implements OnInit {
});
}
+ ngOnChanges(changes: SimpleChanges): void {
+ if (changes["visible"]?.currentValue === true) {
+ this.resetAdvancedSettings();
+ }
+ }
+
+ // Runs every time the modal opens: re-collapse the advanced panel so it
+ // always starts on the simple path (name / RAM / CPU), and restore the
+ // advanced values so a setting from a previous open can't ride along
+ // hidden behind the collapsed panel.
+ private resetAdvancedSettings(): void {
+ this.showAdvancedSettings = false;
+ this.shmSizeValue = DEFAULT_SHM_SIZE_VALUE;
+ this.shmSizeUnit = DEFAULT_SHM_SIZE_UNIT;
+ this.resetJvmMemorySlider();
+ }
+
+ toggleAdvancedSettings(): void {
+ this.showAdvancedSettings = !this.showAdvancedSettings;
+ }
+
+ // Surfaces panel warnings on the collapsed header so an invalid or risky
+ // value tucked inside the panel can't be submitted unseen. The invalid shm
+ // value outranks the advisory max-JVM note when both apply. The shm check
+ // is skipped until the memory options have loaded (selectedMemory is empty).
+ collapsedWarningText(): string | null {
+ if (this.showAdvancedSettings) {
+ return null;
+ }
+ if (this.selectedMemory !== "" && this.isShmTooLarge()) {
+ return "Shared memory exceeds total";
+ }
+ if (this.isMaxJvmMemorySelected()) {
+ return "JVM memory at maximum";
+ }
+ return null;
+ }
+
+ hasCollapsedWarning(): boolean {
+ return this.collapsedWarningText() !== null;
+ }
+
// Determines if the GPU selection dropdown should be shown
showGpuSelection(): boolean {
// Don't show GPU selection if there are no options or only "0" option