diff --git a/src/app/layouts/tasks-executor/tasks-executor.css b/src/app/layouts/tasks-executor/tasks-executor.css index 3d0995e..301f544 100644 --- a/src/app/layouts/tasks-executor/tasks-executor.css +++ b/src/app/layouts/tasks-executor/tasks-executor.css @@ -40,8 +40,11 @@ */ .tasks-executor-tree-panel-floating { position: fixed; - top: 12px; + /* Anchored to the bottom: the top-left corner is where the run's own title and toolbar sit. */ + bottom: 12px; left: 12px; + /* Growing upward from the toggle keeps that toggle in the same place as the tree gets longer. */ + justify-content: flex-end; z-index: calc(var(--z-modal) + 1); width: 280px; max-height: calc(100vh - 24px); diff --git a/src/app/layouts/tasks-executor/tasks-executor.html b/src/app/layouts/tasks-executor/tasks-executor.html index f550c56..fdf071a 100644 --- a/src/app/layouts/tasks-executor/tasks-executor.html +++ b/src/app/layouts/tasks-executor/tasks-executor.html @@ -11,23 +11,21 @@ @if (selectedExecution(); as run) { + @if (executionTreeAvailable()) { +
- @if (executionTreeAvailable() && executionTreeOpen()) { + @if (executionTreeOpen()) { } + } diff --git a/src/app/layouts/tasks-executor/tasks-executor.spec.ts b/src/app/layouts/tasks-executor/tasks-executor.spec.ts index b92fa67..6f248a2 100644 --- a/src/app/layouts/tasks-executor/tasks-executor.spec.ts +++ b/src/app/layouts/tasks-executor/tasks-executor.spec.ts @@ -69,7 +69,8 @@ describe('TasksExecutor', () => { init: vi.fn(), retrieveExecution: vi.fn().mockReturnValue(of(null)), deleteExecution: vi.fn().mockReturnValue(of(null)), - rerunExecution: vi.fn().mockReturnValue(of(null)) + rerunExecution: vi.fn().mockReturnValue(of(null)), + retrieveExecutionEvents: vi.fn().mockReturnValue(of([])) } }, { @@ -81,13 +82,15 @@ describe('TasksExecutor', () => { { provide: BlocksService, useValue: { - getAllBlocksTypes: vi.fn().mockResolvedValue(signal([])) + getAllBlocksTypes: vi.fn().mockResolvedValue(signal([])), + hasLoadedBlockTypes: vi.fn().mockReturnValue(false) } }, { provide: ContainersService, useValue: { - getAllContainerTypes: vi.fn().mockResolvedValue(signal([])) + getAllContainerTypes: vi.fn().mockResolvedValue(signal([])), + peekContainerType: vi.fn().mockReturnValue(null) } }, { @@ -182,8 +185,10 @@ describe('TasksExecutor', () => { } } } as any]); + fixture.detectChanges(); expect(component.executionTreeAvailable()).toBe(true); expect(component.treeFloating()).toBe(false); + expect(fixture.nativeElement.querySelector('.tasks-executor-tree-panel')).not.toBeNull(); component.viewerFullscreen.set(true); expect(component.treeFloating()).toBe(true); @@ -206,9 +211,12 @@ describe('TasksExecutor', () => { } } as any]); component.viewerFullscreen.set(true); + fixture.detectChanges(); expect(component.executionTreeAvailable()).toBe(false); expect(component.treeFloating()).toBe(false); + // Not merely un-floated: a run with no subflow has no tree to offer, so the panel is absent. + expect(fixture.nativeElement.querySelector('.tasks-executor-tree-panel')).toBeNull(); }); it('follows only container steps waiting for a child subflow', () => {