Added Job panel to Admin Console. Added support for JobSpecification, JobAcitivityGraph, and JobRun in the Admin Console code.

git-svn-id: https://hyracks.googlecode.com/svn/branches/hyracks_dev_next@701 123451ca-8445-de46-9d55-352943316053
diff --git a/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/beans/JobActivityGraphDetails.java b/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/beans/JobActivityGraphDetails.java
new file mode 100644
index 0000000..4ee1add
--- /dev/null
+++ b/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/beans/JobActivityGraphDetails.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.hyracks.adminconsole.client.beans;
+
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.core.client.JsArray;
+
+public final class JobActivityGraphDetails extends JavaScriptObject {
+    protected JobActivityGraphDetails() {
+    }
+
+    public native JsArray<ActivityDetails> getActivities()
+    /*-{
+         return this["activities"];
+    }-*/;
+
+    public static final class ActivityDetails extends JavaScriptObject {
+        protected ActivityDetails() {
+        }
+
+        public native String getId()
+        /*-{
+            return this["id"];
+        }-*/;
+
+        public native String getJavaClass()
+        /*-{
+            return this["java-class"];
+        }-*/;
+
+        public native String getOperatorId()
+        /*-{
+            return this["operator-id"];
+        }-*/;
+
+        public native JsArray<ActivityInputDetails> getInputs()
+        /*-{
+             return this["inputs"];
+        }-*/;
+
+        public native JsArray<ActivityOutputDetails> getOutputs()
+        /*-{
+             return this["outputs"];
+        }-*/;
+    }
+
+    public static final class ActivityInputDetails extends JavaScriptObject {
+        protected ActivityInputDetails() {
+        }
+
+        public native Integer getInputPort()
+        /*-{
+            return this["input-port"];
+        }-*/;
+
+        public native String getConnectorId()
+        /*-{
+            return this["connector-id"];
+        }-*/;
+    }
+
+    public static final class ActivityOutputDetails extends JavaScriptObject {
+        protected ActivityOutputDetails() {
+        }
+
+        public native Integer getOutputPort()
+        /*-{
+            return this["output-port"];
+        }-*/;
+
+        public native String getConnectorId()
+        /*-{
+            return this["connector-id"];
+        }-*/;
+    }
+}
\ No newline at end of file
diff --git a/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/beans/JobRunDetails.java b/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/beans/JobRunDetails.java
new file mode 100644
index 0000000..9717f90
--- /dev/null
+++ b/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/beans/JobRunDetails.java
@@ -0,0 +1,250 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.hyracks.adminconsole.client.beans;
+
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.core.client.JsArray;
+import com.google.gwt.core.client.JsArrayInteger;
+import com.google.gwt.core.client.JsArrayString;
+
+public final class JobRunDetails extends JavaScriptObject {
+    protected JobRunDetails() {
+    }
+
+    public native String getJobId()
+    /*-{
+         return this["job-id"];
+    }-*/;
+
+    public native String getApplicationName()
+    /*-{
+         return this["application-name"];
+    }-*/;
+
+    public native String getStatus()
+    /*-{
+         return this.status;
+    }-*/;
+
+    public native Long getCreateTime()
+    /*-{
+         return this["create-time"];
+    }-*/;
+
+    public native Long getStartTime()
+    /*-{
+         return this["start-time"];
+    }-*/;
+
+    public native Long getEndTime()
+    /*-{
+         return this["end-time"];
+    }-*/;
+
+    public native JsArray<ActivityClusterDetails> getActivityClusters()
+    /*-{
+         return this["activity-clusters"];
+     }-*/;
+
+    public static final class ActivityClusterDetails extends JavaScriptObject {
+        protected ActivityClusterDetails() {
+        }
+
+        public native String getActivityClusterId()
+        /*-{
+             return this["activity-cluster-id"];
+        }-*/;
+
+        public native JsArrayString getActivities()
+        /*-{
+             return this.activities;
+         }-*/;
+
+        public native JsArrayString getDependents()
+        /*-{
+             return this.dependents;
+         }-*/;
+
+        public native JsArrayString getDependencies()
+        /*-{
+             return this.dependencies;
+         }-*/;
+
+        public native ActivityClusterPlan getActivityClusterPlan()
+        /*-{
+             return this.plan;
+         }-*/;
+    }
+
+    public static final class ActivityClusterPlan extends JavaScriptObject {
+        protected ActivityClusterPlan() {
+        }
+
+        public native JsArray<ActivityDetails> getActivities()
+        /*-{
+            return this["activities"];
+        }-*/;
+
+        public native JsArray<TaskClusterDetails> getTaskClusters()
+        /*-{
+            return this["task-clusters"];
+        }-*/;
+    }
+
+    public static final class ActivityDetails extends JavaScriptObject {
+        protected ActivityDetails() {
+        }
+
+        public native String getActivityId()
+        /*-{
+            return this["activity-id"];
+        }-*/;
+
+        public native Integer getPartitionCount()
+        /*-{
+            return this["partition-count"];
+        }-*/;
+
+        public native JsArrayInteger getInputPartitionCounts()
+        /*-{
+            return this["input-partition-counts"];
+        }-*/;
+
+        public native JsArrayInteger getOutputPartitionCounts()
+        /*-{
+            return this["output-partition-counts"];
+        }-*/;
+
+        public native JsArray<TaskDetails> getTasks()
+        /*-{
+            return this["tasks"];
+        }-*/;
+    }
+
+    public static final class TaskDetails extends JavaScriptObject {
+        protected TaskDetails() {
+        }
+
+        public native String getTaskId()
+        /*-{
+             return this["task-id"];
+        }-*/;
+
+        public native JsArrayString getDependents()
+        /*-{
+             return this.dependents;
+         }-*/;
+
+        public native JsArrayString getDependencies()
+        /*-{
+             return this.dependencies;
+         }-*/;
+    }
+
+    public static final class TaskClusterDetails extends JavaScriptObject {
+        protected TaskClusterDetails() {
+        }
+
+        public native String getTaskClusterId()
+        /*-{
+             return this["task-cluster-id"];
+        }-*/;
+
+        public native JsArrayString getTasks()
+        /*-{
+             return this.tasks;
+         }-*/;
+
+        public native JsArrayString getProducedPartitions()
+        /*-{
+             return this["produced-partitions"];
+         }-*/;
+
+        public native JsArrayString getRequiredPartitions()
+        /*-{
+             return this["required-partitions"];
+         }-*/;
+    }
+
+    public static final class TaskClusterAttemptDetails extends JavaScriptObject {
+        protected TaskClusterAttemptDetails() {
+        }
+
+        public native Integer getAttempt()
+        /*-{
+             return this["attempt"];
+        }-*/;
+
+        public native String getStatus()
+        /*-{
+             return this["status"];
+        }-*/;
+
+        public native JsArray<TaskAttemptDetails> getTaskAttempts()
+        /*-{
+             return this["task-attempts"];
+        }-*/;
+    }
+
+    public static final class TaskAttemptDetails extends JavaScriptObject {
+        protected TaskAttemptDetails() {
+        }
+
+        public native String getTaskId()
+        /*-{
+             return this["task-id"];
+        }-*/;
+
+        public native String getTaskAttemptId()
+        /*-{
+             return this["task-attempt-id"];
+        }-*/;
+
+        public native String getStatus()
+        /*-{
+             return this["status"];
+        }-*/;
+
+        public native String getNodeId()
+        /*-{
+             return this["node-id"];
+        }-*/;
+
+        public native ExceptionDetails getException()
+        /*-{
+             return this["exception"];
+        }-*/;
+    }
+
+    public static final class ExceptionDetails extends JavaScriptObject {
+        protected ExceptionDetails() {
+        }
+
+        public native String getExceptionClass()
+        /*-{
+             return this["exception-class"];
+        }-*/;
+
+        public native String getExceptionMessage()
+        /*-{
+             return this["exception-message"];
+        }-*/;
+
+        public native String getExceptionStacktrace()
+        /*-{
+             return this["exception-stacktrace"];
+        }-*/;
+    }
+}
\ No newline at end of file
diff --git a/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/beans/JobSpecificationDetails.java b/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/beans/JobSpecificationDetails.java
new file mode 100644
index 0000000..f8d331b
--- /dev/null
+++ b/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/beans/JobSpecificationDetails.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.hyracks.adminconsole.client.beans;
+
+import com.google.gwt.core.client.JavaScriptObject;
+import com.google.gwt.core.client.JsArray;
+
+public final class JobSpecificationDetails extends JavaScriptObject {
+    protected JobSpecificationDetails() {
+    }
+
+    public native JsArray<OperatorDescriptor> getOperators()
+    /*-{
+         return this["operators"];
+    }-*/;
+
+    public native JsArray<OperatorDescriptor> getConnectors()
+    /*-{
+         return this["connectors"];
+    }-*/;
+
+    public static final class OperatorDescriptor extends JavaScriptObject {
+        protected OperatorDescriptor() {
+        }
+
+        public native String getId()
+        /*-{
+            return this["id"];
+        }-*/;
+
+        public native String getJavaClass()
+        /*-{
+            return this["java-class"];
+        }-*/;
+
+        public native Integer getInArity()
+        /*-{
+            return this["in-arity"];
+        }-*/;
+
+        public native String getOutArity()
+        /*-{
+            return this["out-arity"];
+        }-*/;
+    }
+
+    public static final class ConnectorDescriptor extends JavaScriptObject {
+        protected ConnectorDescriptor() {
+        }
+
+        public native String getId()
+        /*-{
+            return this["id"];
+        }-*/;
+
+        public native String getJavaClass()
+        /*-{
+            return this["java-class"];
+        }-*/;
+    }
+}
\ No newline at end of file
diff --git a/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/panels/JobsDetailsPanel.java b/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/panels/JobsDetailsPanel.java
new file mode 100644
index 0000000..c90809d
--- /dev/null
+++ b/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/panels/JobsDetailsPanel.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.hyracks.adminconsole.client.panels;
+
+import com.google.gwt.core.client.GWT;
+import com.google.gwt.http.client.RequestException;
+import com.google.gwt.uibinder.client.UiBinder;
+import com.google.gwt.user.client.Timer;
+import com.google.gwt.user.client.ui.Composite;
+import com.google.gwt.user.client.ui.Widget;
+
+import edu.uci.ics.hyracks.adminconsole.client.beans.JobRunDetails;
+import edu.uci.ics.hyracks.adminconsole.client.rest.AbstractRestFunction;
+import edu.uci.ics.hyracks.adminconsole.client.rest.GetJobRunDetailsFunction;
+
+public class JobsDetailsPanel extends Composite {
+    interface Binder extends UiBinder<Widget, JobsDetailsPanel> {
+    }
+
+    private final static Binder binder = GWT.create(Binder.class);
+
+    private final String jobId;
+
+    private int callCounter;
+
+    private Timer timer;
+
+    public JobsDetailsPanel(String jobId) {
+        initWidget(binder.createAndBindUi(this));
+        this.jobId = jobId;
+
+        timer = new Timer() {
+            @Override
+            public void run() {
+                refresh();
+            }
+        };
+        refresh();
+        timer.scheduleRepeating(10000);
+    }
+
+    public void destroy() {
+        timer.cancel();
+    }
+
+    private void refresh() {
+        try {
+            final int counter = ++callCounter;
+            new GetJobRunDetailsFunction(jobId).call(new AbstractRestFunction.ResultCallback<JobRunDetails>() {
+                @Override
+                public void onSuccess(JobRunDetails result) {
+                    if (counter == callCounter) {
+                    }
+                }
+
+                @Override
+                public void onError(Throwable exception) {
+
+                }
+            });
+        } catch (RequestException e) {
+            e.printStackTrace();
+        }
+    }
+}
\ No newline at end of file
diff --git a/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/panels/JobsDetailsPanel.ui.xml b/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/panels/JobsDetailsPanel.ui.xml
new file mode 100644
index 0000000..6fd21d3
--- /dev/null
+++ b/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/panels/JobsDetailsPanel.ui.xml
@@ -0,0 +1,31 @@
+<!DOCTYPE ui:UiBinder
+  SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent"
+>
+<ui:UiBinder
+  xmlns:ui='urn:ui:com.google.gwt.uibinder'
+  xmlns:g='urn:import:com.google.gwt.user.client.ui'
+  xmlns:charts='urn:import:edu.uci.ics.hyracks.adminconsole.client.details.node.charts'>
+  <g:StackLayoutPanel unit="EM">
+    <g:stack>
+      <g:header size="2">
+        System Load
+      </g:header>
+      <g:ScrollPanel>
+      </g:ScrollPanel>
+    </g:stack>
+    <g:stack>
+      <g:header size="2">
+        Memory Usage
+      </g:header>
+      <g:ScrollPanel>
+      </g:ScrollPanel>
+    </g:stack>
+    <g:stack>
+      <g:header size="2">
+        Thread Count
+      </g:header>
+      <g:ScrollPanel>
+      </g:ScrollPanel>
+    </g:stack>
+  </g:StackLayoutPanel>
+</ui:UiBinder>
\ No newline at end of file
diff --git a/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/panels/JobsPanel.java b/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/panels/JobsPanel.java
index 8e8557b..60d3ab1 100644
--- a/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/panels/JobsPanel.java
+++ b/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/panels/JobsPanel.java
@@ -54,6 +54,17 @@
         initWidget(binder.createAndBindUi(this));
 
         jobs.setRefreshRequestHandler(this);
+        jobs.setClickListener(new JobsTableWidget.IClickListener() {
+            @Override
+            public void click(String jobId) {
+                if (details instanceof JobsDetailsPanel) {
+                    ((JobsDetailsPanel) details).destroy();
+                }
+                split.remove(details);
+                details = new JobsDetailsPanel(jobId);
+                split.add(details);
+            }
+        });
 
         Timer timer = new Timer() {
             @Override
diff --git a/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/rest/GetJobActivityGraphDetailsFunction.java b/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/rest/GetJobActivityGraphDetailsFunction.java
new file mode 100644
index 0000000..0b759b9
--- /dev/null
+++ b/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/rest/GetJobActivityGraphDetailsFunction.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.hyracks.adminconsole.client.rest;
+
+import com.google.gwt.core.client.JsArray;
+
+import edu.uci.ics.hyracks.adminconsole.client.beans.JobActivityGraphDetails;
+
+public class GetJobActivityGraphDetailsFunction extends AbstractRestFunction<JsArray<JobActivityGraphDetails>> {
+    private final String jobId;
+
+    private GetJobActivityGraphDetailsFunction(String jobId) {
+        this.jobId = jobId;
+    }
+
+    @Override
+    protected void appendURLPath(StringBuilder buffer) {
+        buffer.append("/jobs/").append(jobId).append("/job-activity-graph");
+    }
+}
\ No newline at end of file
diff --git a/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/rest/GetJobRunDetailsFunction.java b/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/rest/GetJobRunDetailsFunction.java
new file mode 100644
index 0000000..494cdf7
--- /dev/null
+++ b/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/rest/GetJobRunDetailsFunction.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.hyracks.adminconsole.client.rest;
+
+import edu.uci.ics.hyracks.adminconsole.client.beans.JobRunDetails;
+
+public class GetJobRunDetailsFunction extends AbstractRestFunction<JobRunDetails> {
+    private final String jobId;
+
+    public GetJobRunDetailsFunction(String jobId) {
+        this.jobId = jobId;
+    }
+
+    @Override
+    protected void appendURLPath(StringBuilder buffer) {
+        buffer.append("/jobs/").append(jobId).append("/job-run");
+    }
+}
\ No newline at end of file
diff --git a/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/rest/GetJobSpecificationDetailsFunction.java b/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/rest/GetJobSpecificationDetailsFunction.java
new file mode 100644
index 0000000..7c4de4b
--- /dev/null
+++ b/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/rest/GetJobSpecificationDetailsFunction.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2009-2010 by The Regents of the University of California
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * you may obtain a copy of the License from
+ * 
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package edu.uci.ics.hyracks.adminconsole.client.rest;
+
+import com.google.gwt.core.client.JsArray;
+
+import edu.uci.ics.hyracks.adminconsole.client.beans.JobSpecificationDetails;
+
+public class GetJobSpecificationDetailsFunction extends AbstractRestFunction<JsArray<JobSpecificationDetails>> {
+    private final String jobId;
+
+    private GetJobSpecificationDetailsFunction(String jobId) {
+        this.jobId = jobId;
+    }
+
+    @Override
+    protected void appendURLPath(StringBuilder buffer) {
+        buffer.append("/jobs/").append(jobId).append("/job-specification");
+    }
+}
\ No newline at end of file
diff --git a/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/widgets/JobsTableWidget.java b/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/widgets/JobsTableWidget.java
index 91ab87f..0670451 100644
--- a/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/widgets/JobsTableWidget.java
+++ b/hyracks-admin-console/src/main/java/edu/uci/ics/hyracks/adminconsole/client/widgets/JobsTableWidget.java
@@ -14,10 +14,13 @@
  */
 package edu.uci.ics.hyracks.adminconsole.client.widgets;
 
+import com.google.gwt.cell.client.ClickableTextCell;
+import com.google.gwt.cell.client.FieldUpdater;
 import com.google.gwt.core.client.GWT;
 import com.google.gwt.uibinder.client.UiBinder;
 import com.google.gwt.uibinder.client.UiField;
 import com.google.gwt.user.cellview.client.CellTable;
+import com.google.gwt.user.cellview.client.Column;
 import com.google.gwt.user.cellview.client.TextColumn;
 import com.google.gwt.user.client.ui.Composite;
 import com.google.gwt.user.client.ui.Widget;
@@ -31,6 +34,10 @@
         public void refresh();
     }
 
+    public interface IClickListener {
+        public void click(String jobId);
+    }
+
     interface Binder extends UiBinder<Widget, JobsTableWidget> {
     }
 
@@ -43,15 +50,25 @@
 
     private IRefreshRequestHandler refreshRequestHandler;
 
+    private IClickListener cl;
+
     public JobsTableWidget() {
         initWidget(binder.createAndBindUi(this));
 
-        TextColumn<JobSummary> idCol = new TextColumn<JobSummary>() {
+        Column<JobSummary, String> idCol = new Column<JobSummary, String>(new ClickableTextCell()) {
             @Override
             public String getValue(JobSummary object) {
                 return object.getJobId();
             }
         };
+        idCol.setFieldUpdater(new FieldUpdater<JobSummary, String>() {
+            @Override
+            public void update(int index, JobSummary object, String value) {
+                if (cl != null) {
+                    cl.click(value);
+                }
+            }
+        });
         idCol.setSortable(true);
 
         TextColumn<JobSummary> appCol = new TextColumn<JobSummary>() {
@@ -115,6 +132,10 @@
         jobSummaryProvider.addDataDisplay(table);
     }
 
+    public void setClickListener(IClickListener cl) {
+        this.cl = cl;
+    }
+
     public AsyncDataProvider<JobSummary> getDataProvider() {
         return jobSummaryProvider;
     }
diff --git a/hyracks-control-cc/src/main/java/edu/uci/ics/hyracks/control/cc/job/JobRun.java b/hyracks-control-cc/src/main/java/edu/uci/ics/hyracks/control/cc/job/JobRun.java
index 8fdde7c..3b3a777 100644
--- a/hyracks-control-cc/src/main/java/edu/uci/ics/hyracks/control/cc/job/JobRun.java
+++ b/hyracks-control-cc/src/main/java/edu/uci/ics/hyracks/control/cc/job/JobRun.java
@@ -175,6 +175,8 @@
         JSONObject result = new JSONObject();
 
         result.put("job-id", jobId.toString());
+        result.put("application-name", jag.getApplicationName());
+        result.put("status", getStatus());
         result.put("create-time", getCreateTime());
         result.put("start-time", getCreateTime());
         result.put("end-time", getCreateTime());
@@ -260,7 +262,7 @@
 
                     acTasks.put(entry);
                 }
-                planJSON.put("task-map", acTasks);
+                planJSON.put("activities", acTasks);
 
                 JSONArray tClusters = new JSONArray();
                 for (TaskCluster tc : acp.getTaskClusters()) {
@@ -296,6 +298,7 @@
                             JSONArray taskAttempts = new JSONArray();
                             for (TaskAttempt ta : tca.getTaskAttempts()) {
                                 JSONObject taskAttempt = new JSONObject();
+                                taskAttempt.put("task-id", ta.getTaskAttemptId().getTaskId());
                                 taskAttempt.put("task-attempt-id", ta.getTaskAttemptId());
                                 taskAttempt.put("status", ta.getStatus());
                                 taskAttempt.put("node-id", ta.getNodeId());