completed monitor
git-svn-id: http://svn.research-infrastructures.eu/public/d4science/gcube/trunk/portlets/widgets/ws-task-executor-widget@167565 82a268e6-3cf1-43bd-a215-b396298e98cf
This commit is contained in:
parent
0c69fa392d
commit
3352415902
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.gcube.portlets.widgets.wstaskexecutor.client;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import com.google.gwt.i18n.client.DateTimeFormat;
|
||||
|
||||
|
||||
/**
|
||||
* The Class DateFormatterUtil.
|
||||
*
|
||||
* @author Francesco Mangiacrapa at ISTI-CNR (francesco.mangiacrapa@isti.cnr.it)
|
||||
* May 17, 2018
|
||||
*/
|
||||
public class DateFormatterUtil {
|
||||
|
||||
public static DateTimeFormat formatDate = DateTimeFormat
|
||||
.getFormat("yyyy/MM/dd");
|
||||
public static DateTimeFormat formatTime = DateTimeFormat
|
||||
.getFormat("yyyy/MM/dd 'at' HH:mm:ss");
|
||||
|
||||
|
||||
/**
|
||||
* Gets the date time to string.
|
||||
*
|
||||
* @param time the time
|
||||
* @return the date time to string
|
||||
*/
|
||||
public static String getDateTimeToString(Long time) {
|
||||
Date date;
|
||||
if(time!=null)
|
||||
date = new Date(time.longValue());
|
||||
else
|
||||
date = new Date();
|
||||
|
||||
return formatTime.format(date);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the date to string.
|
||||
*
|
||||
* @param time
|
||||
* the time
|
||||
* @return the date to string
|
||||
*/
|
||||
public static String getDateToString(long time) {
|
||||
Date date = new Date(time);
|
||||
return formatDate.format(date);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,134 @@
|
|||
/**
|
||||
*
|
||||
*/
|
||||
package org.gcube.portlets.widgets.wstaskexecutor.client;
|
||||
|
||||
import com.google.gwt.storage.client.Storage;
|
||||
import com.google.gwt.storage.client.StorageMap;
|
||||
|
||||
|
||||
/**
|
||||
* The Class HTML5StorageUtil.
|
||||
*
|
||||
* @author Francesco Mangiacrapa francesco.mangiacrapa@isti.cnr.it
|
||||
* May 17, 2018
|
||||
*/
|
||||
public class HTML5StorageUtil {
|
||||
|
||||
private Storage localStorage;
|
||||
private StorageMap localStorageMap;
|
||||
|
||||
|
||||
/**
|
||||
* Instantiates a new HTM l5 storage util.
|
||||
*/
|
||||
public HTML5StorageUtil() {
|
||||
initLocalStorage();
|
||||
initStorageMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Inits the local storage.
|
||||
*/
|
||||
private void initLocalStorage(){
|
||||
if(localStorage==null)
|
||||
localStorage = Storage.getSessionStorageIfSupported();
|
||||
}
|
||||
|
||||
/**
|
||||
* Inits the storage map.
|
||||
*
|
||||
* @return the storage map
|
||||
*/
|
||||
private StorageMap initStorageMap(){
|
||||
if(localStorageMap==null)
|
||||
localStorageMap = new StorageMap(localStorage);
|
||||
|
||||
return localStorageMap;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if is supported.
|
||||
*
|
||||
* @return true, if is supported
|
||||
*/
|
||||
public boolean isSupported(){
|
||||
|
||||
return localStorage!=null?true:false;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the item.
|
||||
*
|
||||
* @param key the key
|
||||
* @param data the data
|
||||
*/
|
||||
public void setItem(String key, String data){
|
||||
|
||||
if(localStorage==null)
|
||||
return;
|
||||
|
||||
localStorage.setItem(key, data);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the item.
|
||||
*
|
||||
* @param key the key
|
||||
* @return the item
|
||||
*/
|
||||
public String getItem(String key){
|
||||
if(localStorage==null)
|
||||
return "";
|
||||
|
||||
String data = localStorage.getItem(key);
|
||||
|
||||
return data==null?"":data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append value.
|
||||
*
|
||||
* @param key the key
|
||||
* @param data the value
|
||||
*/
|
||||
public void appendValue(String key, String data){
|
||||
|
||||
if(localStorageMap==null)
|
||||
return;
|
||||
|
||||
String newData = "";
|
||||
if (localStorageMap.containsKey(key)!= true){
|
||||
newData = localStorage.getItem(key); //adding old data at start
|
||||
}
|
||||
|
||||
newData += data;
|
||||
setItem(key, newData);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the local storage.
|
||||
*
|
||||
* @return the localStorage
|
||||
*/
|
||||
public Storage getLocalStorage() {
|
||||
|
||||
return localStorage;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gets the local storage map.
|
||||
*
|
||||
* @return the localStorageMap
|
||||
*/
|
||||
public StorageMap getLocalStorageMap() {
|
||||
|
||||
return localStorageMap;
|
||||
}
|
||||
|
||||
}
|
|
@ -264,7 +264,8 @@ public class WsTaskExecutorWidget {
|
|||
final Modal box = new Modal(true);
|
||||
box.setTitle("Executing task configuration...");
|
||||
|
||||
LoaderIcon loader = new LoaderIcon("Executing task configuration for: <br/>"+conf.getTaskId());
|
||||
String algName = conf.getTaskId().substring(conf.getTaskId().lastIndexOf(".")+1, conf.getTaskId().length());
|
||||
LoaderIcon loader = new LoaderIcon("Inizializing new run for: "+algName);
|
||||
box.add(loader);
|
||||
|
||||
WsTaskExecutorWidget.wsTaskService.executeTheTask(conf, new AsyncCallback<TaskExecutionStatus>() {
|
||||
|
|
|
@ -119,7 +119,7 @@ public class WsTaskExecutorWidgetViewManager {
|
|||
GWT.log("Show Monitor TaskStatus for itemId: "+folder.getItemId());
|
||||
|
||||
final Modal box = new Modal(true);
|
||||
box.addStyleName("ws-thredds-modal-body");
|
||||
box.addStyleName("ws-task-modal-body");
|
||||
box.setTitle("Monitor Task Execution on: "+FormatUtil.getFolderTitle(folder.getItemName(), 20));
|
||||
box.setWidth(800);
|
||||
box.hide(false);
|
||||
|
|
|
@ -5,18 +5,24 @@ import org.gcube.common.workspacetaskexecutor.shared.TaskStatus;
|
|||
import org.gcube.common.workspacetaskexecutor.shared.dataminer.TaskComputation;
|
||||
import org.gcube.common.workspacetaskexecutor.shared.dataminer.TaskConfiguration;
|
||||
import org.gcube.common.workspacetaskexecutor.shared.dataminer.TaskExecutionStatus;
|
||||
import org.gcube.portlets.widgets.wstaskexecutor.client.DateFormatterUtil;
|
||||
import org.gcube.portlets.widgets.wstaskexecutor.client.HTML5StorageUtil;
|
||||
import org.gcube.portlets.widgets.wstaskexecutor.client.view.LoaderIcon;
|
||||
import org.gcube.portlets.widgets.wstaskexecutor.shared.WSItem;
|
||||
|
||||
import com.github.gwtbootstrap.client.ui.Alert;
|
||||
import com.github.gwtbootstrap.client.ui.Form;
|
||||
import com.github.gwtbootstrap.client.ui.Label;
|
||||
import com.github.gwtbootstrap.client.ui.Pager;
|
||||
import com.github.gwtbootstrap.client.ui.ProgressBar;
|
||||
import com.github.gwtbootstrap.client.ui.TextArea;
|
||||
import com.github.gwtbootstrap.client.ui.TextBox;
|
||||
import com.github.gwtbootstrap.client.ui.constants.AlertType;
|
||||
import com.github.gwtbootstrap.client.ui.constants.LabelType;
|
||||
import com.github.gwtbootstrap.client.ui.constants.ResizeType;
|
||||
import com.google.gwt.core.client.GWT;
|
||||
import com.google.gwt.dom.client.Style.Float;
|
||||
import com.google.gwt.dom.client.Style.Unit;
|
||||
import com.google.gwt.event.dom.client.ClickEvent;
|
||||
import com.google.gwt.event.dom.client.ClickHandler;
|
||||
import com.google.gwt.uibinder.client.UiBinder;
|
||||
|
@ -24,6 +30,7 @@ import com.google.gwt.uibinder.client.UiField;
|
|||
import com.google.gwt.user.client.Timer;
|
||||
import com.google.gwt.user.client.ui.Composite;
|
||||
import com.google.gwt.user.client.ui.HTMLPanel;
|
||||
import com.google.gwt.user.client.ui.HorizontalPanel;
|
||||
import com.google.gwt.user.client.ui.Widget;
|
||||
|
||||
|
||||
|
@ -39,14 +46,29 @@ public abstract class MonitorFolderTaskExecutionStatusView extends Composite {
|
|||
|
||||
//private static final String DATE_FORMAT_YYYY_MM_DD_HH_MM_SS = "yyyy-MM-dd HH:mm:ss";
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final String KEY_LOCAL_STORAGE_COMP_MSG_HISTORY = "comp_msg_history";
|
||||
|
||||
public static final String PROCESSING_STATE = "Processing state: ";
|
||||
|
||||
private static final String EMPTY = "EMPTY";
|
||||
|
||||
private static final String NEW_STATUS_CHARS = "******* ";
|
||||
|
||||
private static final String NEW_LINE = "\n";
|
||||
|
||||
private static final String NEW_LOG = NEW_STATUS_CHARS;
|
||||
|
||||
private static final String DASH = "-";
|
||||
|
||||
private static final String START_SECTION = DASH+DASH;
|
||||
|
||||
private static final String NEW_SECTION = NEW_LINE+NEW_LINE+DASH+DASH;
|
||||
|
||||
public static int maxLogSize = 10000;
|
||||
|
||||
/** The ui binder. */
|
||||
private static MonitorFolderTaskExecutionStatusViewUiBinder uiBinder =
|
||||
GWT.create(MonitorFolderTaskExecutionStatusViewUiBinder.class);
|
||||
|
@ -68,24 +90,14 @@ public abstract class MonitorFolderTaskExecutionStatusView extends Composite {
|
|||
@UiField
|
||||
ProgressBar progress_percentage;
|
||||
|
||||
|
||||
@UiField
|
||||
TextArea field_current_message;
|
||||
|
||||
// @UiField
|
||||
// TextBox field_queued_items;
|
||||
//
|
||||
// @UiField
|
||||
// TextBox field_transferred_items;
|
||||
|
||||
// @UiField
|
||||
// TextBox field_number_error;
|
||||
|
||||
@UiField
|
||||
TextArea field_history_messages;
|
||||
|
||||
@UiField
|
||||
HTMLPanel form_monitor_thredds_transfer;
|
||||
TextArea field_computation_info;
|
||||
|
||||
@UiField
|
||||
HTMLPanel field_loader;
|
||||
|
@ -93,7 +105,10 @@ public abstract class MonitorFolderTaskExecutionStatusView extends Composite {
|
|||
@UiField
|
||||
Form field_form;
|
||||
|
||||
private WSItem folder;
|
||||
@UiField
|
||||
HorizontalPanel field_times;
|
||||
|
||||
private WSItem wsItem;
|
||||
|
||||
|
||||
/** The scheduler time. */
|
||||
|
@ -103,6 +118,8 @@ public abstract class MonitorFolderTaskExecutionStatusView extends Composite {
|
|||
|
||||
private TaskComputation taskComputation;
|
||||
|
||||
private HTML5StorageUtil storageUtil = new HTML5StorageUtil();
|
||||
|
||||
|
||||
/**
|
||||
* Submit handler.
|
||||
|
@ -149,48 +166,61 @@ public abstract class MonitorFolderTaskExecutionStatusView extends Composite {
|
|||
|
||||
pager.getRight().setVisible(false);
|
||||
|
||||
field_history_messages.setHeight("200px");
|
||||
field_history_messages.setHeight("165px");
|
||||
field_history_messages.setResize(ResizeType.BOTH);
|
||||
field_current_message.setHeight("80px");
|
||||
|
||||
field_computation_info.setHeight("165px");
|
||||
field_computation_info.setResize(ResizeType.BOTH);
|
||||
|
||||
field_current_message.setResize(ResizeType.BOTH);
|
||||
|
||||
// field_queued_items.addStyleName("myLittleWidth");
|
||||
// field_number_error.addStyleName("myLittleWidth");
|
||||
// field_transferred_items.addStyleName("myLittleWidth");
|
||||
|
||||
// field_current_message.addStyleName("textAreaWidth");
|
||||
// field_history_messages.addStyleName("textAreaWidth");
|
||||
|
||||
// field_form.addStyleName("myFormWidth");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update status view.
|
||||
*
|
||||
* @param folder the folder
|
||||
* @param wsItem the folder
|
||||
* @param taskExecutionStatus the sync status
|
||||
*/
|
||||
public void updateStatusView(WSItem folder, TaskExecutionStatus taskExecutionStatus) {
|
||||
this.folder = folder;
|
||||
public void updateStatusView(WSItem wsItem, TaskExecutionStatus taskExecutionStatus) {
|
||||
this.wsItem = wsItem;
|
||||
|
||||
field_loader.clear();
|
||||
LoaderIcon loader = new LoaderIcon("Waiting...");
|
||||
field_loader.add(loader);
|
||||
|
||||
this.folder = folder;
|
||||
this.wsItem = wsItem;
|
||||
this.field_current_message.setValue(EMPTY);
|
||||
//setFieldValue(this.field_number_error, UNKNOWN);
|
||||
// setFieldValue(this.field_queued_items, UNKNOWN);
|
||||
// setFieldValue(this.field_transferred_items, UNKNOWN);
|
||||
this.field_history_messages.setValue(EMPTY);
|
||||
|
||||
if(folder==null || taskExecutionStatus==null || taskExecutionStatus.getStatus()==null) {
|
||||
if(wsItem==null || taskExecutionStatus==null || taskExecutionStatus.getStatus()==null) {
|
||||
//setError(true, "Sync status error: either folder does not exist or the status is null");
|
||||
GWT.log("Sync status error: either folder does not exist or the status is null");
|
||||
return;
|
||||
}
|
||||
|
||||
String startTime = DateFormatterUtil.getDateTimeToString(taskExecutionStatus.getTaskComputation().getStartTime());
|
||||
field_times.clear();
|
||||
field_times.getElement().getStyle().setMarginTop(5, Unit.PX);
|
||||
field_times.getElement().getStyle().setMarginBottom(5, Unit.PX);
|
||||
field_times.setWidth("100%");
|
||||
Label l1 = new Label("Start: "+startTime);
|
||||
l1.setType(LabelType.INFO);
|
||||
field_times.add(l1);
|
||||
|
||||
Label endTimeLabel = new Label();
|
||||
if(taskExecutionStatus.getTaskComputation().getEndTime()!=null){
|
||||
String endTime = DateFormatterUtil.getDateTimeToString(taskExecutionStatus.getTaskComputation().getEndTime());
|
||||
//field_end_time.clear();
|
||||
endTimeLabel.setText("End: "+endTime);
|
||||
endTimeLabel.setType(LabelType.INFO);
|
||||
endTimeLabel.getElement().getStyle().setFloat(Float.RIGHT);
|
||||
field_times.add(endTimeLabel);
|
||||
}
|
||||
|
||||
if(taskExecutionStatus.getPercentCompleted()>=0){
|
||||
float perc = taskExecutionStatus.getPercentCompleted();
|
||||
progress_percentage.setPercent((int)perc);
|
||||
|
@ -220,6 +250,8 @@ public abstract class MonitorFolderTaskExecutionStatusView extends Composite {
|
|||
alert.setClose(false);
|
||||
alert.setType(AlertType.SUCCESS);
|
||||
field_loader.add(alert);
|
||||
if(endTimeLabel!=null)
|
||||
endTimeLabel.setType(LabelType.SUCCESS);
|
||||
break;
|
||||
case CANCELLED:
|
||||
field_loader.clear();
|
||||
|
@ -227,6 +259,7 @@ public abstract class MonitorFolderTaskExecutionStatusView extends Composite {
|
|||
alert1.setClose(false);
|
||||
alert1.setType(AlertType.WARNING);
|
||||
field_loader.add(alert1);
|
||||
endTimeLabel.setType(LabelType.WARNING);
|
||||
//progress_percentage.setVisible(false);
|
||||
break;
|
||||
case FAILED:
|
||||
|
@ -235,21 +268,27 @@ public abstract class MonitorFolderTaskExecutionStatusView extends Composite {
|
|||
alert2.setClose(false);
|
||||
alert2.setType(AlertType.ERROR);
|
||||
field_loader.add(alert2);
|
||||
endTimeLabel.setType(LabelType.WARNING);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
//Duration.currentTimeMillis()
|
||||
//first time adding the configurations
|
||||
String confs=START_SECTION+"Operator Id: "+NEW_LINE+taskExecutionStatus.getTaskComputation().getOperatorId();
|
||||
confs+=NEW_SECTION+"Operator Name: "+NEW_LINE+taskExecutionStatus.getTaskComputation().getOperatorName();
|
||||
confs+=NEW_SECTION+"EquivalentRequest: "+NEW_LINE+taskExecutionStatus.getTaskComputation().getEquivalentRequest();
|
||||
confs+=NEW_SECTION+"URL ID: "+NEW_LINE+taskExecutionStatus.getTaskComputation().getUrlId();
|
||||
this.field_computation_info.setValue(confs);
|
||||
|
||||
if(taskExecutionStatus.getCurrentMessage()!=null)
|
||||
this.field_current_message.setValue(taskExecutionStatus.getCurrentMessage());
|
||||
|
||||
// if(taskExecutionStatus.getErrorCount()!=null)
|
||||
// this.field_number_error.setValue(taskExecutionStatus.getErrorCount().toString());
|
||||
|
||||
if(taskExecutionStatus.getLog()!=null)
|
||||
this.field_history_messages.setValue(taskExecutionStatus.getLog());
|
||||
String msgHistory = NEW_LINE+NEW_LOG+DateFormatterUtil.getDateTimeToString(null)+NEW_LINE;
|
||||
msgHistory += taskExecutionStatus.getMessage();
|
||||
msgHistory += NEW_LINE;
|
||||
msgHistory += storageUtil.getItem(KEY_LOCAL_STORAGE_COMP_MSG_HISTORY); //adding also history
|
||||
this.field_history_messages.setValue(msgHistory);
|
||||
storageUtil.setItem(KEY_LOCAL_STORAGE_COMP_MSG_HISTORY, msgHistory);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -6,43 +6,26 @@
|
|||
border: 0px;
|
||||
}
|
||||
|
||||
.myPaddingLeft {
|
||||
padding-left: 180px;
|
||||
}
|
||||
|
||||
.myFormWidth {
|
||||
}
|
||||
</ui:style>
|
||||
<g:VerticalPanel>
|
||||
<g:HTMLPanel ui:field="form_monitor_thredds_transfer">
|
||||
<g:HTMLPanel ui:field="form_monitor_task">
|
||||
<g:HTMLPanel ui:field="field_loader">
|
||||
</g:HTMLPanel>
|
||||
<g:HTMLPanel>
|
||||
<g:HorizontalPanel ui:field="field_times"></g:HorizontalPanel>
|
||||
</g:HTMLPanel>
|
||||
<b:ProgressBar type="DEFAULT" color="INFO" percent="0"
|
||||
ui:field="progress_percentage" />
|
||||
<!-- <g:HorizontalPanel addStyleNames="myMarginLeft"> -->
|
||||
<!-- <b:ControlGroup ui:field="cg_queued_items" addStyleNames="myLittleMarginLeft"> -->
|
||||
<!-- <b:ControlLabel for="cl_queued_items">Items in queue</b:ControlLabel> -->
|
||||
<!-- <b:Controls> -->
|
||||
<!-- <b:TextBox b:id="field_queued_items" ui:field="field_queued_items" -->
|
||||
<!-- readOnly="true" addStyleNames="myLittleWidth"></b:TextBox> -->
|
||||
<!-- </b:Controls> -->
|
||||
<!-- </b:ControlGroup> -->
|
||||
<!-- <b:ControlGroup ui:field="cg_transferred_items" addStyleNames="myLittleMarginLeft"> -->
|
||||
<!-- <b:ControlLabel for="cl_transferred_items">Transferred items</b:ControlLabel> -->
|
||||
<!-- <b:Controls> -->
|
||||
<!-- <b:TextBox b:id="field_transferred_items" ui:field="field_transferred_items" -->
|
||||
<!-- readOnly="true" addStyleNames="myLittleWidth"> -->
|
||||
<!-- </b:TextBox> -->
|
||||
<!-- </b:Controls> -->
|
||||
<!-- </b:ControlGroup> -->
|
||||
<!-- <b:ControlGroup ui:field="cg_number_error" addStyleNames="myLittleMarginLeft"> -->
|
||||
<!-- <b:ControlLabel for="cl_number_error">Number of Errors</b:ControlLabel> -->
|
||||
<!-- <b:Controls> -->
|
||||
<!-- <b:TextBox b:id="field_number_error" ui:field="field_number_error" -->
|
||||
<!-- readOnly="true" addStyleNames="myLittleWidth"></b:TextBox> -->
|
||||
<!-- </b:Controls> -->
|
||||
<!-- </b:ControlGroup> -->
|
||||
<!-- </g:HorizontalPanel> -->
|
||||
|
||||
<!-- <g:HorizontalPanel addStyleNames="myMarginLeft"> -->
|
||||
<!-- <b:ControlGroup ui:field="cg_number_error" addStyleNames="myLittleMarginLeft"> -->
|
||||
<!-- <b:ControlLabel for="cl_number_error">Number of Errors</b:ControlLabel> -->
|
||||
<!-- <b:Controls> -->
|
||||
<!-- <b:TextBox b:id="field_number_error" ui:field="field_number_error" -->
|
||||
<!-- readOnly="true" addStyleNames="myLittleWidth"></b:TextBox> -->
|
||||
<!-- </b:Controls> -->
|
||||
<!-- </b:ControlGroup> -->
|
||||
<!-- </g:HorizontalPanel> -->
|
||||
<b:Form type="HORIZONTAL" addStyleNames="myFormWidth"
|
||||
ui:field="field_form">
|
||||
<b:Fieldset styleName="{style.noBorder}">
|
||||
|
@ -53,8 +36,16 @@
|
|||
<!-- readOnly="true" addStyleNames="{style.myWidth}"></b:TextBox> -->
|
||||
<!-- </b:Controls> -->
|
||||
<!-- </b:ControlGroup> -->
|
||||
<b:ControlGroup ui:field="cg_computation_info">
|
||||
<b:ControlLabel for="cl_computation_info">Computation Info</b:ControlLabel>
|
||||
<b:Controls>
|
||||
<b:TextArea b:id="field_computation_info" ui:field="field_computation_info"
|
||||
readOnly="true" addStyleNames="textAreaWidth"></b:TextArea>
|
||||
</b:Controls>
|
||||
</b:ControlGroup>
|
||||
|
||||
<b:ControlGroup ui:field="cg_current_message">
|
||||
<b:ControlLabel for="cl_current_message">Status Message</b:ControlLabel>
|
||||
<b:ControlLabel for="cl_current_message">Computation Message</b:ControlLabel>
|
||||
<b:Controls>
|
||||
<b:TextArea b:id="field_current_message" ui:field="field_current_message"
|
||||
readOnly="true" addStyleNames="textAreaWidth"></b:TextArea>
|
||||
|
@ -69,13 +60,6 @@
|
|||
</b:Controls>
|
||||
</b:ControlGroup>
|
||||
|
||||
<!-- <b:ControlGroup ui:field="cg_last_sync"> -->
|
||||
<!-- <b:ControlLabel for="cl_last_sync">Last Sync Time</b:ControlLabel> -->
|
||||
<!-- <b:Controls> -->
|
||||
<!-- <b:TextBox b:id="field_last_sync" ui:field="field_last_sync" -->
|
||||
<!-- readOnly="true"></b:TextBox> -->
|
||||
<!-- </b:Controls> -->
|
||||
<!-- </b:ControlGroup> -->
|
||||
</b:Fieldset>
|
||||
</b:Form>
|
||||
</g:HTMLPanel>
|
||||
|
|
Loading…
Reference in New Issue