ui: make node settings collapsible
This commit is contained in:
parent
d3f8ea3006
commit
44a4ff09a9
|
|
@ -219,7 +219,8 @@
|
|||
}
|
||||
|
||||
.container-node__delete,
|
||||
.container-node__focus {
|
||||
.container-node__focus,
|
||||
.container-node__settings {
|
||||
border: 0;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
|
|
@ -228,6 +229,11 @@
|
|||
color: #f8fafc;
|
||||
}
|
||||
|
||||
.container-node__settings--active {
|
||||
background: rgba(255, 255, 255, 0.34);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.container-node__clone {
|
||||
border: 0;
|
||||
width: 30px;
|
||||
|
|
|
|||
|
|
@ -72,6 +72,18 @@
|
|||
</div>
|
||||
}
|
||||
@if (!isReadonly) {
|
||||
@if (!focusOpen && (hasParameterFields() || hasMainContent())) {
|
||||
<button
|
||||
type="button"
|
||||
class="container-node__settings"
|
||||
[class.container-node__settings--active]="nodeSettingsOpen"
|
||||
[attr.aria-expanded]="nodeSettingsOpen"
|
||||
[matTooltip]="nodeSettingsOpen ? 'Hide settings' : 'Show settings'"
|
||||
(pointerdown)="$event.stopPropagation()"
|
||||
(click)="toggleNodeSettings($event)">
|
||||
<i class="bi bi-gear"></i>
|
||||
</button>
|
||||
}
|
||||
<button type="button" class="container-node__focus" [matTooltip]="focusOpen ? 'Close expanded node' : 'Expand node'" (pointerdown)="$event.stopPropagation()" (click)="toggleFocus($event)">
|
||||
<i class="bi" [class.bi-arrows-angle-expand]="!focusOpen" [class.bi-x-lg]="focusOpen"></i>
|
||||
</button>
|
||||
|
|
@ -219,7 +231,7 @@
|
|||
</div>
|
||||
}
|
||||
|
||||
@if (hasParameterFields() || hasMainContent()) {
|
||||
@if ((hasParameterFields() || hasMainContent()) && (nodeSettingsOpen || focusOpen)) {
|
||||
<div class="container-node__params container-node__params-shell">
|
||||
@if (!schemaReady) {
|
||||
<div class="container-node__skeleton-overlay" aria-hidden="true">
|
||||
|
|
|
|||
|
|
@ -137,6 +137,8 @@ export class ContainerNodeComponent implements OnDestroy {
|
|||
optionalGroupFieldDefinitions: SchemaOptionalGroupFieldDefinition[] = [];
|
||||
parameterDisplaySections: ContainerDisplaySection[] = [];
|
||||
schemaReady = false;
|
||||
/** Settings stay out of the way on the canvas until the gear button opens them. */
|
||||
nodeSettingsOpen = false;
|
||||
focusOpen = false;
|
||||
private schemaLoading = false;
|
||||
nameEditorOpen = false;
|
||||
|
|
@ -219,6 +221,13 @@ export class ContainerNodeComponent implements OnDestroy {
|
|||
return this.data?.data?.['__readonly'] === true;
|
||||
}
|
||||
|
||||
toggleNodeSettings(event?: Event) {
|
||||
event?.preventDefault();
|
||||
event?.stopPropagation();
|
||||
this.nodeSettingsOpen = !this.nodeSettingsOpen;
|
||||
this.cdr.markForCheck();
|
||||
}
|
||||
|
||||
toggleFocus(event?: Event) {
|
||||
event?.preventDefault();
|
||||
event?.stopPropagation();
|
||||
|
|
|
|||
|
|
@ -443,6 +443,11 @@
|
|||
color: #1d4ed8;
|
||||
}
|
||||
|
||||
.llm-clone-btn--active {
|
||||
background: #dbeafe;
|
||||
color: #1d4ed8;
|
||||
}
|
||||
|
||||
.llm-node--human .llm-clone-btn:hover {
|
||||
background: #fff7ed;
|
||||
color: #c2410c;
|
||||
|
|
|
|||
|
|
@ -108,6 +108,18 @@
|
|||
</div>
|
||||
}
|
||||
@if (!isReadonly) {
|
||||
@if (!focusOpen && hasOrderedParameterItems()) {
|
||||
<button
|
||||
type="button"
|
||||
class="llm-clone-btn"
|
||||
[class.llm-clone-btn--active]="nodeSettingsOpen"
|
||||
[attr.aria-expanded]="nodeSettingsOpen"
|
||||
[matTooltip]="nodeSettingsOpen ? 'Hide settings' : 'Show settings'"
|
||||
(pointerdown)="$event.stopPropagation()"
|
||||
(click)="toggleNodeSettings($event)">
|
||||
<i class="bi bi-gear"></i>
|
||||
</button>
|
||||
}
|
||||
<button
|
||||
type="button"
|
||||
class="llm-clone-btn"
|
||||
|
|
@ -291,7 +303,7 @@
|
|||
</div>
|
||||
}
|
||||
|
||||
<app-node-parameters [host]="this" />
|
||||
<app-node-parameters [host]="this" [showParameters]="nodeSettingsOpen || focusOpen" />
|
||||
|
||||
@if (biasAnnotationsAllowed) {
|
||||
<app-bias-annotations
|
||||
|
|
|
|||
|
|
@ -99,6 +99,16 @@ describe('GenericNodeComponent', () => {
|
|||
await fixture.whenStable();
|
||||
});
|
||||
|
||||
it('keeps the name editor available while settings are collapsed', () => {
|
||||
expect(component.nodeSettingsOpen).toBe(false);
|
||||
|
||||
component.openNameEditor();
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(component.localEditorOpen).toBe(true);
|
||||
expect(fixture.nativeElement.querySelector('.llm-modal-backdrop')).not.toBeNull();
|
||||
});
|
||||
|
||||
describe('clearing an optional number', () => {
|
||||
/** Opens the modal editor on a numeric path, as clicking the pen does. */
|
||||
function openNumericEditor(path: string, current: unknown) {
|
||||
|
|
@ -518,6 +528,7 @@ describe('GenericNodeComponent', () => {
|
|||
item: { path: 'skills', field: null, richContentField: null, arrayField, optionalGroupField: null }
|
||||
}
|
||||
];
|
||||
component.nodeSettingsOpen = true;
|
||||
component.cdr.detectChanges();
|
||||
// A list starts closed, showing only its count; opened, its rows offer the button.
|
||||
for (const toggle of fixture.nativeElement.querySelectorAll('.llm-array-toggle')) {
|
||||
|
|
|
|||
|
|
@ -235,6 +235,8 @@ export class GenericNodeComponent implements OnDestroy {
|
|||
localEditorFreeText = false;
|
||||
localEditorBindableInputName: string | null = null;
|
||||
deleteConfirmOpen = false;
|
||||
/** Keeps the canvas compact until the person explicitly needs to inspect or edit the fields. */
|
||||
nodeSettingsOpen = false;
|
||||
focusOpen = false;
|
||||
schemaReady = false;
|
||||
private schemaLoading = false;
|
||||
|
|
@ -368,6 +370,13 @@ export class GenericNodeComponent implements OnDestroy {
|
|||
return this.blockId ?? 'unknown-id';
|
||||
}
|
||||
|
||||
toggleNodeSettings(event?: Event) {
|
||||
event?.preventDefault();
|
||||
event?.stopPropagation();
|
||||
this.nodeSettingsOpen = !this.nodeSettingsOpen;
|
||||
this.cdr.markForCheck();
|
||||
}
|
||||
|
||||
toggleFocus(event?: Event) {
|
||||
event?.preventDefault();
|
||||
event?.stopPropagation();
|
||||
|
|
@ -431,6 +440,7 @@ export class GenericNodeComponent implements OnDestroy {
|
|||
this.localEditorGlobalInputs = [];
|
||||
this.localEditorFreeText = false;
|
||||
this.localEditorBindableInputName = null;
|
||||
this.cdr.markForCheck();
|
||||
}
|
||||
|
||||
async openParameterEditor(path: string, event?: Event) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
Attribution term under AGPL-3.0 section 7(b): see LICENSE-ADDENDUM.
|
||||
-->
|
||||
|
||||
@if (showParameters) {
|
||||
<div class="llm-params llm-params-shell">
|
||||
@if (!host.schemaReady) {
|
||||
<div class="llm-skeleton-overlay" aria-hidden="true">
|
||||
|
|
@ -245,6 +246,7 @@
|
|||
}
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
@if (host.localEditorOpen) {
|
||||
<dialog #simpleEditorDialog class="llm-modal-backdrop" (pointerdown)="$event.stopPropagation()" (click)="onSimpleEditorDialogClick($event)" (cancel)="host.closeSimpleParamEditor($event)">
|
||||
|
|
|
|||
|
|
@ -79,6 +79,8 @@ export type NodeParametersHost = {
|
|||
})
|
||||
export class NodeParametersComponent {
|
||||
@Input({ required: true }) host!: NodeParametersHost;
|
||||
/** The editor dialog must stay mounted even while the card's fields are collapsed. */
|
||||
@Input() showParameters = true;
|
||||
|
||||
/**
|
||||
* This renders inside a node card, which rete.js positions with a CSS `transform` for pan and
|
||||
|
|
|
|||
|
|
@ -225,10 +225,13 @@
|
|||
}
|
||||
|
||||
.resource-card__settings {
|
||||
margin-top: 10px;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.resource-card__settings--open {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.resource-card__confirm {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
|
|
|||
|
|
@ -90,11 +90,10 @@
|
|||
</div>
|
||||
}
|
||||
}
|
||||
} @else {
|
||||
<div class="resource-card__settings" (pointerdown)="$event.stopPropagation()">
|
||||
<app-node-parameters [host]="this" />
|
||||
</div>
|
||||
}
|
||||
<div class="resource-card__settings" [class.resource-card__settings--open]="settingsOpen() || focusOpen" (pointerdown)="$event.stopPropagation()">
|
||||
<app-node-parameters [host]="this" [showParameters]="settingsOpen() || focusOpen" />
|
||||
</div>
|
||||
|
||||
@if (resourceLinkOutput; as resourceLinkOutput) {
|
||||
<div class="resource-card__link" title="Drag to a storage operation to link it here">
|
||||
|
|
|
|||
Loading…
Reference in New Issue