Skip to content
This repository has been archived by the owner on Apr 4, 2023. It is now read-only.

Commit

Permalink
Display an animated icon for a terminal tab while a task is running
Browse files Browse the repository at this point in the history
Signed-off-by: Roman Nikitenko <rnikiten@redhat.com>
  • Loading branch information
RomanNikitenko committed May 14, 2020
1 parent 997bebb commit 6d93698
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/

import { TaskTerminalWidgetManager, TaskTerminalWidgetOpenerOptions } from '@theia/task/lib/browser/task-terminal-widget-manager';
import { TaskTerminalWidgetManager, TaskTerminalWidgetOpenerOptions, TaskTerminalWidget } from '@theia/task/lib/browser/task-terminal-widget-manager';
import { TerminalWidget, TerminalWidgetOptions } from '@theia/terminal/lib/browser/base/terminal-widget';
import { TerminalWidgetFactoryOptions } from '@theia/terminal/lib/browser/terminal-widget-impl';
import { injectable } from 'inversify';
Expand Down Expand Up @@ -67,4 +67,12 @@ export class CheTaskTerminalWidgetManager extends TaskTerminalWidgetManager {

return super.open(factoryOptions, openerOptions);
}

getTaskTerminals(): TerminalWidget[] {
return this.terminalService.all.filter(terminal => this.isTaskTerminal(terminal));
}

isTaskTerminal(terminal: TerminalWidget): boolean {
return TaskTerminalWidget.is(terminal) || RemoteTaskTerminalWidget.is(terminal);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

.task-status-success:before {
color: #89d185;
}

.task-status-error:before {
color: var(--theia-notificationsErrorIcon-foreground);
}
.p-TabBar.theia-app-centers .p-TabBar-tabIcon.task-status-in-progress {
background-size: 12px;
background-image: var(--theia-preloader);
background-repeat: no-repeat;
background-position: center;
background-color: transparent;
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
* SPDX-License-Identifier: EPL-2.0
**********************************************************************/

import { Emitter, Event } from '@theia/core';
import { WidgetOpenMode } from '@theia/core/lib/browser';
import { TaskService } from '@theia/task/lib/browser';
import { TaskTerminalWidgetOpenerOptions } from '@theia/task/lib/browser/task-terminal-widget-manager';
Expand All @@ -20,6 +21,9 @@ import { CHE_TASK_TYPE, REMOTE_TASK_KIND, TASK_KIND } from './che-task-terminal-
@injectable()
export class TaskConfigurationsService extends TaskService {

protected readonly onDidStartTaskFailureEmitter = new Emitter<TaskInfo>();
readonly onDidStartTaskFailure: Event<TaskInfo> = this.onDidStartTaskFailureEmitter.event;

@inject(CheTaskResolver)
protected readonly cheTaskResolver: CheTaskResolver;

Expand All @@ -39,6 +43,8 @@ export class TaskConfigurationsService extends TaskService {

return taskInfo;
} catch (error) {
this.onDidStartTaskFailureEmitter.fire({ config: resolvedTask, kind: terminal.kind, terminalId: terminal.terminalId, taskId: -1, });

const errorMessage = `Error launching task '${taskLabel}': ${error.message}`;
terminal.writeLine(`\x1b[31m ${errorMessage} \x1b[0m\n`);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,21 @@
import { TaskStatusOptions } from '@eclipse-che/plugin';
import { TerminalService } from '@theia/terminal/lib/browser/base/terminal-service';
import { TerminalWidget } from '@theia/terminal/lib/browser/base/terminal-widget';
import { inject, injectable } from 'inversify';
import { inject, injectable, postConstruct } from 'inversify';
import { CheTaskTerminalWidgetManager } from './che-task-terminal-widget-manager';
import { TaskConfigurationsService } from './task-config-service';

const StatusIcon = {
SUCCESS: 'fa fa-check task-status-success',
ERROR: 'fa fa-times-circle task-status-error',
SUCCESS: 'fa fa-check',
ERROR: 'fa fa-times-circle',
IN_PROGRESS: 'task-status-in-progress',
UNKNOWN: 'fa-question'
};

enum TaskStatus {
Success = 'SUCCESS',
Error = 'ERROR',
InProgress = 'IN_PROGRESS',
Unknown = 'UNKNOWN'
}

Expand All @@ -34,6 +37,34 @@ export class TaskStatusHandler {
@inject(TaskConfigurationsService)
protected readonly taskService: TaskConfigurationsService;

@inject(CheTaskTerminalWidgetManager)
protected readonly cheTaskTerminalWidgetManager: CheTaskTerminalWidgetManager;

@postConstruct()
protected init(): void {
this.terminalService.onDidCreateTerminal(async (terminal: TerminalWidget) => {
if (this.cheTaskTerminalWidgetManager.isTaskTerminal(terminal)) {
this.setStatus(TaskStatus.InProgress, terminal);

this.subscribeOnTaskTerminalEvents(terminal);
}
});

this.taskService.onDidStartTaskFailure(taskInfo => {
const kind = taskInfo.kind;
const terminalId = taskInfo.terminalId;

if (kind && terminalId) {
const status = TaskStatus.Error;
const terminalIdentifier = { kind, terminalId };

this.setTaskStatus({ status, terminalIdentifier });
}
});

this.handleOpenTerminals();
}

async setTaskStatus(options: TaskStatusOptions): Promise<void> {
const terminalIdentifier = options.terminalIdentifier;
const kind = terminalIdentifier.kind;
Expand All @@ -55,4 +86,33 @@ export class TaskStatusHandler {
terminal.title.iconClass = newStatusIcon;
}
}

private async handleOpenTerminals(): Promise<void> {
const taskTerminals = this.cheTaskTerminalWidgetManager.getTaskTerminals();
for (const terminal of taskTerminals) {
try {
const processId = await terminal.processId;
if (processId) {
this.setStatus(TaskStatus.InProgress, terminal);
}
} catch (error) {
// an error is thrown if a terminal is not started, we are trying to get a process ID for started terminals
}
}
}

private subscribeOnTaskTerminalEvents(terminal: TerminalWidget): void {
const didOpenListener = terminal.onDidOpen(async () => {
this.setStatus(TaskStatus.InProgress, terminal);
});

const didOpenFailureListener = terminal.onDidOpenFailure(async () => {
this.setStatus(TaskStatus.Error, terminal);
});

terminal.onDidDispose(() => {
didOpenListener.dispose();
didOpenFailureListener.dispose();
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { CheTask, CheTaskMain, PLUGIN_RPC_CONTEXT } from '../common/che-protocol

export enum TaskStatus {
Success = 'SUCCESS',
InProgress = 'IN_PROGRESS',
Error = 'ERROR',
Unknown = 'UNKNOWN'
}
Expand Down
1 change: 1 addition & 0 deletions extensions/eclipse-che-theia-plugin/src/che-proposed.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ declare module '@eclipse-che/plugin' {
export enum TaskStatus {
Success = 'SUCCESS',
Error = 'ERROR',
InProgress = 'IN_PROGRESS',
Unknown = 'UNKNOWN'
}

Expand Down

0 comments on commit 6d93698

Please sign in to comment.